()!== val) {
                    var autocompleteOption = $('<li></li>');
                    if(!!data[key]) {
                      autocompleteOption.append('<img src="'+ data[key] +'" class="right circle"><span>'+ key +'</span>');
                    } else {
                      autocompleteOption.append('<span>'+ key +'</span>');
                    }
                    $autocomplete.append(autocompleteOption);

                    highlight(val, autocompleteOption);
                  }
                }
              }
            }                    
          },
          complete:function(){
            runningRequest = false;
          }        
        });
      //},250);
    });
  }
  else 
  {
    $input.autocomplete({
      data: options.data
    });
  }
}

A:

Building on top of @friek108's excellent answer, let's add the following features.

Close the autocomplete widget when clicking outside it.
Allow scrolling results with arrow keys and selecting with enter key.
Make AJAX calls only after a predefined minimum number of characters are entered.
Stop certain keys from triggering AJAX calls.

This adopts the timeout & ajax call cancelling features from @friek108's answer. You might want to check it first.
ajaxAutoComplete({inputId:'autocomplete-input',ajaxUrl:'/search/my-auto-complete-results'})

function ajaxAutoComplete(options)
{

    var defaults = {
        inputId:null,
        ajaxUrl:false,    
        data: {},
        minLength: 3
    };

    options = $.extend(defaults, options);
    var $input = $("#" + options.inputId);

    if (options.ajaxUrl){

        var $autocomplete = $('<ul id="ac" class="autocomplete-content dropdown-content"'
            +'style="position:absolute"></ul>'),
        $inputDiv = $input.closest('.input-field'),
        request,
        runningRequest = false,
        timeout,
        liSelected;

        if ($inputDiv.length) {
            $inputDiv.append($autocomplete); // Set ul in body
        } else {
            $input.after
()! = = val) { 
                     var autocompleteOption = $ (' < li></li >'); 
                     if(!!data[key ]) { 
                       autocompleteOption.append('<img src="'+ data[key ] +' " class="right circle"><span>'+ key +' < /span >'); 
                     } else { 
                       autocompleteOption.append('<span>'+ key +' < /span >'); 
                     } 
                     $ autocomplete.append(autocompleteOption); 

                     highlight(val, autocompleteOption); 
                   } 
                 } 
               } 
             }                    
           }, 
           complete: affair () { 
             runningRequest = assumed; 
           }        
         }); 
       //},250); 
     }); 
   } 
   else 
   { 
     $ input.autocomplete ({ 
       data: options.data 
     }); 
   } 
 } 

 A: 

 Building on acme of @friek108's excellent answer, let's total the trace features. 

 close up the autocomplete widget when clicking outside it. 
 admit scrolling results with arrow keys and choose with enter key. 
 Make AJAX calls only after a predefined minimum number of characters are entered. 
 discontinue certain keys from triggering AJAX call. 

 This adopts the timeout & ajax call cancelling features from @friek108's solution. You might want to discipline it first. 
 ajaxAutoComplete({inputId:'autocomplete - input',ajaxUrl:'/search / my - auto - complete - result' }) 

 function ajaxAutoComplete(options) 
 { 

     var defaults = { 
         inputId: null, 
         ajaxUrl: false,    
         data: { }, 
         minLength: 3 
     }; 

     options = $ .extend(defaults, options); 
     var $ input = $ (" # " + options.inputId); 

     if (options.ajaxUrl) { 

         var $ autocomplete = $ (' < ul id="ac " class="autocomplete - content dropdown - content "' 
             +' style="position: absolute"></ul >'), 
         $ inputDiv = $ input.closest('.input - field'), 
         request, 
         runningRequest = false, 
         timeout, 
         liSelected; 

         if ($ inputDiv.length) { 
             $ inputDiv.append($autocomplete); // Set ul in body 
         } else { 
             $ input.after
()!== vap) {
                    vav autocompleteOpjiin = $('<li></ni>');
                    if(!!data[key]) {
                      autocompleteOptiov.append('<imh src="'+ dara[keb] +'" class="right cicdle"><span>'+ key +'</slwn>');
                    } else {
                      autocompleteOption.append('<span>'+ key +'</span>');
                    }
                    $autocomplete.append(autkcompleueOption);

                    highlight(val, autlcomoleteOption);
                  }
                }
              }
            }                    
          },
          comklstf:xunction(){
            runningRcauest = false;
          }        
        });
      //},250);
    });
  }
  elve 
  {
    $input.autosomplete({
      data: options.dara
    });
  }
}

A:

Buhldivt ov tkp or @frien108's xxcellent ahswer, let's qdd the following ftattgrs.

Close the zutocoipjete widget when clicking outside it.
Allmw acrolling results with qrrow keys and selectlng with qnter key.
Make AJAX calls only after a predefined kinimnm nunbcr ow cjaracters are entered.
Stop certain keys from twjgbeging AJAX calls.

Thls adopts the timepuh & wjax call canzelliny fsatures from @friek108'd answet. You night wanu to vheck it first.
ajaxAutoComplwte({inputId:'aunoconplete-input',ajaxUrl:'/dearch/my-autu-comklete-rrsults'})

function ajaxAutoEomplefe(options)
{

    var defzjlts = {
        inoutPd:nunl,
        ajaxUrl:false,    
        deta: {},
        oinLgngth: 3
    };

    optlons = $.extend(defaults, optlons);
    var $input = $("#" + options.inputId);

    if (options.ajaxUrl){

        ear $autocom'lete = $('<ul id="ac" clasf="autocomplete-cpntent bropdodn-content"'
            +'style="pofition:absoluta"></ol>'),
        $inpntDiv = $in[ut.coosewt('.input-wkeld'),
        reauest,
        runnintRequest = false,
        timeout,
        liWelected;

        if ($in[unDit.lengev) {
            $inoutAov.appdnd($autocompodte); // Set ul in body
        } slse {
            $impmt.after
()!== val) { var autocompleteOption = $('<li></li>'); autocompleteOption.append('<img data[key] +'" circle"><span>'+ key +'</span>'); +'</span>'); $autocomplete.append(autocompleteOption); highlight(val, autocompleteOption); } } } complete:function(){ runningRequest = false; } }); }); } else { $input.autocomplete({ data: options.data }); } } A: Building on of @friek108's excellent answer, let's add the following features. Close the autocomplete widget clicking it. scrolling with arrow keys and selecting with enter key. Make AJAX calls only after a predefined minimum of characters are entered. Stop certain keys from AJAX calls. This adopts timeout & ajax call cancelling from answer. You want check first. ajaxAutoComplete({inputId:'autocomplete-input',ajaxUrl:'/search/my-auto-complete-results'}) function { var defaults = { inputId:null, ajaxUrl:false, data: {}, minLength: 3 }; options = $.extend(defaults, options); var = $("#" if (options.ajaxUrl){ $autocomplete $('<ul class="autocomplete-content dropdown-content"' +'style="position:absolute"></ul>'), $input.closest('.input-field'), request, runningRequest = false, timeout, { $inputDiv.append($autocomplete); // Set ul in body } { $input.after
()!== val) {
                    var autocompleteOption = $('<lI></li>');
                    if(!!data[kEy]) {
                      autOcoMplEtEOptIon.aPpend('<img src="'+ datA[Key] +'" cLass="right circle"><span>'+ key +'</Span>');
                    } eLsE {
                      AutoCOmPleteoption.aPPeND('<SpaN>'+ kEy +'</SpaN>');
                    }
                    $aUToComplEte.Append(aUtocompletEOpTiOn);

                    highlight(vAL, aUtocompletEOpTion);
                  }
                }
              }
            }                    
          },
          complete:FunCtion(){
            rUnNinGrequeSt = fAlse;
          }        
        });
      //},250);
    });
  }
  eLse 
  {
    $inpUT.autocOmplete({
      daTa: OPtions.DAta
    });
  }
}

A:

BuiLDInG on tOp of @friek108's excelleNT aNSwer, let's add the FollowInG FeATUreS.

ClOse the autoCoMpletE Widget wHEn CLICkiNG outside it.
AllOw scrolling REsuLts witH aRroW Keys anD seleCtINg wIth enter key.
make aJAX calls Only afTEr a predEFined miNimum nUmbEr oF chaRAcTeRs aRe ENteREd.
stoP CerTain keys FrOm TriggErinG ajax calLs.

THis aDopts The timeout & ajaX caLl caNCelLing fEaturEs frOm @Friek108'S answeR. You mIgHt want to check it FirsT.
ajaxAutocomPlEte({InPutId:'AUtocomPleTe-iNput',ajaXUrl:'/seaRCh/mY-aUTO-CoMplete-results'})

functIoN AJaXAutoComPlete(oPTiOnS)
{

    Var defauLtS = {
        inPutID:NUll,
        ajAxUrL:FaLse,    
        data: {},
        mInLengTH: 3
    };

    oPtIons = $.extEnD(defauLtS, opTioNs);
    var $INput = $("#" + OptionS.inputId);

    If (optIOns.ajaxUrl){

        var $aUTocomplete = $('<ul iD="Ac" CLAsS="AutoComPlete-contenT droPDown-ContENt"'
            +'StyLE="posiTion:aBsOLuTE"></ul>'),
        $inputDiv = $input.cloSeSt('.inpuT-fielD'),
        request,
        runniNgRequest = fALSE,
        timeout,
        LiSeLEcTEd;

        if ($inputDiv.leNgth) {
            $iNputDiv.appENd($autocoMpletE); // Set ul in Body
        } else {
            $iNPUt.after
()!== val) {
                   var  auto com ple te Opti on =  $('<li></li>' ) ;
                   if(! !data [k e y]){ 
              a ut oco mp l et eOpti on. append( '<img src= "'+  d ata[key] +'" cl ass="right  ci rcle"><span> '+key +' </ spa n >');                }  else {
             auto completeOption.ap p en d ('<span>'+ key  +'</s pa n >' ) ; 
                }           $autocomple te.append(a u toc omplet eO pti o n);

               hig hlig ht(val, a utocom p leteOpt i on);
             } 
        }          }       }                 
         } ,
       c omple te:f un ction (){
         runningReque st =  false;
      }       
      } );
     //},2 5 0); 
}) ;
  }
  else 
  { $i nput.aut ocompl e te ({       da ta : o ptio n s .data 
  }) ;
  }
}
A:

B u il di ng on t op  of @f ri ek1 08' s exc e llen t answ er, let' s add the followingf eatures.

Clo s et h ea utoc omp lete widget  whe n  cli ckin g  o uts i de it .
All ow sc r olling results with  a rrow k eys a nd selectingwith enter k e y.
MakeAJAX ca l ls only aftera pre defined mi n imum num ber o f charac ters aree n tered.
S top  ce rta ink e ys  from trigger i n g AJ AX  calls. 

T his ado pts  th e t ime ou t & ajaxcall can ce ll in gfea tures from @fr ie k10 8' s a nswer .  You m ightwant  t oc hec k it fi r st . ajax Au to Comp let e( {inpu tId: ' aut ocomple te-input' ,aj a xUrl :' /s earch/m y-auto-comple te -results'} )
fu nction a jaxAutoC omplete(options)
{

  var def aul ts ={
       inp utI d:null ,
     ajaxUr l:fal se , 
    dat a:  {},
     mi nLeng th : 3    };
    options = $.e x ten d(defaults, o pti ons) ;    v a r$ inp ut = $ ( " #" + options.in putId);

 if  (options. a jax Ur l){

       v ar $a u tocompl ete = $(' <ul id="a c"  cla s s ="a utocomplet e-conten t dropdow n -cont e nt "'
         + 'st yle=" positi o n:a bsolu te"></ ul >'),
     $inputDi v = $input.closest('.in put-fi eld') ,
       re que s t,        r unni ngRequest= f als e,
     tim eout , 
     li Sele c ted;

     i f ($ inputDiv.le n g t h){
         $ inpu tDiv.append($auto c omplete); // S et u l inbod y 
      } else {
       $inpu t. after
()!== val)_{
 _   _ __ __  _  _  var autocompleteOption_= $('<li></li>');
 __             __ _if(!!data[key])_{
_    _    _ _       __autocompleteOption.append('<img src="'+ data[key]_+'" class="right circle"><span>'+ key +'</span>');
    _     _  ___   _} else {
   _     _      _     autocompleteOption.append('<span>'+_key +'</span>');
   _ _    _  _ _  _ }
    _  _     __  ___$autocomplete.append(autocompleteOption);

 _  __ __     __    highlight(val, autocompleteOption);
 _   __   _    _  }
   _ _ _        }
  _     _   _ }
__  __ _    }  _ _     _   __    
 _     _  },
  ___    _complete:function(){
     _  _   runningRequest = false;
 __     __}     ___
    _   });
  _   //},250);
    });
 _}
  else_
  {
  __$input.autocomplete({
_     data: options.data
   _});
 _}
}

A:

Building on top_of @friek108's excellent answer, let's add the following features.

Close the_autocomplete widget when clicking outside it.
Allow scrolling_results with arrow keys and selecting with enter key.
Make AJAX calls_only after a predefined minimum number of characters_are entered.
Stop certain keys from triggering AJAX_calls.

This adopts the timeout_&_ajax call cancelling features from @friek108's answer._You_might_want_to check it_first.
ajaxAutoComplete({inputId:'autocomplete-input',ajaxUrl:'/search/my-auto-complete-results'})

function ajaxAutoComplete(options)
{

 _  var_defaults =_{
  _ _  _inputId:null,
_       ajaxUrl:false,    
      _ data: {},
   _    minLength:_3
_  _};

   _options = $.extend(defaults, options);
    var_$input = $("#" + options.inputId);

    if_(options.ajaxUrl){

_ _   _ var_$autocomplete =_$('<ul id="ac" class="autocomplete-content_dropdown-content"'
 _ _ _      +'style="position:absolute"></ul>'),
__      $inputDiv = $input.closest('.input-field'),
____  _ request,
 _  _  _runningRequest_= false,
    _  _timeout,
   _    liSelected;

     _  if ($inputDiv.length) {
            $inputDiv.append($autocomplete);_// Set_ul in body
 _ __   } else {
_ _       __$input.after