skip to Main Content

I have a JSON file which I want to use to fill in an auto-complete dynamic menu. I want to append this through className since the input texts are dynamic.

Sample json data in the file(.json) is as below:

[
  {"Id":"1", "CountryId":"201", "DailingCode":"196", "countryName":"SUDAN", "City":"khartoum", "Code":"KRT"},
  {"Id":"2", "CountryId":"110", "DailingCode":"+254", "countryName":"KENYA", "City":"Nairobi", "Code":"NBO"},
  {"Id":"3", "CountryId":"196", "DailingCode":"+252", "countryName":"SOMALIA", "City":"Mogadishu", "Code":"MGQ"},
  {"Id":"4", "CountryId":"68", "DailingCode":"+251", "countryName":"ETHIOPIA", "City":"Addis Ababa", "Code":"ADD"},
  {"Id":"5", "CountryId":"59", "DailingCode":"+253", "countryName":"DJIBOUTI", "City":"DJIBOUTI", "Code":"JIB"},
  //and so on
]

I want to be able bind them to any input texts with SearchPlaces class with auto-complete. The user should be able to search with City or Code.

So far I have tried the code below which works fine for input select. I could combine this with select2JS but the better option would be to use input text with auto-complete.

function GetPlaces() {


        let dropdown = $('.SearchPlaces');

        dropdown.empty();

        dropdown.append('<option selected="true" disabled>Search...</option>');
        dropdown.prop('selectedIndex', 0);

        const url = './Places.json';

        $.getJSON(url, function (data) {
            $.each(data, function (key, entry) {
                dropdown.append($('<option></option>').attr('value', entry.code).text(entry.City));
            })
        });
    }

I aslo applied select2JS for searching.

//Searchable Dropdown List
     $(document).ready(function () {
         $('.SearchPlaces').select2();
     });

One other problem with the above code is that when the user selects City from the seacrh, the result is all the Cities in the Json File.

Can someone help me with is or give me a direction of how/where to go about it?

I also saw this and this questions here. They were the closet resource I have come across, but I could not get anything from them.

Edit:

In simple terms, I want to use the content of the .json file in any input text type having the SearchPlaces class using JavScript/jQuery. The search Params are City & Code and the displayed search option(auto-complete as the user types) is City which will be set as the text after the user selects one from the search options.

2

Answers


  1. Chosen as BEST ANSWER

    Thanks @76484, Here Goes My final solution.

     <select class="SearchPlaces place1" id="place1" name="place1"></select>
    
     <select class="SearchPlaces place2" id="place2" name="place2"></select>
    
    
     <button id="btnGetSelectedPlaces" type="button">Log current value</button>
    
    
    
    function GetPlaces() {
            //console.log('GetRoutes()');
    
            let dropdown = $('.SearchPlaces');
    
            dropdown.empty();
    
            dropdown.append('<option selected="true" disabled>Search...</option>');
            dropdown.prop('selectedIndex', 0);
    
            const url = './Places.json'; //json file directory
    
            $.getJSON(url, function (data) {
                //console.log(data);
                $.each(data, function (key, entry) {
                    dropdown.append($('<option></option>').attr('value', entry.code).text(entry.name));
                })
            });
        }
    

    Call GetPlaces() where you need (Document.ready and in AddPlace button click event in my case)

    I also changed the the custom matcher into function since I wanted to use it in the dynamically added selects as well.

    function GetPlacesCustomMatcher(){
    // Custom matcher
        $(function () {
            $('.Route').select2({
                matcher: function (params, data) {
                    if ($.trim(params.term) === '') {
                        return null;
                    }
    
                    const term = params.term.toLowerCase();
    
                    if (data.text.toLowerCase().indexOf(term) > -1) {
                        return data;
                    }
    
                    if (data.id.toLowerCase().indexOf(term) > -1) {
                        return data;
                    }
    
                    return null;
                }
            });
        });
    }
    

    To get the selected options

     $('#btnGetSelectedPlaces').on('click', function(){
          var Val1 = $("#place1").val();
          var text1 = $("#place1").select2('data')[0].text;
    
          var text2 = $("#place2").val();
          var Val2 = $("#place2").select2('data')[0].text;
    
          console.log('place 1 value : '+Val1+', place 1 text : '+text1 );
          console.log('place 2 value : '+Val2+', place  text : '+);
     });
    

    here I used the ids to get the value & text, you can use the class or name attributes as well or you can loop them through if you have multiple selects tags

    also Note ``inex[0] in getting the text, I noticed that everytime you change the selected option, the text continues to append in an array like and the current selected option text is alway at index[0]


  2. I think Select2 is a good choice for this because you have more complex matching criteria – the user should be able to search by city name or code.

    Select2 has support for you providing a custom matcher.

    However, before you can write a custom matcher, you will need to ensure you are setting each option’s value correctly. You haven’t upper-cased code. It should be:

    dropdown.append($('<option></option>').attr('value', entry.Code).text(entry.City));
    

    With that fixed, we can create our custom matcher:

    $('.SearchPlaces').select2({
      matcher: function(params, data) {
        if ($.trim(params.term) === '') {
          return data;
        }
    
        const term = params.term.toLowerCase();
    
        // data.text corresponds to the text content of the <option>
        if (data.text.toLowerCase().indexOf(term) > -1) {
          return data;
        }
    
        // data.id corresponds to the value of the <option>
        if (data.id.toLowerCase().indexOf(term) > -1) {
          return data;
        }
    
        return null;
      }
    );
    

    Here is a fiddle for reference.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search