Fast and non-intrusive HTML select menu

Installs: 2 439

Dependents: 0

Suggesters: 0

Security: 0

Stars: 7

Watchers: 3

Forks: 5

Open Issues: 2


1.1.1 2013-07-03 11:50 UTC

This package is auto-updated.

Last update: 2023-11-23 03:55:54 UTC


Build Status

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) {

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:// vendor/fselectmenu

Plain PHP

You can render a FSelectMenu with the FSelectMenu\Renderer class:


$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


echo $renderer->render('x', array('x' => 'Foo', 'y' => 'Bar'), array('nativeAttrs' => array('name' => 'foo')));


Register the extension:

$extension = new FSelectMenu\Twig\Extension;

The extension exposes the fselectmenu method:

fselectmenu(value, choices, options)

See Plain PHP above for a description of the parameters.


{{ 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);


Add the FSelectMenu namespace to your autoloader

// app/autoload.php

    'FSelectMenu' => __DIR__.'/../vendor/fselectmenu/lib',
    // your other namespaces

Add FSelectMenuBundle to your application kernel

// app/AppKernel.php

public function registerBundles()
    return array(
        // ...
        new FSelectMenu\Bundle\FSelectMenuBundle(),

Overload the choice_widget block in your form theme:

{% 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 %}


Register view helper path:

# application.ini
resources.view.helperPath.FSelectMenu_Zend_View_Helper = APPLICATION_PATH "/../vendor/fselectmenu/lib/FSelectMenu/Zend/View/Helper"

Subclass Zend_Form_Element_Select:

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.

Graceful degradation

Support for clients without javascript enabled can be achieved by hidding the fake select menu and displaying the native one:

        .fselectmenu-label-wrapper { display: none; }
        .fselectmenu-native { display: inline; }