<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <id>tag:www.refactormycode.com,2007:users1917</id>
  <link type="application/atom+xml" href="http://www.refactormycode.com/users/1917" rel="self"/>
  <title>akarzim</title>
  <updated>Wed Feb 03 23:05:22 -0800 2010</updated>
  <entry>
    <id>tag:www.refactormycode.com,2007:Code1168</id>
    <published>2010-02-03T23:05:22-08:00</published>
    <updated>2010-02-26T07:54:11-08:00</updated>
    <title>[JavaScript] filter selectbox with 3000+ options </title>
    <content type="html">&lt;p&gt;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 ?&lt;/p&gt;

&lt;p&gt;usage : $(&amp;quot;select&amp;quot;).multiselect({single: true});&lt;/p&gt;

&lt;pre&gt;## 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 = $('&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;');

                    var $options = $('&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;');

                    var $search = $('&amp;lt;input type=&amp;quot;text&amp;quot;/&amp;gt;')
                    .addClass('multiselectSearch')
                    .keyup(function(e) {
                            var _val = $(this).val();

                            if(!_val) {
                                $options
                                .children(&amp;quot;div&amp;quot;)
                                .show();
                            } else {
                                $options
                                .children(&amp;quot;div&amp;quot;)
                                .hide()
                                .filter(&amp;quot;:icontains(&amp;quot;+_val+&amp;quot;)&amp;quot;)
                                .show();
                            }
                        }
                    );

                    var $widget = $(&amp;quot;&amp;lt;div/&amp;gt;&amp;quot;) ;

                    var $choose;
                    if(options.single) {
                        $choose = $search
                    } else {
                        $choose = $(&amp;quot;&amp;lt;a/&amp;gt;&amp;quot;)
                        .addClass('multiselectChoose')
                        .text(&amp;quot;[Choose...]&amp;quot;);
                    }
                    $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&amp;lt;$$parents.length; i++) {
                            if($$parents[i] == $widget[0]) {
                                hide=false;
                                break;
                            }
                        }
                        if(hide) {
                            $widget.hide();
                            $(document).unbind(&amp;quot;click&amp;quot;, body_click_hide_widget);
                        }
                    }

                    var update_selected_elements = function() {
                        var arr = new Array();
                        $options.find(&amp;quot;:checked&amp;quot;).next('label').each(function() {
                                arr.push($(this).text());
                            }
                        );
                        $selected_elements.text(arr.join(', '));
                    };

                    $widget.append($search);

                    // button close
                    if(!options.single) {
                        $widget
                        .append(
                            $(&amp;quot;&amp;lt;a/&amp;gt;&amp;quot;)
                            .text(&amp;quot;close&amp;quot;)
                            .addClass('multiselectClose')
                            .click(function(e) {
                                    e.preventDefault();
                                    $widget.hide();
                                    $(document).unbind(&amp;quot;click&amp;quot;, body_click_hide_widget);
                                }
                            )
                        )
                    }

                    var $this = $(this).hide();
                    var $opts = $this.children(&amp;quot;option&amp;quot;);
                    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 = '&amp;lt;input type=&amp;quot;' + type + '&amp;quot; id=&amp;quot;' + $parent_id + '-' + $$this_value + '&amp;quot; name=&amp;quot;' + $parent_name + '&amp;quot; value=&amp;quot;' + $$this_value + '&amp;quot;' + ($$this.is(':selected') ? ' checked=checked' : '') + ' /&amp;gt;';

                            var label = '&amp;lt;label for=&amp;quot;' + $parent_id + '-' + $$this_value + '&amp;quot;&amp;gt;' + $$this.text() + '&amp;lt;/label&amp;gt;';

                            var option = '&amp;lt;div&amp;gt;'+input+label+'&amp;lt;/div&amp;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(&amp;quot;click&amp;quot;, 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);&lt;/pre&gt;</content>
    <author>
      <name>akarzim</name>
      <email>akarzim@gmail.com</email>
    </author>
    <link type="text/html" href="http://www.refactormycode.com/codes/1168-filter-selectbox-with-3000-options" rel="alternate"/>
  </entry>
</feed>

