, (*1)
FSelectMenu is a Fast and non-intrusive HTML select menu., (*2)
Features:
-
Fast: rendering is done on the server side: no DOM manipulation on the client side, (*3)
-
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.)., (*4)
-
Non intrusive: Works out of the box with existing scripts, (*5)
- 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
Usage
Load and init the FSelectMenu javascript module:, (*6)
``` javascript
require(['fselectmenu/fselectmenu'], function(FSelectMenu) {
FSelectMenu.init();
});, (*7)
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.
Install
-------
$ git submodule add git://github.com/arnaud-lb/fselectmenu.git vendor/fselectmenu, (*8)
### Plain PHP
You can render a FSelectMenu with the FSelectMenu\Renderer class:
``` php
<?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:, (*9)
``` php
<?php
echo $renderer->render('x', array('x' => 'Foo', 'y' => 'Bar'), array('nativeAttrs' => array('name' => 'foo')));, (*10)
### Twig
Register the extension:
``` php
<?php
$extension = new FSelectMenu\Twig\Extension;
$twigEnvironment->addExtension($extension);
The extension exposes the fselectmenu
method:, (*11)
fselectmenu(value, choices, options)
See Plain PHP above for a description of the parameters., (*12)
Example:, (*13)
``` jinja
{{ fselectmenu('x', {'x': 'Foo', 'y': 'Bar'}, {'nativeAttrs':{'name': 'foo'}}) }}, (*14)
### Javascript
Menus can also be rendered in Javascript (e.g. on the client side or in nodejs) with the `renderer` module:
``` javascript
require(['fselectmenu/renderer'], function(renderer) {
var html = renderer.render(value, choices, options);
});
Symfony2
``` php
<?php
// app/autoload.php, (*15)
$loader->registerNamespaces(array(
'FSelectMenu' => DIR.'/../vendor/fselectmenu/lib',
// your other namespaces
);, (*16)
#### Add FSelectMenuBundle to your application kernel
``` php
<?php
// app/AppKernel.php
public function registerBundles()
{
return array(
// ...
new FSelectMenu\Bundle\FSelectMenuBundle(),
);
}
``` jinja
{% use "FSelectMenuBundle::fselectmenu.html.twig" %}, (*17)
{% 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 %}, (*18)
### ZendFramework
#### Register view helper path:
``` ini
# 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';
}
Styling
FSelectMenu comes with a minimal (behavior only) stylesheet at lib/FSelectMenu/Bundle/Resources/sass/_fselectmenu.sass
., (*19)
Graceful degradation
Support for clients without javascript enabled can be achieved by hidding the fake select menu and displaying the native one:, (*20)
html
<noscript>
<style>
.fselectmenu-label-wrapper { display: none; }
.fselectmenu-native { display: inline; }
</style>
</noscript>
, (*21)