FSelectMenu is a Fast and non-intrusive HTML select menu.
-
Fast: rendering is done on the server side: no DOM manipulation on the client side
-
Non intrusive: Once FSelectMenu is initialized you can forget it: every select menu will work, whether they were present during initialization or added later. (FSelectMenu uses event delegation. The HTML code is generated on the server; all that is left to FSelectMenu is to listen for events bubbling to the document element.).
-
Non intrusive: Works out of the box with existing scripts
- Scripts don't have to know anything about FSelectMenu for simple things like listening for events, getting and changing the value, etc.
- Scripts interact with the native select element directly
Load and init the FSelectMenu javascript module:
require(['fselectmenu/fselectmenu'], function(FSelectMenu) {
FSelectMenu.init();
});
That's all.
If you add new select menus on the document after that, you don't have to call .init()
again.
Just trigger the change
event on the native select element when programmatically changing its value.
$ git submodule add git://github.com/arnaud-lb/fselectmenu.git vendor/fselectmenu
You can render a FSelectMenu with the FSelectMenu\Renderer class:
<?php
$renderer = new FSelectMenu\Renderer;
echo $renderer->render($value, $choices, $options);
- $value is the value of the selected choice
- $choices is an array of value => label choices (with nested arrays, for optgroups)
- $options is an array with the following keys:
- attrs: fselectmenu element attributes (e.g. id, class, ...)
- nativeAttrs: native select element attributes (e.g. id, name)
- optionAttrs: choice elements attributes (array of value => attributes)
- optionWrapperAttrs: choice elements wrapper attributes
- rawLabels: whether to escape labels
- fixedLabel: a label that will always be displayed instead of the selected label
Example:
<?php
echo $renderer->render('x', array('x' => 'Foo', 'y' => 'Bar'), array('nativeAttrs' => array('name' => 'foo')));
Register the extension:
<?php
$extension = new FSelectMenu\Twig\Extension;
$twigEnvironment->addExtension($extension);
The extension exposes the fselectmenu
method:
fselectmenu(value, choices, options)
See Plain PHP above for a description of the parameters.
Example:
{{ fselectmenu('x', {'x': 'Foo', 'y': 'Bar'}, {'nativeAttrs':{'name': 'foo'}}) }}
Menus can also be rendered in Javascript (e.g. on the client side or in nodejs) with the renderer
module:
require(['fselectmenu/renderer'], function(renderer) {
var html = renderer.render(value, choices, options);
});
<?php
// app/autoload.php
$loader->registerNamespaces(array(
'FSelectMenu' => __DIR__.'/../vendor/fselectmenu/lib',
// your other namespaces
);
<?php
// app/AppKernel.php
public function registerBundles()
{
return array(
// ...
new FSelectMenu\Bundle\FSelectMenuBundle(),
);
}
{% use "FSelectMenuBundle::fselectmenu.html.twig" %}
{% block choice_widget %}
{% spaceless %}
{% if expanded %}
{% for child in form %}
{{ form_widget(child) }}
{% endfor %}
{% else %}
{% if multiple %}
{{ parent() }}
{% else %}
{# Symfony >= 2.1 #}
{{ block('fselectmenu_choice_widget_2_1') }}
{# Symfony 2.0 #}
{# {{ block('fselectmenu_choice_widget') }} #}
{% endif %}
{% endif %}
{% endspaceless %}
{% endblock choice_widget %}
# application.ini
resources.view.helperPath.FSelectMenu_Zend_View_Helper = APPLICATION_PATH "/../vendor/fselectmenu/lib/FSelectMenu/Zend/View/Helper"
<?php
class App_Form_Element_FSelectMenu extends Zend_Form_Element_Select
{
public $helper = 'formFSelectMenu';
}
FSelectMenu comes with a minimal (behavior only) stylesheet at lib/FSelectMenu/Bundle/Resources/sass/_fselectmenu.sass
.
Support for clients without javascript enabled can be achieved by hidding the fake select menu and displaying the native one:
<noscript>
<style>
.fselectmenu-label-wrapper { display: none; }
.fselectmenu-native { display: inline; }
</style>
</noscript>