Advertisement
Guest User

Untitled

a guest
Jan 10th, 2014
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  * Autocomplete - jQuery plugin 1.1pre
  3.  *
  4.  * Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, Jörn Zaefferer
  5.  *
  6.  * Dual licensed under the MIT and GPL licenses:
  7.  *   http://www.opensource.org/licenses/mit-license.php
  8.  *   http://www.gnu.org/licenses/gpl.html
  9.  *
  10.  * Revision: $Id: jquery.autocomplete.js 5785 2008-07-12 10:37:33Z joern.zaefferer $
  11.  *
  12.  */
  13.  
  14. ;(function($) {
  15.    
  16. $.fn.extend({
  17.     autocomplete: function(urlOrData, options) {
  18.         var isUrl = typeof urlOrData == "string";
  19.         options = $.extend({}, $.Autocompleter.defaults, {
  20.             url: isUrl ? urlOrData : null,
  21.             data: isUrl ? null : urlOrData,
  22.             delay: isUrl ? $.Autocompleter.defaults.delay : 10,
  23.             max: options && !options.scroll ? 10 : 150
  24.         }, options);
  25.        
  26.         // if highlight is set to false, replace it with a do-nothing function
  27.         options.highlight = options.highlight || function(value) { return value; };
  28.        
  29.         // if the formatMatch option is not specified, then use formatItem for backwards compatibility
  30.         options.formatMatch = options.formatMatch || options.formatItem;
  31.        
  32.         return this.each(function() {
  33.             new $.Autocompleter(this, options);
  34.         });
  35.     },
  36.     result: function(handler) {
  37.         return this.bind("result", handler);
  38.     },
  39.     search: function(handler) {
  40.         return this.trigger("search", [handler]);
  41.     },
  42.     flushCache: function() {
  43.         return this.trigger("flushCache");
  44.     },
  45.     setOptions: function(options){
  46.         return this.trigger("setOptions", [options]);
  47.     },
  48.     unautocomplete: function() {
  49.         return this.trigger("unautocomplete");
  50.     }
  51. });
  52.  
  53. $.Autocompleter = function(input, options) {
  54.  
  55.     var KEY = {
  56.         UP: 38,
  57.         DOWN: 40,
  58.         DEL: 46,
  59.         TAB: 9,
  60.         RETURN: 13,
  61.         ESC: 27,
  62.         COMMA: 188,
  63.         PAGEUP: 33,
  64.         PAGEDOWN: 34,
  65.         BACKSPACE: 8
  66.     };
  67.  
  68.     // Create $ object for input element
  69.     var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass);
  70.  
  71.     var timeout;
  72.     var previousValue = "";
  73.     var cache = $.Autocompleter.Cache(options);
  74.     var hasFocus = 0;
  75.     var lastKeyPressCode;
  76.     var config = {
  77.         mouseDownOnSelect: false
  78.     };
  79.     var select = $.Autocompleter.Select(options, input, selectCurrent, config);
  80.    
  81.     var blockSubmit;
  82.    
  83.     // prevent form submit in opera when selecting with return key
  84.     $.browser.opera && $(input.form).bind("submit.autocomplete", function() {
  85.         if (blockSubmit) {
  86.             blockSubmit = false;
  87.             return false;
  88.         }
  89.     });
  90.    
  91.     // only opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all
  92.     $input.bind(($.browser.opera ? "keypress" : "keydown") + ".autocomplete", function(event) {
  93.         // track last key pressed
  94.         lastKeyPressCode = event.keyCode;
  95.         switch(event.keyCode) {
  96.        
  97.             case KEY.UP:
  98.                 event.preventDefault();
  99.                 if ( select.visible() ) {
  100.                     select.prev();
  101.                 } else {
  102.                     onChange(0, true);
  103.                 }
  104.                 break;
  105.                
  106.             case KEY.DOWN:
  107.                 event.preventDefault();
  108.                 if ( select.visible() ) {
  109.                     select.next();
  110.                 } else {
  111.                     onChange(0, true);
  112.                 }
  113.                 break;
  114.                
  115.             case KEY.PAGEUP:
  116.                 event.preventDefault();
  117.                 if ( select.visible() ) {
  118.                     select.pageUp();
  119.                 } else {
  120.                     onChange(0, true);
  121.                 }
  122.                 break;
  123.                
  124.             case KEY.PAGEDOWN:
  125.                 event.preventDefault();
  126.                 if ( select.visible() ) {
  127.                     select.pageDown();
  128.                 } else {
  129.                     onChange(0, true);
  130.                 }
  131.                 break;
  132.            
  133.             // matches also semicolon
  134.             case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA:
  135.             case KEY.TAB:
  136.             case KEY.RETURN:
  137.                 if( selectCurrent() ) {
  138.                     // stop default to prevent a form submit, Opera needs special handling
  139.                     event.preventDefault();
  140.                     blockSubmit = true;
  141.                     return false;
  142.                 }
  143.                 break;
  144.                
  145.             case KEY.ESC:
  146.                 select.hide();
  147.                 break;
  148.                
  149.             default:
  150.                 clearTimeout(timeout);
  151.                 timeout = setTimeout(onChange, options.delay);
  152.                 break;
  153.         }
  154.     }).focus(function(){
  155.         // track whether the field has focus, we shouldn't process any
  156.         // results if the field no longer has focus
  157.         hasFocus++;
  158.     }).blur(function() {
  159.         hasFocus = 0;
  160.         if (!config.mouseDownOnSelect) {
  161.             hideResults();
  162.         }
  163.     }).click(function() {
  164.         // show select when clicking in a focused field
  165.         if ( hasFocus++ > 1 && !select.visible() ) {
  166.             onChange(0, true);
  167.         }
  168.     }).bind("search", function() {
  169.         // TODO why not just specifying both arguments?
  170.         var fn = (arguments.length > 1) ? arguments[1] : null;
  171.         function findValueCallback(q, data) {
  172.             var result;
  173.             if( data && data.length ) {
  174.                 for (var i=0; i < data.length; i++) {
  175.                     if( data[i].result.toLowerCase() == q.toLowerCase() ) {
  176.                         result = data[i];
  177.                         break;
  178.                     }
  179.                 }
  180.             }
  181.             if( typeof fn == "function" ) fn(result);
  182.             else $input.trigger("result", result && [result.data, result.value]);
  183.         }
  184.         $.each(trimWords($input.val()), function(i, value) {
  185.             request(value, findValueCallback, findValueCallback);
  186.         });
  187.     }).bind("flushCache", function() {
  188.         cache.flush();
  189.     }).bind("setOptions", function() {
  190.         $.extend(options, arguments[1]);
  191.         // if we've updated the data, repopulate
  192.         if ( "data" in arguments[1] )
  193.             cache.populate();
  194.     }).bind("unautocomplete", function() {
  195.         select.unbind();
  196.         $input.unbind();
  197.         $(input.form).unbind(".autocomplete");
  198.     });
  199.    
  200.    
  201.     function selectCurrent() {
  202.         var selected = select.selected();
  203.         if( !selected )
  204.             return false;
  205.        
  206.         var v = selected.result;
  207.         previousValue = v;
  208.        
  209.         if ( options.multiple ) {
  210.             var words = trimWords($input.val());
  211.             if ( words.length > 1 ) {
  212.                 v = words.slice(0, words.length - 1).join( options.multipleSeparator ) + options.multipleSeparator + v;
  213.             }
  214.             v += options.multipleSeparator;
  215.         }
  216.        
  217.         $input.val(v);
  218.         hideResultsNow();
  219.         $input.trigger("result", [selected.data, selected.value]);
  220.         return true;
  221.     }
  222.    
  223.     function onChange(crap, skipPrevCheck) {
  224.         if( lastKeyPressCode == KEY.DEL ) {
  225.             select.hide();
  226.             return;
  227.         }
  228.        
  229.         var currentValue = $input.val();
  230.        
  231.         if ( !skipPrevCheck && currentValue == previousValue )
  232.             return;
  233.        
  234.         previousValue = currentValue;
  235.        
  236.         currentValue = lastWord(currentValue);
  237.         if ( currentValue.length >= options.minChars) {
  238.             $input.addClass(options.loadingClass);
  239.             if (!options.matchCase)
  240.                 currentValue = currentValue.toLowerCase();
  241.             request(currentValue, receiveData, hideResultsNow);
  242.         } else {
  243.             stopLoading();
  244.             select.hide();
  245.         }
  246.     };
  247.    
  248.     function trimWords(value) {
  249.         if ( !value ) {
  250.             return [""];
  251.         }
  252.         var words = value.split( options.multipleSeparator );
  253.         var result = [];
  254.         $.each(words, function(i, value) {
  255.             if ( $.trim(value) )
  256.                 result[i] = $.trim(value);
  257.         });
  258.         return result;
  259.     }
  260.    
  261.     function lastWord(value) {
  262.         if ( !options.multiple )
  263.             return value;
  264.         var words = trimWords(value);
  265.         return words[words.length - 1];
  266.     }
  267.    
  268.     // fills in the input box w/the first match (assumed to be the best match)
  269.     // q: the term entered
  270.     // sValue: the first matching result
  271.     function autoFill(q, sValue){
  272.         // autofill in the complete box w/the first match as long as the user hasn't entered in more data
  273.         // if the last user key pressed was backspace, don't autofill
  274.         if( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) {
  275.             // fill in the value (keep the case the user has typed)
  276.             $input.val($input.val() + sValue.substring(lastWord(previousValue).length));
  277.             // select the portion of the value not typed by the user (so the next character will erase)
  278.             $.Autocompleter.Selection(input, previousValue.length, previousValue.length + sValue.length);
  279.         }
  280.     };
  281.  
  282.     function hideResults() {
  283.         clearTimeout(timeout);
  284.         timeout = setTimeout(hideResultsNow, 200);
  285.     };
  286.  
  287.     function hideResultsNow() {
  288.         var wasVisible = select.visible();
  289.         select.hide();
  290.         clearTimeout(timeout);
  291.         stopLoading();
  292.         if (options.mustMatch) {
  293.             // call search and run callback
  294.             $input.search(
  295.                 function (result){
  296.                     // if no value found, clear the input box
  297.                     if( !result ) {
  298.                         if (options.multiple) {
  299.                             var words = trimWords($input.val()).slice(0, -1);
  300.                             $input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "") );
  301.                         }
  302.                         else
  303.                             $input.val( "" );
  304.                     }
  305.                 }
  306.             );
  307.         }
  308.         if (wasVisible)
  309.             // position cursor at end of input field
  310.             $.Autocompleter.Selection(input, input.value.length, input.value.length);
  311.     };
  312.  
  313.     function receiveData(q, data) {
  314.         if ( data && data.length && hasFocus ) {
  315.             stopLoading();
  316.             select.display(data, q);
  317.             autoFill(q, data[0].value);
  318.             select.show();
  319.         } else {
  320.             hideResultsNow();
  321.         }
  322.     };
  323.  
  324.     function request(term, success, failure) {
  325.         if (!options.matchCase)
  326.             term = term.toLowerCase();
  327.         var data = cache.load(term);
  328.         // recieve the cached data
  329.         if (data && data.length) {
  330.             success(term, data);
  331.         // if an AJAX url has been supplied, try loading the data now
  332.         } else if( (typeof options.url == "string") && (options.url.length > 0) ){
  333.            
  334.             var extraParams = {
  335.                 timestamp: +new Date()
  336.             };
  337.             $.each(options.extraParams, function(key, param) {
  338.                 extraParams[key] = typeof param == "function" ? param() : param;
  339.             });
  340.            
  341.             $.ajax({
  342.                 // try to leverage ajaxQueue plugin to abort previous requests
  343.                 mode: "abort",
  344.                 // limit abortion to this input
  345.                 port: "autocomplete" + input.name,
  346.                 dataType: options.dataType,
  347.                 url: options.url,
  348.                 data: $.extend({
  349.                     q: lastWord(term),
  350.                     limit: options.max
  351.                 }, extraParams),
  352.                 success: function(data) {
  353.                     var parsed = options.parse && options.parse(data) || parse(data);
  354.                     cache.add(term, parsed);
  355.                     success(term, parsed);
  356.                 }
  357.             });
  358.         } else {
  359.             // if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match
  360.             select.emptyList();
  361.             failure(term);
  362.         }
  363.     };
  364.    
  365.     function parse(data) {
  366.         var parsed = [];
  367.         var rows = data.split("\n");
  368.         for (var i=0; i < rows.length; i++) {
  369.             var row = $.trim(rows[i]);
  370.             if (row) {
  371.                 row = row.split("|");
  372.                 parsed[parsed.length] = {
  373.                     data: row,
  374.                     value: row[0],
  375.                     result: options.formatResult && options.formatResult(row, row[0]) || row[0]
  376.                 };
  377.             }
  378.         }
  379.         return parsed;
  380.     };
  381.  
  382.     function stopLoading() {
  383.         $input.removeClass(options.loadingClass);
  384.     };
  385.  
  386. };
  387.  
  388. $.Autocompleter.defaults = {
  389.     inputClass: "ac_input",
  390.     resultsClass: "ac_results",
  391.     loadingClass: "ac_loading",
  392.     minChars: 1,
  393.     delay: 400,
  394.     matchCase: false,
  395.     matchSubset: true,
  396.     matchContains: false,
  397.     cacheLength: 10,
  398.     max: 100,
  399.     mustMatch: false,
  400.     extraParams: {},
  401.     selectFirst: true,
  402.     formatItem: function(row) { return row[0]; },
  403.     formatMatch: null,
  404.     autoFill: false,
  405.     width: 0,
  406.     multiple: false,
  407.     multipleSeparator: ", ",
  408.     highlight: function(value, term) {
  409.         return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
  410.     },
  411.     scroll: true,
  412.     scrollHeight: 180
  413. };
  414.  
  415. $.Autocompleter.Cache = function(options) {
  416.  
  417.     var data = {};
  418.     var length = 0;
  419.    
  420.     function matchSubset(s, sub) {
  421.         if (!options.matchCase)
  422.             s = s.toLowerCase();
  423.         var i = s.indexOf(sub);
  424.         if (options.matchContains == "word"){
  425.             i = s.toLowerCase().search("\\b" + sub.toLowerCase());
  426.         }
  427.         if (i == -1) return false;
  428.         return i == 0 || options.matchContains;
  429.     };
  430.    
  431.     function add(q, value) {
  432.         if (length > options.cacheLength){
  433.             flush();
  434.         }
  435.         if (!data[q]){
  436.             length++;
  437.         }
  438.         data[q] = value;
  439.     }
  440.    
  441.     function populate(){
  442.         if( !options.data ) return false;
  443.         // track the matches
  444.         var stMatchSets = {},
  445.             nullData = 0;
  446.  
  447.         // no url was specified, we need to adjust the cache length to make sure it fits the local data store
  448.         if( !options.url ) options.cacheLength = 1;
  449.        
  450.         // track all options for minChars = 0
  451.         stMatchSets[""] = [];
  452.        
  453.         // loop through the array and create a lookup structure
  454.         for ( var i = 0, ol = options.data.length; i < ol; i++ ) {
  455.             var rawValue = options.data[i];
  456.             // if rawValue is a string, make an array otherwise just reference the array
  457.             rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue;
  458.            
  459.             var value = options.formatMatch(rawValue, i+1, options.data.length);
  460.             if ( value === false )
  461.                 continue;
  462.                
  463.             var firstChar = value.charAt(0).toLowerCase();
  464.             // if no lookup array for this character exists, look it up now
  465.             if( !stMatchSets[firstChar] )
  466.                 stMatchSets[firstChar] = [];
  467.  
  468.             // if the match is a string
  469.             var row = {
  470.                 value: value,
  471.                 data: rawValue,
  472.                 result: options.formatResult && options.formatResult(rawValue) || value
  473.             };
  474.            
  475.             // push the current match into the set list
  476.             stMatchSets[firstChar].push(row);
  477.  
  478.             // keep track of minChars zero items
  479.             if ( nullData++ < options.max ) {
  480.                 stMatchSets[""].push(row);
  481.             }
  482.         };
  483.  
  484.         // add the data items to the cache
  485.         $.each(stMatchSets, function(i, value) {
  486.             // increase the cache size
  487.             options.cacheLength++;
  488.             // add to the cache
  489.             add(i, value);
  490.         });
  491.     }
  492.    
  493.     // populate any existing data
  494.     setTimeout(populate, 25);
  495.    
  496.     function flush(){
  497.         data = {};
  498.         length = 0;
  499.     }
  500.    
  501.     return {
  502.         flush: flush,
  503.         add: add,
  504.         populate: populate,
  505.         load: function(q) {
  506.             if (!options.cacheLength || !length)
  507.                 return null;
  508.             /*
  509.              * if dealing w/local data and matchContains than we must make sure
  510.              * to loop through all the data collections looking for matches
  511.              */
  512.             if( !options.url && options.matchContains ){
  513.                 // track all matches
  514.                 var csub = [];
  515.                 // loop through all the data grids for matches
  516.                 for( var k in data ){
  517.                     // don't search through the stMatchSets[""] (minChars: 0) cache
  518.                     // this prevents duplicates
  519.                     if( k.length > 0 ){
  520.                         var c = data[k];
  521.                         $.each(c, function(i, x) {
  522.                             // if we've got a match, add it to the array
  523.                             if (matchSubset(x.value, q)) {
  524.                                 csub.push(x);
  525.                             }
  526.                         });
  527.                     }
  528.                 }              
  529.                 return csub;
  530.             } else
  531.             // if the exact item exists, use it
  532.             if (data[q]){
  533.                 return data[q];
  534.             } else
  535.             if (options.matchSubset) {
  536.                 for (var i = q.length - 1; i >= options.minChars; i--) {
  537.                     var c = data[q.substr(0, i)];
  538.                     if (c) {
  539.                         var csub = [];
  540.                         $.each(c, function(i, x) {
  541.                             if (matchSubset(x.value, q)) {
  542.                                 csub[csub.length] = x;
  543.                             }
  544.                         });
  545.                         return csub;
  546.                     }
  547.                 }
  548.             }
  549.             return null;
  550.         }
  551.     };
  552. };
  553.  
  554. $.Autocompleter.Select = function (options, input, select, config) {
  555.     var CLASSES = {
  556.         ACTIVE: "ac_over"
  557.     };
  558.    
  559.     var listItems,
  560.         active = -1,
  561.         data,
  562.         term = "",
  563.         needsInit = true,
  564.         element,
  565.         list;
  566.    
  567.     // Create results
  568.     function init() {
  569.         if (!needsInit)
  570.             return;
  571.         element = $("<div/>")
  572.         .hide()
  573.         .addClass(options.resultsClass)
  574.         .css("position", "absolute")
  575.         .appendTo(document.body);
  576.    
  577.         list = $("<ul/>").appendTo(element).mouseover( function(event) {
  578.             if(target(event).nodeName && target(event).nodeName.toUpperCase() == 'LI') {
  579.                 active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event));
  580.                 $(target(event)).addClass(CLASSES.ACTIVE);            
  581.             }
  582.         }).click(function(event) {
  583.             $(target(event)).addClass(CLASSES.ACTIVE);
  584.             select();
  585.             // TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focus
  586.             input.focus();
  587.             return false;
  588.         }).mousedown(function() {
  589.             config.mouseDownOnSelect = true;
  590.         }).mouseup(function() {
  591.             config.mouseDownOnSelect = false;
  592.         });
  593.        
  594.         if( options.width > 0 )
  595.             element.css("width", options.width);
  596.            
  597.         needsInit = false;
  598.     }
  599.    
  600.     function target(event) {
  601.         var element = event.target;
  602.         while(element && element.tagName != "LI")
  603.             element = element.parentNode;
  604.         // more fun with IE, sometimes event.target is empty, just ignore it then
  605.         if(!element)
  606.             return [];
  607.         return element;
  608.     }
  609.  
  610.     function moveSelect(step) {
  611.         listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
  612.         movePosition(step);
  613.         var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
  614.         if(options.scroll) {
  615.             var offset = 0;
  616.             listItems.slice(0, active).each(function() {
  617.                 offset += this.offsetHeight;
  618.             });
  619.             if((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
  620.                 list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
  621.             } else if(offset < list.scrollTop()) {
  622.                 list.scrollTop(offset);
  623.             }
  624.         }
  625.     };
  626.    
  627.     function movePosition(step) {
  628.         active += step;
  629.         if (active < 0) {
  630.             active = listItems.size() - 1;
  631.         } else if (active >= listItems.size()) {
  632.             active = 0;
  633.         }
  634.     }
  635.    
  636.     function limitNumberOfItems(available) {
  637.         return options.max && options.max < available
  638.             ? options.max
  639.             : available;
  640.     }
  641.    
  642.     function fillList() {
  643.         list.empty();
  644.         var max = limitNumberOfItems(data.length);
  645.         for (var i=0; i < max; i++) {
  646.             if (!data[i])
  647.                 continue;
  648.             var formatted = options.formatItem(data[i].data, i+1, max, data[i].value, term);
  649.             if ( formatted === false )
  650.                 continue;
  651.             var li = $("<li/>").html( options.highlight(formatted, term) ).addClass(i%2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];
  652.             $.data(li, "ac_data", data[i]);
  653.         }
  654.         listItems = list.find("li");
  655.         if ( options.selectFirst ) {
  656.             listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
  657.             active = 0;
  658.         }
  659.         // apply bgiframe if available
  660.         if ( $.fn.bgiframe )
  661.             list.bgiframe();
  662.     }
  663.    
  664.     return {
  665.         display: function(d, q) {
  666.             init();
  667.             data = d;
  668.             term = q;
  669.             fillList();
  670.         },
  671.         next: function() {
  672.             moveSelect(1);
  673.         },
  674.         prev: function() {
  675.             moveSelect(-1);
  676.         },
  677.         pageUp: function() {
  678.             if (active != 0 && active - 8 < 0) {
  679.                 moveSelect( -active );
  680.             } else {
  681.                 moveSelect(-8);
  682.             }
  683.         },
  684.         pageDown: function() {
  685.             if (active != listItems.size() - 1 && active + 8 > listItems.size()) {
  686.                 moveSelect( listItems.size() - 1 - active );
  687.             } else {
  688.                 moveSelect(8);
  689.             }
  690.         },
  691.         hide: function() {
  692.             element && element.hide();
  693.             listItems && listItems.removeClass(CLASSES.ACTIVE);
  694.             active = -1;
  695.         },
  696.         visible : function() {
  697.             return element && element.is(":visible");
  698.         },
  699.         current: function() {
  700.             return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);
  701.         },
  702.         show: function() {
  703.             var offset = $(input).offset();
  704.             element.css({
  705.                 width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(),
  706.                 top: offset.top + input.offsetHeight,
  707.                 left: offset.left
  708.             }).show();
  709.             if(options.scroll) {
  710.                 list.scrollTop(0);
  711.                 list.css({
  712.                     maxHeight: options.scrollHeight,
  713.                     overflow: 'auto'
  714.                 });
  715.                
  716.                 if($.browser.msie && typeof document.body.style.maxHeight === "undefined") {
  717.                     var listHeight = 0;
  718.                     listItems.each(function() {
  719.                         listHeight += this.offsetHeight;
  720.                     });
  721.                     var scrollbarsVisible = listHeight > options.scrollHeight;
  722.                     list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight );
  723.                     if (!scrollbarsVisible) {
  724.                         // IE doesn't recalculate width when scrollbar disappears
  725.                         listItems.width( list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right")) );
  726.                     }
  727.                 }
  728.                
  729.             }
  730.         },
  731.         selected: function() {
  732.             var selected = listItems && listItems.filter("." + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);
  733.             return selected && selected.length && $.data(selected[0], "ac_data");
  734.         },
  735.         emptyList: function (){
  736.             list && list.empty();
  737.         },
  738.         unbind: function() {
  739.             element && element.remove();
  740.         }
  741.     };
  742. };
  743.  
  744. $.Autocompleter.Selection = function(field, start, end) {
  745.     if( field.createTextRange ){
  746.         var selRange = field.createTextRange();
  747.         selRange.collapse(true);
  748.         selRange.moveStart("character", start);
  749.         selRange.moveEnd("character", end);
  750.         selRange.select();
  751.     } else if( field.setSelectionRange ){
  752.         field.setSelectionRange(start, end);
  753.     } else {
  754.         if( field.selectionStart ){
  755.             field.selectionStart = start;
  756.             field.selectionEnd = end;
  757.         }
  758.     }
  759.     field.focus();
  760. };
  761.  
  762. })(jQuery);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement