How to suggest similar words in autocomplete

后端 未结 2 1136
情书的邮戳
情书的邮戳 2021-01-03 12:03

I have an input field for locations with jquery-ui-autocomplete.



        
相关标签:
2条回答
  • 2021-01-03 12:30

    After some additional research and many tries, I found a way to do it. This is specific for Django, so any other more generic proposal is of course more than welcome.

    The solution is based on this tutorial, although with some modifications.


    First of all, import jQuery and jQueryUI in the template:

    <link rel="stylesheet" href="http://code.jquery.com/ui/1.8.18/themes/base/jquery-ui.css" type="text/css" media="all" />
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
    

    Afterwards, in the template itself, you need to assign an id to the input tag. Note that this id is how jquery will identify in which form to run the autocomplete.

    <div class="ui-widget">
      <label for="cities">City: </label>
      <input id="autocomplete-cities">
    </div>
    

    The javascript code is as follows:

    <script type="text/javascript">
        $(document).ready(function(){
            var location_input=$('input[id="autocomplete-city"]');
            location_input.autocomplete({
              source: "/api/get_city_names/",
              minLength: 2
            });
          } );
    
        //   keeps same width as box
          jQuery.ui.autocomplete.prototype._resizeMenu = function () {
              var ul = this.menu.element;
              ul.outerWidth(this.element.outerWidth());
            }
    </script>
    

    And urls.py file needs to be modified accordingly:

    # urls.py
    
    import yourapp.views
    
    urlpatterns = [
        ...,
        url(r'^api/get_city_names/', yourapp.views.get_city_names),
        ...,
    ]
    

    And finally create the django view. The name of the function has to be the same as the one written in urls.py and the one written in the source of the javascript.

    #views.py
    
    import json
    
    def get_city_names(request):
    
        #what was in the question an array is now a python list of dicts.
        #it can also be in some other file and just imported.
        all_city_names = [
        { good_name: 'Mallorca', input_name: 'Palma de Mallorca' },
        { good_name: 'Mallorca', input_name: 'Mallorca' },
        { good_name: 'Mallorca', input_name: 'Majorca' },
        # etc
        ]
    
        if request.is_ajax():
            q = request.GET.get('term', '')
    
            city_names = [c['good_name'] for c in all_city_names if q in c["input_name"]]
            city_names = set(city_names) #removing duplicates
    
            results = []
            for cn in city_names:
                cn_json = {'value': cn}
                results.append(cn_json)
            data = json.dumps(results)
        else:
            data = 'fail'
        mimetype = 'application/json'
        return HttpResponse(data, mimetype)
    

    And the autocomplete should work.

    0 讨论(0)
  • 2021-01-03 12:40

    You are almost there. You can use the response function (see in API) to remove the alternate spellings from the results. Also put the best spelling ("Mallorca" in this case) last. Check this out, I hope the comments are enough to get the logic. Try to type "Ma", or "Maj" and select the only option. In both cases it will display "Mallorca"

     $( function() {
        var availableTags = [      
        { value: 'Mallorca', label: 'Palma de Mallorca' },
        { value: 'Mallorca', label: 'Majorca' },
        { value: 'Mallorca', label: 'Mallorca' },
        { value: 'Madrid', label: 'Madrid' }
        ];
        $( "#tags" ).autocomplete({
          source: availableTags,      
          response: function( event, ui ) {
            var added = [];//Keep here the unique labels that are already in the list
            for(var i=ui.content.length-1;i>=0;i--){//Start a loop, itterate all items backwards
              var cur = ui.content[i].value;//Value of the item
              if($.inArray(cur,added)==-1){//If not already loaded
                added.push(cur);//Put the new item in the list
              }else{            
                ui.content.splice(i,1);//If already loaded remove it from the results
              }
            }        
          }
        });
      } );
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <link href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
    <div class="ui-widget">
      <label for="tags">Tags: </label>
      <input id="tags">
    </div>

    0 讨论(0)
提交回复
热议问题