2013-01-15 18:25:11 +00:00
/ * *
2013-03-27 19:01:24 +00:00
* Ajax Autocomplete for jQuery , version 1.2 . 5
2013-01-15 18:25:11 +00:00
* ( c ) 2013 Tomas Kirda
*
* Ajax Autocomplete for jQuery is freely distributable under the terms of an MIT - style license .
* For details , see the web site : http : //www.devbridge.com/projects/autocomplete/jquery/
*
* /
2013-03-27 19:01:24 +00:00
( function ( e ) { "function" === typeof define && define . amd ? define ( [ "jquery" ] , e ) : e ( jQuery ) } ) ( function ( e ) { function f ( a , b ) { var c = function ( ) { } , c = { autoSelectFirst : ! 1 , appendTo : "body" , serviceUrl : null , lookup : null , onSelect : null , width : "auto" , minChars : 1 , maxHeight : 300 , deferRequestBy : 0 , params : { } , formatResult : f . formatResult , delimiter : null , zIndex : 9999 , type : "GET" , noCache : ! 1 , onSearchStart : c , onSearchComplete : c , containerClass : "autocomplete-suggestions" , tabDisabled : ! 1 , dataType : "text" , lookupFilter : function ( a , b , c ) { return - 1 !==
a . value . toLowerCase ( ) . indexOf ( c ) } , paramName : "query" , transformResult : function ( a ) { return "string" === typeof a ? e . parseJSON ( a ) : a } } ; this . element = a ; this . el = e ( a ) ; this . suggestions = [ ] ; this . badQueries = [ ] ; this . selectedIndex = - 1 ; this . currentValue = this . element . value ; this . intervalId = 0 ; this . cachedResponse = [ ] ; this . onChange = this . onChangeInterval = null ; this . isLocal = this . ignoreValueChange = ! 1 ; this . suggestionsContainer = null ; this . options = e . extend ( { } , c , b ) ; this . classes = { selected : "autocomplete-selected" , suggestion : "autocomplete-suggestion" } ;
this . initialize ( ) ; this . setOptions ( b ) } var h = { extend : function ( a , b ) { return e . extend ( a , b ) } , addEvent : function ( a , b , c ) { if ( a . addEventListener ) a . addEventListener ( b , c , ! 1 ) ; else if ( a . attachEvent ) a . attachEvent ( "on" + b , c ) ; else throw Error ( "Browser doesn't support addEventListener or attachEvent" ) ; } , removeEvent : function ( a , b , c ) { a . removeEventListener ? a . removeEventListener ( b , c , ! 1 ) : a . detachEvent && a . detachEvent ( "on" + b , c ) } , createNode : function ( a ) { var b = document . createElement ( "div" ) ; b . innerHTML = a ; return b . firstChild } } ; f . utils =
h ; e . Autocomplete = f ; f . formatResult = function ( a , b ) { var c = "(" + b . replace ( RegExp ( "(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\)" , "g" ) , "\\$1" ) + ")" ; return a . value . replace ( RegExp ( c , "gi" ) , "<strong>$1</strong>" ) } ; f . prototype = { killerFn : null , initialize : function ( ) { var a = this , b = "." + a . classes . suggestion , c = a . classes . selected , d = a . options , g ; a . element . setAttribute ( "autocomplete" , "off" ) ; a . killerFn = function ( b ) { 0 === e ( b . target ) . closest ( "." + a . options . containerClass ) . length && ( a . killSuggestions ( ) , a . disableKillerFn ( ) ) } ;
if ( ! d . width || "auto" === d . width ) d . width = a . el . outerWidth ( ) ; a . suggestionsContainer = f . utils . createNode ( '<div class="' + d . containerClass + '" style="position: absolute; display: none;"></div>' ) ; g = e ( a . suggestionsContainer ) ; g . appendTo ( d . appendTo ) . width ( d . width ) ; g . on ( "mouseover" , b , function ( ) { a . activate ( e ( this ) . data ( "index" ) ) } ) ; g . on ( "mouseout" , function ( ) { a . selectedIndex = - 1 ; g . children ( "." + c ) . removeClass ( c ) } ) ; g . on ( "click" , b , function ( ) { a . select ( e ( this ) . data ( "index" ) , ! 1 ) } ) ; a . fixPosition ( ) ; if ( window . opera ) a . el . on ( "keypress" ,
function ( b ) { a . onKeyPress ( b ) } ) ; else a . el . on ( "keydown" , function ( b ) { a . onKeyPress ( b ) } ) ; a . el . on ( "keyup" , function ( b ) { a . onKeyUp ( b ) } ) ; a . el . on ( "blur" , function ( ) { a . onBlur ( ) } ) ; a . el . on ( "focus" , function ( ) { a . fixPosition ( ) } ) } , onBlur : function ( ) { this . enableKillerFn ( ) } , setOptions : function ( a ) { var b = this . options ; h . extend ( b , a ) ; if ( this . isLocal = e . isArray ( b . lookup ) ) b . lookup = this . verifySuggestionsFormat ( b . lookup ) ; e ( this . suggestionsContainer ) . css ( { "max-height" : b . maxHeight + "px" , width : b . width + "px" , "z-index" : b . zIndex } ) } , clearCache : function ( ) { this . cachedResponse =
[ ] ; this . badQueries = [ ] } , disable : function ( ) { this . disabled = ! 0 } , enable : function ( ) { this . disabled = ! 1 } , fixPosition : function ( ) { var a ; "body" === this . options . appendTo && ( a = this . el . offset ( ) , e ( this . suggestionsContainer ) . css ( { top : a . top + this . el . outerHeight ( ) + "px" , left : a . left + "px" } ) ) } , enableKillerFn : function ( ) { e ( document ) . on ( "click" , this . killerFn ) } , disableKillerFn : function ( ) { e ( document ) . off ( "click" , this . killerFn ) } , killSuggestions : function ( ) { var a = this ; a . stopKillSuggestions ( ) ; a . intervalId = window . setInterval ( function ( ) { a . hide ( ) ;
2013-02-08 20:51:45 +00:00
a . stopKillSuggestions ( ) } , 300 ) } , stopKillSuggestions : function ( ) { window . clearInterval ( this . intervalId ) } , onKeyPress : function ( a ) { if ( ! this . disabled && ! this . visible && 40 === a . keyCode && this . currentValue ) this . suggest ( ) ; else if ( ! this . disabled && this . visible ) { switch ( a . keyCode ) { case 27 : this . el . val ( this . currentValue ) ; this . hide ( ) ; break ; case 9 : case 13 : if ( - 1 === this . selectedIndex ) { this . hide ( ) ; return } this . select ( this . selectedIndex , 13 === a . keyCode ) ; if ( 9 === a . keyCode && ! 1 === this . options . tabDisabled ) return ; break ; case 38 : this . moveUp ( ) ;
break ; case 40 : this . moveDown ( ) ; break ; default : return } a . stopImmediatePropagation ( ) ; a . preventDefault ( ) } } , onKeyUp : function ( a ) { var b = this ; if ( ! b . disabled ) { switch ( a . keyCode ) { case 38 : case 40 : return } clearInterval ( b . onChangeInterval ) ; if ( b . currentValue !== b . el . val ( ) ) if ( 0 < b . options . deferRequestBy ) b . onChangeInterval = setInterval ( function ( ) { b . onValueChange ( ) } , b . options . deferRequestBy ) ; else b . onValueChange ( ) } } , onValueChange : function ( ) { var a ; clearInterval ( this . onChangeInterval ) ; this . currentValue = this . element . value ;
2013-03-27 19:01:24 +00:00
a = this . getQuery ( this . currentValue ) ; this . selectedIndex = - 1 ; this . ignoreValueChange ? this . ignoreValueChange = ! 1 : a . length < this . options . minChars ? this . hide ( ) : this . getSuggestions ( a ) } , getQuery : function ( a ) { var b = this . options . delimiter ; if ( ! b ) return e . trim ( a ) ; a = a . split ( b ) ; return e . trim ( a [ a . length - 1 ] ) } , getSuggestionsLocal : function ( a ) { var b = a . toLowerCase ( ) , c = this . options . lookupFilter ; return { suggestions : e . grep ( this . options . lookup , function ( d ) { return c ( d , a , b ) } ) } } , getSuggestions : function ( a ) { var b , c = this , d = c . options ;
( b = c . isLocal ? c . getSuggestionsLocal ( a ) : c . cachedResponse [ a ] ) && e . isArray ( b . suggestions ) ? ( c . suggestions = b . suggestions , c . suggest ( ) ) : c . isBadQuery ( a ) || ( d . params [ d . paramName ] = a , d . onSearchStart . call ( c . element , d . params ) , e . ajax ( { url : d . serviceUrl , data : d . params , type : d . type , dataType : d . dataType } ) . done ( function ( b ) { c . processResponse ( b , a ) ; d . onSearchComplete . call ( c . element , a ) } ) ) } , isBadQuery : function ( a ) { for ( var b = this . badQueries , c = b . length ; c -- ; ) if ( 0 === a . indexOf ( b [ c ] ) ) return ! 0 ; return ! 1 } , hide : function ( ) { this . visible = ! 1 ;
this . selectedIndex = - 1 ; e ( this . suggestionsContainer ) . hide ( ) } , suggest : function ( ) { if ( 0 === this . suggestions . length ) this . hide ( ) ; else { var a = this . options . formatResult , b = this . getQuery ( this . currentValue ) , c = this . classes . suggestion , d = this . classes . selected , g = e ( this . suggestionsContainer ) , f = "" ; e . each ( this . suggestions , function ( d , e ) { f += '<div class="' + c + '" data-index="' + d + '">' + a ( e , b ) + "</div>" } ) ; g . html ( f ) . show ( ) ; this . visible = ! 0 ; this . options . autoSelectFirst && ( this . selectedIndex = 0 , g . children ( ) . first ( ) . addClass ( d ) ) } } , verifySuggestionsFormat : function ( a ) { return a . length &&
"string" === typeof a [ 0 ] ? e . map ( a , function ( a ) { return { value : a , data : null } } ) : a } , processResponse : function ( a , b ) { var c = this . options , d = c . transformResult ( a , b ) ; d . suggestions = this . verifySuggestionsFormat ( d . suggestions ) ; c . noCache || ( this . cachedResponse [ d [ c . paramName ] ] = d , 0 === d . suggestions . length && this . badQueries . push ( d [ c . paramName ] ) ) ; b === this . getQuery ( this . currentValue ) && ( this . suggestions = d . suggestions , this . suggest ( ) ) } , activate : function ( a ) { var b = this . classes . selected , c = e ( this . suggestionsContainer ) , d = c . children ( ) ;
c . children ( "." + b ) . removeClass ( b ) ; this . selectedIndex = a ; return - 1 !== this . selectedIndex && d . length > this . selectedIndex ? ( a = d . get ( this . selectedIndex ) , e ( a ) . addClass ( b ) , a ) : null } , select : function ( a , b ) { var c = this . suggestions [ a ] ; c && ( this . el . val ( c ) , this . ignoreValueChange = b , this . hide ( ) , this . onSelect ( a ) ) } , moveUp : function ( ) { - 1 !== this . selectedIndex && ( 0 === this . selectedIndex ? ( e ( this . suggestionsContainer ) . children ( ) . first ( ) . removeClass ( this . classes . selected ) , this . selectedIndex = - 1 , this . el . val ( this . currentValue ) ) : this . adjustScroll ( this . selectedIndex -
1 ) ) } , moveDown : function ( ) { this . selectedIndex !== this . suggestions . length - 1 && this . adjustScroll ( this . selectedIndex + 1 ) } , adjustScroll : function ( a ) { var b = this . activate ( a ) , c , d ; b && ( b = b . offsetTop , c = e ( this . suggestionsContainer ) . scrollTop ( ) , d = c + this . options . maxHeight - 25 , b < c ? e ( this . suggestionsContainer ) . scrollTop ( b ) : b > d && e ( this . suggestionsContainer ) . scrollTop ( b - this . options . maxHeight + 25 ) , this . el . val ( this . getValue ( this . suggestions [ a ] . value ) ) ) } , onSelect : function ( a ) { var b = this . options . onSelect ; a = this . suggestions [ a ] ;
this . el . val ( this . getValue ( a . value ) ) ; e . isFunction ( b ) && b . call ( this . element , a ) } , getValue : function ( a ) { var b = this . options . delimiter , c ; if ( ! b ) return a ; c = this . currentValue ; b = c . split ( b ) ; return 1 === b . length ? a : c . substr ( 0 , c . length - b [ b . length - 1 ] . length ) + a } } ; e . fn . autocomplete = function ( a , b ) { return this . each ( function ( ) { var c = e ( this ) , d ; if ( "string" === typeof a ) { if ( d = c . data ( "autocomplete" ) , "function" === typeof d [ a ] ) d [ a ] ( b ) } else d = new f ( this , a ) , c . data ( "autocomplete" , d ) } ) } } ) ;