<?xml version="1.0" encoding="UTF-8"?>
<code>
  <code>## Javascript [jquery_javascript]
;(function($) {
        $.fn.extend(
            {
                multiselect: function(options) {
                    var options = $.extend({
                            changeCallback: null,
                            single: false,
                        },
                        options || {}
                    );

                    return this.each(function(){
                            $(this).multiselect_render(options);
                        }
                    )
                },
                multiselect_render: function(options) {
                    var $selected_elements = $('&lt;span&gt;&lt;/span&gt;');

                    var $options = $('&lt;div&gt;&lt;/div&gt;');

                    var $search = $('&lt;input type="text"/&gt;')
                    .addClass('multiselectSearch')
                    .keyup(function(e) {
                            var _val = $(this).val();

                            if(!_val) {
                                $options
                                .children("div")
                                .show();
                            } else {
                                $options
                                .children("div")
                                .hide()
                                .filter(":icontains("+_val+")")
                                .show();
                            }
                        }
                    );

                    var $widget = $("&lt;div/&gt;") ;

                    var $choose;
                    if(options.single) {
                        $choose = $search
                    } else {
                        $choose = $("&lt;a/&gt;")
                        .addClass('multiselectChoose')
                        .text("[Choose...]");
                    }
                    $choose.click(function(e) {
                            e.preventDefault();
                            $widget.toggle(
                                0,
                                function() {
                                    $(document).click(body_click_hide_widget);
                                }
                            );
                            $search.select();
                        }
                    );

                    var body_click_hide_widget = function(e) {
                        var $$this = $(e.target);

                        if($$this[0] == $choose[0])
                            return;

                        var $$parents = $$this.parents().andSelf();

                        hide = true;
                        for (var i=0; i&lt;$$parents.length; i++) {
                            if($$parents[i] == $widget[0]) {
                                hide=false;
                                break;
                            }
                        }
                        if(hide) {
                            $widget.hide();
                            $(document).unbind("click", body_click_hide_widget);
                        }
                    }

                    var update_selected_elements = function() {
                        var arr = new Array();
                        $options.find(":checked").next('label').each(function() {
                                arr.push($(this).text());
                            }
                        );
                        $selected_elements.text(arr.join(', '));
                    };

                    $widget.append($search);

                    // button close
                    if(!options.single) {
                        $widget
                        .append(
                            $("&lt;a/&gt;")
                            .text("close")
                            .addClass('multiselectClose')
                            .click(function(e) {
                                    e.preventDefault();
                                    $widget.hide();
                                    $(document).unbind("click", body_click_hide_widget);
                                }
                            )
                        )
                    }

                    var $this = $(this).hide();
                    var $opts = $this.children("option");
                    var $parent_id = $this.attr('id');
                    var $parent_name = $this.attr('name');
                    var nb_opts = $opts.length;
                    var type = options.single ? 'radio' : 'checkbox';
                    var opts_arr = new Array();
                    $opts.each(
                        function(idx) {
                            var $$this = $(this);
                            var $$this_value = $$this.val()

                            var input = '&lt;input type="' + type + '" id="' + $parent_id + '-' + $$this_value + '" name="' + $parent_name + '" value="' + $$this_value + '"' + ($$this.is(':selected') ? ' checked=checked' : '') + ' /&gt;';

                            var label = '&lt;label for="' + $parent_id + '-' + $$this_value + '"&gt;' + $$this.text() + '&lt;/label&gt;';

                            var option = '&lt;div&gt;'+input+label+'&lt;/div&gt;';

                            opts_arr.push(option);
                        }
                    );

                    $options.append(opts_arr.join(''));

                    $options
                    .children('div').addClass('multiselectOption')
                    .change(
                        function(e) {
                            if(options.changeCallback) {
                                options.changeCallback.call(this);
                            }
                            update_selected_elements();
                            if(options.single) {
                                $search.val($selected_elements.text());
                                $widget.hide();
                                $(document).unbind("click", body_click_hide_widget);
                            }
                        }
                    );

                    update_selected_elements();

                    $widget.append($options);

                    if(options.single) {
                        $choose.val($selected_elements.text())
                        $this.before($choose);
                    } else {
                        $this.before($selected_elements).before($choose);
                    }

                    $this.replaceWith($widget.hide().addClass('multiselectWidget'));
                    return $widget
                }
            }
        );
    }
)(jQuery);</code>
  <comment>This is a little jQuery script I wrote in order to add a filter field to a selectbox (or multiselectbox). It works fine with few options but is painfully slow with 3000+ options. Any idea to refactor it ?

usage : $("select").multiselect({single: true});</comment>
  <created-at type="datetime">2010-02-03T23:05:22+00:00</created-at>
  <id type="integer">1168</id>
  <language>JavaScript</language>
  <permalink>filter-selectbox-with-3000-options</permalink>
  <refactors-count type="integer">2</refactors-count>
  <title>filter selectbox with 3000+ options </title>
  <trackback-url></trackback-url>
  <updated-at type="datetime">2010-02-26T07:54:11+00:00</updated-at>
  <user-id type="integer">1917</user-id>
  <refactors type="array">
    <refactor>
      <code></code>
      <code-id type="integer">1168</code-id>
      <comment>Not to step on your toes, but there'a already a multiselect that has been developed for jQuery UI
http://quasipartikel.at/multiselect/

You may find quite a difference of performance.</comment>
      <created-at type="datetime">2010-02-04T02:25:13+00:00</created-at>
      <id type="integer">436622</id>
      <language>JavaScript</language>
      <rating type="integer">0</rating>
      <ratings-count type="integer">0</ratings-count>
      <title>On filter selectbox with 3000+ options </title>
      <user-id type="integer">940</user-id>
      <user-name>paul.wilkins.myopenid.com</user-name>
      <user-website></user-website>
    </refactor>
    <refactor>
      <code nil="true"></code>
      <code-id type="integer">1168</code-id>
      <comment>Keep posting stuff like this i really like it</comment>
      <created-at type="datetime">2010-02-26T07:54:07+00:00</created-at>
      <id type="integer">460201</id>
      <language>JavaScript</language>
      <rating type="integer">0</rating>
      <ratings-count type="integer">0</ratings-count>
      <title>On filter selectbox with 3000+ options </title>
      <user-id type="integer" nil="true"></user-id>
      <user-name>cna training</user-name>
      <user-website>http://www.cna-trainingclass.com/</user-website>
    </refactor>
  </refactors>
</code>
