![]() |
|
Snippets |
|
I've found it annoying to set the show and hide commands on each remote request. So I've used this to define it globally:
/* * Defines the indicator globally */ Ajax.Responders.register({ onCreate: function() { Element.show('indicator'); }, onComplete: function() { Element.hide('indicator'); } });
It's very annoying that the pake tasks @doctrine-build-all@ and @doctrine-build-all-load@ don't work. So I've thought, why don't write a shell script which executes the single steps for me.
Just create a new file in your batch directory. For example 'build' or 'doctrine'
#!/usr/bin/env bash
symfony doctrine-drop-db <your app>
symfony doctrine-build-db <your app>
symfony doctrine-build-model <your app>
symfony doctrine-build-sql <your app>
symfony doctrine-insert-sql <your app>
php batch/<your load-data-batch-file>.php
I needed the object_admin_double_list helper of the admin generator for my regular projects (without using admin generator). So I ported the admin_double_list helper a bit and now I want to publish this for you.
The admin_double_list helper is for selecting multiple items from a pool of items using ManyToMany relationships. For example to associate a user to multiple groups.
The helper itself has two parts: - two helper functions - two javascript functions
After that I have an example how the three controller, view and model parts handle this helper.
/** * two multiline select tags with associated and unassociated items * * @return string * @param object object * @param string method of object * @param array options * @param array html options of select tags **/ function double_list($object, $method, $options = array(), $html_options = array()) { $options = _parse_attributes($options); // get the lists of objects list($all_objects, $objects_associated, $associated_ids) = _get_object_list($object, $method, _get_option($options, 'through_class')); // options $html_options['multiple'] = _get_option($html_options, 'multiple', true); $html_options['size'] = _get_option($html_options, 'size', 10); $html_options['class'] = 'double_list'; $label_assoc = _get_option($options, 'associated_label', 'Zugehörige Gruppen'); $label_all = _get_option($options, 'unassociated_label', 'Gruppenliste'); $name1 = _get_option($options, 'associated', 'associated'); $name2 = _get_option($options, 'unassociated', 'unassociated'); $form = _get_option($options, 'form_id', 'editForm'); // unassociated objects $objects_unassociated = array(); foreach ($all_objects as $object) { if (!in_array($object->getPrimaryKey(), $associated_ids)) $objects_unassociated[] = $object; } // select tags $select1 = select_tag($name1, options_for_select(_get_options_from_objects($objects_associated), '', $options), $html_options); unset($html_options['class']); $select2 = select_tag($name2, options_for_select(_get_options_from_objects($objects_unassociated), '', $options), $html_options); // output skeloton $html = '<div style="float:left; padding-right: 20px;"> <label for="%s">%s</label> %s </div> <div class="float:left; padding-right: 20px; padding-top: 20px">%s<br />%s</div> <div class="float:left;"> <label for="%s">%s</label> %s </div> <div style="clear:both"></div>'; // include js library $response = sfContext::getInstance()->getResponse(); $response->addJavascript('/js/double_list.js', 'last'); return sprintf($html, $name1, $label_assoc, $select1, link_to_function(image_tag('resultset_previous'), "double_list_move(\$('{$name2}'), \$('{$name1}'))"), link_to_function(image_tag('resultset_next'), "double_list_move(\$('{$name1}'), \$('{$name2}'))", 'style=display:block'), $name2, $label_all, $select2, $form ); } /** * retrieve object list via propel * * @return array * @param object root object * @param string retrieving method * @param string name of satellite class **/ function _get_object_list($object, $method, $middleClass) { // get object $object = $object instanceof sfOutputEscaper ? $object->getRawValue() : $object; // get all objects $objects = sfPropelManyToMany::getAllObjects($object, $middleClass); // get related objects $objects_associated = sfPropelManyToMany::getRelatedObjects($object, $middleClass); // get ids $ids = array_map(create_function('$o', 'return $o->getPrimaryKey();'), $objects_associated); return array($objects, $objects_associated, $ids); }
You probably want to modify the look of the list using css (like I do). So you can change the $js variable like you want f.e. adding class names. And you perhaps also want to change the image paths (I used two icons of the famfamfam icon library).
Put the code below in a file called double_list.js in your js directory. (For individual path and file name, modify the double_list helper, search for $response)
function double_list_move(src, dest)
{
for (var i = 0; i < src.options.length; i++)
{
if (src.options[i].selected)
{
dest.options[dest.length] = new Option(src.options[i].text, src.options[i].value);
src.options[i] = null;
--i;
}
}
}
function double_list_submit()
{
// get all selects with double list class
selects = $$('select.double_list');
selects.each(function(element){
for (var i = 0; i < element.options.length; i++)
element.options[i].selected = true;
});
return true;
}
I would like to show an example how to handle this helper in the three patterns.
The example is easy. Assigning an user to many groups.
We have to build a table which handles the ManyToMany relationship.
user_group:
_attributes:
phpName: UserGroup
group_id:
type: integer
primaryKey: true
foreignTable:groups
foreignReference:id
onDelete: cascade
user_id:
type: integer
primaryKey: true
foreignTable:users
foreignReference:id
onDelete: cascade
Don't forget to rebuild all db stuff and to clear the cache.
Now we display the double_list:
<?php echo double_list($user, 'getUserGroups', 'through_class=UserGroup associated=groups unassociated=not_groups associated_label=Associated Groups unassociated_label=Group list') ?>
The first parameter is the user object, than the method of the object retrieving the UserGroup records. I think the options are clear.
At last we have to save the selection of the user. Before doing this we have to delete all UserGroup objects of the user, because we would assign it twice, if the item was selected before.
// clear group data to save it again $c = new Criteria(); $c->add(UserGroupPeer::USER_ID, $user->getId()); UserGroupPeer::doDelete($c); // save groups $groups = $this->getRequestParameter('groups'); if ($groups) { foreach ($groups as $id) { $group = new UserGroup(); $group->setGroupId($id); $group->setUserId($user->getId()); $group->save(); } }
It was a bit too long. As I said, this is a port of the original object_admin_double_list helper, which can be practically only used with the Admin Generator.
Please check the snippet, because I use this in a little bit more customized version.
If you are displeased having different anti-aliasing of fonts in your Gecko Browsers (Camino, Firefox, Flock), when WebDebug is on. Gecko Browsers will show the fonts more thiner. But when you close WebDebug, the fonts will be normal again.
I think that this is not a acceptable casualty, so i deactivate the semi-transparence of the Bar. This will correct the behavior of the Gecko engine.
Just put the code in your css file (don't modify the css of web debug):
#sfWebDebugBar, .sfWebDebugCache { filter:alpha(opacity=100); -moz-opacity:1; opacity: 1; }
If you want to hide the Web Debug Details/Menus but also want to have quick access when you need it.
Then this could help you. Just copy this in a js file or print it in your layout:
/* * HIDE WEB DEBUG DETAILS ON LAUNCH */ Event.observe(window, 'load', function(){ // check if web debug is on if ($('sfWebDebugBar')) sfWebDebugToggleMenu(); });