Recently i created nice and simple Symfony widget: sfWidgetFormJQueryMultiSelect. It’s really simple in use and implementation. I have used code written recently by Eric Hynds: jQuery MultiSelect Plugin w/ ThemeRoller Support and standard sfWidgetFormChoice.
As a result, i received sfWidgetFormJQueryMultiSelect.
<?php
/**
* sfWidgetFormJQueryMultiSelect represents a multi choice select widget.
*
* @package symfony
* @subpackage widget
* @author Kamil Adryjanek <kamil.adryjanek@gmail.com>
*/
class sfWidgetFormJQueryMultiSelect extends sfWidgetFormChoice
{
/**
* Constructor.
*
* Available options:
*
* * choices: An array of possible choices (required)
* * renderer_class: The class to use instead of the default ones
* * renderer_options: The options to pass to the renderer constructor
* * renderer: A renderer widget (overrides the expanded and renderer_options options)
* The choices option must be: new sfCallable($thisWidgetInstance, 'getChoices')
* @param array $options An array of options
* @param array $attributes An array of default HTML attributes
*
* @see sfWidgetFormChoiceBase
*/
protected function configure($options = array(), $attributes = array())
{
$this->addOption('config', '{}');
parent::configure($options, $attributes);
$this->setOption('multiple', true);
$this->setOption('expanded', true);
}
/**
* @param string $name The element name
* @param string $value The value selected in this widget
* @param array $attributes An array of HTML attributes to be merged with the default HTML attributes
* @param array $errors An array of errors for the field
*
* @return string An HTML tag string
*
* @see sfWidgetForm
*/
public function render($name, $value = null, $attributes = array(), $errors = array())
{
return parent::render($name, $value = null, $attributes = array(), $errors = array()).
sprintf(<<<EOF
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery("#%s").multiSelect(
%s
);
});
</script>
EOF
,
$this->generateId($name),
$this->getOption('config')
);
}
}
How to use it
Include into your application neccessary JavaScripts (jQuery 1.4+ and jQuery UI required) and stylesheets: (for example view.yml):
stylesheets: [main.css, ui-lightness/jquery-ui-1.7.2.custom.css, jquery.multiselect.css] javascripts: [jquery.js, jquery-ui.js, jquery.multiselect.js]
Then we need to create simple form and set our widgets:
<?php
class SimpleForm extends sfForm {
public function configure() {
$userChoices = array('John', 'Michael', 'Tom', 'Peter');
$this->setWidgets(array(
'users' => new sfWidgetFormJQueryMultiSelect(array(
'choices' => $userChoices
))
));
$this->setValidators(array(
'users' => new sfValidatorChoice(array(
'choices' => array_keys($userChoices)
))
));
}
}
How does it work (look)
Form should now look similar to that:
Widget should work with Symfony 1.2.X - 1.4.X.
More information about jquery.multiselect plugin can be found on this page.
In the near future I would like to create Symfony widget and put there some of my custom widgets (for example sfWidgetFormJQueryDateTime).
Enjoy

This is great! Thanks for your article. I am new at python and this got me straight.
Excelent guide I have searching for a easy to use guide for understanding php arrays.
Sorry but your widget not work form me. I use symfony 1.4 but i have a problem because the widget nt rendered my select input box.
I have try avery combination:
$userChoices = array(’John’, ‘Michael’, ‘Tom’, ‘Peter’);
sfWidgetFormJQueryMultiSelect(array(’choices’ => $userChoices));
or
$this->widgetSchema['author_list']->setOption(’renderer_class’, ’sfWidgetFormJQueryMultiSelect’);
I have returned every time the same list of standard input of symfony
Sorry for my english. i’m newbie in symfony. and i like your application!
thanks in advance!
i’ve try so with your example but the problem is the same!!
Did you download and include stylesheets and JavaScripts (jquery.js, jquery-ui.js, jquery.multiselect.js, ui-lightness/jquery-ui-1.7.2.custom.css, jquery.multiselect.css)?
my form render th UL tag list and not SELECT tag, why?
i have added all header content..but doesn’t work!!
thanks for all!!
Send me your code
i will do my best to fix it.
thanks…realy!! I’m archaelogyst and not web programmer
class MesBookForm extends BaseMesBookForm
{
public function configure()
{
parent::setup();
$this - > widgetSchema['MesUsersId'] = new sfWidgetFormInputHidden();
unset(
$this['created_at'], $this['updated_at'],
$this['is_public'], $this['is_actived'],
$this['mes_books_list']
);
$this->widgetSchema->setLabels(array(
‘name’ => ‘Title’,
‘note’ => ‘Remark’,
‘year’ => ‘Year’,
‘letter’ => ‘Letter’,
‘pages’ => ‘Pages’,
‘place_of_edition’ => ‘Place of Edition’,
‘publisher’ => ‘Publisher’,
‘editors’ => ‘Editors’,
‘MesUsersId’ => ‘Mes User’,
‘author_list’ => ‘Authors’
));
$this->widgetSchema['author_list']->setOption(’renderer_class’, ’sfWidgetFormJQueryMultiSelect’);
}
}
public function setup()
{
$this->setWidgets(array(
‘id’ => new sfWidgetFormInputHidden(),
‘name’ => new sfWidgetFormInputText(),
…
‘is_public’ => new sfWidgetFormInputCheckbox(),
‘is_actived’ => new sfWidgetFormInputCheckbox(),
‘MesUsersId’ => new sfWidgetFormDoctrineChoice(array(’model’ => $this->getRelatedModelName(’sfGuardUser’), ‘add_empty’ => false)),
‘created_at’ => new sfWidgetFormDateTime(),
‘updated_at’ => new sfWidgetFormDateTime(),
‘author_list’ => new sfWidgetFormDoctrineChoice(array(’multiple’ => true, ‘model’ => ‘MesAuthor’)),
‘mes_books_list’ => new sfWidgetFormDoctrineChoice(array(’multiple’ => true, ‘model’ => ‘MesCities’)),
));
$this->setValidators(array(
‘id’ => new sfValidatorDoctrineChoice(array(’model’ => $this->getModelName(), ‘column’ => ‘id’, ‘required’ => false)),
…
‘is_public’ => new sfValidatorBoolean(array(’required’ => false)),
‘is_actived’ => new sfValidatorBoolean(array(’required’ => false)),
‘MesUsersId’ => new sfValidatorDoctrineChoice(array(’model’ => $this->getRelatedModelName(’sfGuardUser’))),
‘created_at’ => new sfValidatorDateTime(),
‘updated_at’ => new sfValidatorDateTime(),
‘author_list’ => new sfValidatorDoctrineChoice(array(’multiple’ => true, ‘model’ => ‘MesAuthor’, ‘required’ => false)),
‘mes_books_list’ => new sfValidatorDoctrineChoice(array(’multiple’ => true, ‘model’ => ‘MesCities’, ‘required’ => false)),
));
…
and i have comment this line in your widget to obtain a select box with multiple, about exempla in erichynds’s page
$this->setOption(’multiple’, true);
//$this->setOption(’expanded’, true);
but now i received from firebug this error:
H is undefined
I suppose is from my bad configuration in jquery.. any idea?
thank to much! and so sorry for my english..
and this is my js and css
stylesheets: [main.css, jquery-ui-1.7.2.custom.css, jquery.fancybox-1.3.1.css, jquery.jgrowl.css, jquery.multiselect.css]
javascripts: [prototype.js, jquery-1.3.2.min.js, jquery-ui-1.7.2.custom.min.js, jquery.fancybox-1.3.1.js, jquery.form.js, jquery.validate.js, jquery.multiselect.min.js, DropDownMenuX]
“H is undefined”
Your jQuery version is out of date. As i wrote:
“Include into your application neccessary JavaScripts (jQuery 1.4+ and jQuery UI 1.8+ required) ”
Also youu cannot use my widget class as a renderer.
In your case you need stg like sfWidgetFormDoctrineJQueryMultiSelect.
But in this case you should:
‘author_list’ => new sfWidgetFormJQueryMultiSelect(array(’choices’ => $mesAuthorChoices))
Hi Kamil, i’ve resolve.
I’ve some error in javascript bu it work.
I’ve changed the jquery library with your suggest and i copy a part of css ui in my lyout. Where i found url in css i replace it with php function url_for to replace a correct image for css.
I’v commented in your widget this line
$this->setOption(’multiple’, true);
//$this->setOption(’expanded’, true);
and in jquery.multiselect.js i’ve changed in line 236 this
…
width: width+’px’
}).show();
with:
…
width: width+’px’,
display : ‘block’
}).html().show();
and here i’ve a error in firebug
$options.css({position: “absolute”, top: top + “px”, left: offset.left + “px”, width: width + “px”, display: “block”}).html().show is not a function
For me is not a problem, because it work!!
thanks for your help!! really!
Gday, extremely high quality online site. Cheers for taking the time to come up with so many useful blogposts