1/* 2 * jQuery selectbox plugin 3 * 4 * Copyright (c) 2007 Sadri Sahraoui (brainfault.com) 5 * Licensed under the GPL license and MIT: 6 * http://www.opensource.org/licenses/GPL-license.php 7 * http://www.opensource.org/licenses/mit-license.php 8 * 9 * The code is inspired from Autocomplete plugin (http://www.dyve.net/jquery/?autocomplete) 10 * 11 * Revision: $Id$ 12 * Version: 1.2 13 * 14 * Changelog : 15 * Version is modified by [email protected] and few lines related to width are commented out. 16 * Version 1.2 By Guillaume Vergnolle (web-opensource.com) 17 * - Add optgroup support 18 * - possibility to choose between span or input as replacement of the select box 19 * - support for jquery change event 20 * - add a max height option for drop down list 21 * Version 1.1 22 * - Fix IE bug 23 * Version 1.0 24 * - Support jQuery noConflict option 25 * - Add callback for onChange event, thanks to Jason 26 * - Fix IE8 support 27 * - Fix auto width support 28 * - Fix focus on firefox dont show the carret 29 * Version 0.6 30 * - Fix IE scrolling problem 31 * Version 0.5 32 * - separate css style for current selected element and hover element which solve the highlight issue 33 * Version 0.4 34 * - Fix width when the select is in a hidden div @Pawel Maziarz 35 * - Add a unique id for generated li to avoid conflict with other selects and empty values @Pawel Maziarz 36 */ 37jQuery.fn.extend({ 38 selectbox: function(options) { 39 return this.each(function() { 40 new jQuery.SelectBox(this, options); 41 }); 42 } 43}); 44 45 46/* pawel maziarz: work around for ie logging */ 47if (!window.console) { 48 var console = { 49 log: function(msg) { 50 } 51 } 52} 53/* */ 54 55jQuery.SelectBox = function(selectobj, options) { 56 57 var $ = jQuery; 58 var opt = options || {}; 59 opt.inputType = opt.inputType || "input"; 60 opt.inputClass = opt.inputClass || "selectbox"; 61 opt.containerClass = opt.containerClass || "selectbox-wrapper"; 62 opt.hoverClass = opt.hoverClass || "current"; 63 opt.currentClass = opt.currentClass || "selected"; 64 opt.groupClass = opt.groupClass || "groupname"; //css class for group 65 opt.maxHeight = opt.maxHeight || 200; // max height of dropdown list 66 opt.loopnoStep = opt.loopnoStep || false; // to remove the step in list moves loop 67 opt.onChangeCallback = opt.onChangeCallback || false; 68 opt.onChangeParams = opt.onChangeParams || false; 69 opt.debug = opt.debug || false; 70 71 var elm_id = selectobj.id; 72 var active = 0; 73 var inFocus = false; 74 var hasfocus = 0; 75 //jquery object for select element 76 var $select = jQuery(selectobj); 77 // jquery container object 78 var $container = setupContainer(opt); 79 //jquery input object 80 var $input = setupInput(opt); 81 // hide select and append newly created elements 82 $select.hide().before($input).before($container); 83 84 85 init(); 86 87 $input 88 .click(function(){ 89 if (!inFocus) { 90 $container.toggle(); 91 } 92 }) 93 .focus(function(){ 94 if ($container.not(':visible')) { 95 inFocus = true; 96 $container.show(); 97 } 98 }) 99 .keydown(function(event) { 100 switch(event.keyCode) { 101 case 38: // up 102 event.preventDefault(); 103 moveSelect(-1); 104 break; 105 case 40: // down 106 event.preventDefault(); 107 moveSelect(1); 108 break; 109 //case 9: // tab 110 case 13: // return 111 event.preventDefault(); // seems not working in mac ! 112 $('li.'+opt.hoverClass).trigger('click'); 113 break; 114 case 27: //escape 115 hideMe(); 116 break; 117 } 118 }) 119 .blur(function() { 120 if ($container.is(':visible') && hasfocus > 0 ) { 121 if(opt.debug) console.log('container visible and has focus') 122 } else { 123 // Workaround for ie scroll - thanks to Bernd Matzner
124 if((jQuery.browser.msie && jQuery.browser.version.substr(0,1) < 8) 125 || (jQuery.browser.safari && !/chrome/.test(navigator.userAgent.toLowerCase()))) { 126 if(document.activeElement.getAttribute('id').indexOf('_container')==-1){ 127 hideMe(); 128 } else { 129 $input.focus(); 130 } 131 } else { 132 hideMe(); 133 } 134 } 135 }); 136 137 function hideMe() { 138 hasfocus = 0; 139 $container.hide(); 140 } 141 142 function init() { 143 $container.append(getSelectOptions($input.attr('id'))).hide(); 144 var width = $input.css('width'); 145 if($container.height() > opt.maxHeight){ 146 /* 147 Commented By Saqib 148 $container.width(parseInt(width)+parseInt($input.css('paddingRight'))+parseInt($input.css('paddingLeft'))); 149 */ 150 $container.height(opt.maxHeight); 151 } else{ 152 /* 153 Commented By Saqib 154 $container.width(width); 155 */ 156 } 157 } 158 159 function setupContainer(options) { 160 var container = document.createElement("div"); 161 $container = jQuery(container); 162 $container.attr('id', elm_id+'_container'); 163 $container.addClass(options.containerClass); 164 $container.css('display', 'none'); 165 166 return $container; 167 } 168 169 function setupInput(options) { 170 if(opt.inputType == "span"){ 171 var input = document.createElement("span"); 172 var $input = jQuery(input); 173 $input.attr("id", elm_id+"_input"); 174 $input.addClass(options.inputClass); 175 $input.attr("tabIndex", $select.attr("tabindex")); 176 } else { 177 var input = document.createElement("input"); 178 var $input = jQuery(input); 179 $input.attr("id", elm_id+"_input"); 180 $input.attr("type", "text"); 181 $input.addClass(options.inputClass); 182 $input.attr("autocomplete", "off"); 183 $input.attr("readonly", "readonly"); 184 $input.attr("tabIndex", $select.attr("tabindex")); // "I" capital is important for ie 185 /* 186 Commented By Saqib 187 $input.css("width", $select.css("width")); 188 */ 189 } 190 return $input; 191 } 192 193 function moveSelect(step) { 194 var lis = jQuery("li", $container); 195 if (!lis || lis.length == 0) return false; 196 // find the first non-group (first option) 197 firstchoice = 0; 198 while($(lis[firstchoice]).hasClass(opt.groupClass)) firstchoice++; 199 active += step; 200 // if we are on a group step one more time 201 if($(lis[active]).hasClass(opt.groupClass)) active += step; 202 //loop through list from the first possible option 203 if (active < firstchoice) { 204 (opt.loopnoStep ? active = lis.size()-1 : active = lis.size() ); 205 } else if (opt.loopnoStep && active > lis.size()-1) { 206 active = firstchoice; 207 } else if (active > lis.size()) { 208 active = firstchoice; 209 } 210 scroll(lis, active); 211 lis.removeClass(opt.hoverClass); 212 213 jQuery(lis[active]).addClass(opt.hoverClass); 214 } 215 216 function scroll(list, active) { 217 var el = jQuery(list[active]).get(0); 218 var list = $container.get(0); 219 220 if (el.offsetTop + el.offsetHeight > list.scrollTop + list.clientHeight) { 221 list.scrollTop = el.offsetTop + el.offsetHeight - list.clientHeight; 222 } else if(el.offsetTop < list.scrollTop) { 223 list.scrollTop = el.offsetTop; 224 } 225 } 226 227 function setCurrent() { 228 var li = jQuery("li."+opt.currentClass, $container).get(0); 229 var ar = (''+li.id).split('_'); 230 var el = ar[ar.length-1]; 231 if (opt.onChangeCallback){ 232 $select.get(0).selectedIndex = $('li', $container).index(li); 233 opt.onChangeParams = { selectedVal : $select.val() }; 234 opt.onChangeCallback(opt.onChangeParams); 235 } else { 236 $select.val(el); 237 $select.change(); 238 } 239 if(opt.inputType == 'span') $input.html($(li).html()); 240 else $input.val($(li).html()); 241 return true; 242 } 243 244 // select value 245 function getCurrentSelected() { 246 return $select.val(); 247 } 248 249 // input value 250 function getCurrentValue() { 251 return $input.val(); 252 } 253 254 function getSelectOptions(parentid) { 255 var select_options = new Array(); 256 var ul = document.createElement('ul'); 257 select_options = $select.children('option'); 258 if(select_options.length == 0) { 259 var select_optgroups = new Array(); 260 select_optgroups = $select.children('optgroup'); 261 for(x=0;x<select_optgroups.length;x++){ 262 select_options = $("#"+select_optgroups[x].id).children('option'); 263 var li = document.createElement('li'); 264 li.setAttribute('id', parentid + '_' + $(this).val()); 265 li.innerHTML = $("#"+select_optgroups[x].id).attr('label'); 266 li.className = opt.groupClass; 267 ul.appendChild(li); 268 select_options.each(function() { 269 var li = document.createElement('li'); 270 li.setAttribute('id', parentid + '_' + $(this).val()); 271 li.innerHTML = $(this).html(); 272 if ($(this).is(':selected')) { 273 $input.html($(this).html()); 274 $(li).addClass(opt.currentClass); 275 } 276 ul.appendChild(li); 277 $(li) 278 .mouseover(function(event) { 279 hasfocus = 1; 280 if (opt.debug) console.log('over on : '+this.id
280); 281 jQuery(event.target, $container).addClass(opt.hoverClass); 282 }) 283 .mouseout(function(event) { 284 hasfocus = -1; 285 if (opt.debug) console.log('out on : '+this.id); 286 jQuery(event.target, $container).removeClass(opt.hoverClass); 287 }) 288 .click(function(event) { 289 var fl = $('li.'+opt.hoverClass, $container).get(0); 290 if (opt.debug) console.log('click on :'+this.id); 291 $('li.'+opt.currentClass, $container).removeClass(opt.currentClass); 292 $(this).addClass(opt.currentClass); 293 setCurrent(); 294 $select.get(0).blur(); 295 hideMe(); 296 }); 297 }); 298 } 299 } else select_options.each(function() { 300 var li = document.createElement('li'); 301 li.setAttribute('id', parentid + '_' + $(this).val()); 302 li.innerHTML = $(this).html(); 303 if ($(this).is(':selected')) { 304 $input.val($(this).html()); 305 $(li).addClass(opt.currentClass); 306 } 307 ul.appendChild(li); 308 $(li) 309 .mouseover(function(event) { 310 hasfocus = 1; 311 if (opt.debug) console.log('over on : '+this.id); 312 jQuery(event.target, $container).addClass(opt.hoverClass); 313 }) 314 .mouseout(function(event) { 315 hasfocus = -1; 316 if (opt.debug) console.log('out on : '+this.id); 317 jQuery(event.target, $container).removeClass(opt.hoverClass); 318 }) 319 .click(function(event) { 320 var fl = $('li.'+opt.hoverClass, $container).get(0); 321 if (opt.debug) console.log('click on :'+this.id); 322 $('li.'+opt.currentClass, $container).removeClass(opt.currentClass); 323 $(this).addClass(opt.currentClass); 324 setCurrent(); 325 $select.get(0).blur(); 326 hideMe(); 327 }); 328 }); 329 return ul; 330 } 331 332 333 334};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.