Javascript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
;(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 = $('<span></span>'); var $options = $('<div></div>'); var $search = $('<input type="text"/>') .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 = $("<div/>") ; var $choose; if(options.single) { $choose = $search } else { $choose = $("<a/>") .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<$$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( $("<a/>") .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 = '<input type="' + type + '" id="' + $parent_id + '-' + $$this_value + '" name="' + $parent_name + '" value="' + $$this_value + '"' + ($$this.is(':selected') ? ' checked=checked' : '') + ' />'; var label = '<label for="' + $parent_id + '-' + $$this_value + '">' + $$this.text() + '</label>'; var option = '<div>'+input+label+'</div>'; 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);
Refactorings
No refactoring yet !
paul.wilkins.myopenid.com
February 4, 2010, February 04, 2010 02:25, permalink
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.
cna training
February 26, 2010, February 26, 2010 07:54, permalink
Keep posting stuff like this i really like it
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});