Search code examples
jqueryajaxjquery-select2jquery-select2-4

Display select2 ajax results into template


I have select2 displaying data after making an ajax call.

 <script>
    $(document).ready(function () {
        $("#citySelect").select2({
            theme: 'bootstrap-5',
            placeholder: "Search for your city",
            dropdownAutoWidth: true,
            width: 'auto',
            minimumInputLength: 3,
            allowClear: true,
            async: true,
            ajax: {
                url:
                    function (params) {
                        return '@GatewaySettings.Value.Url' + '/api/location/cities/' + params.term;
                    },
                contentType: "application/json; charset=utf-8",
                type: 'GET',
                processResults: function (result) {
                    return {
                        results: $.map(result, function (item) {
                            return { id: item.id, text: item.city };
                        }),
                    };
                }
            }
        });
    });
</script>

I am able to search for a list of cities

I would like for the active search results to display as city + ', ' + state + ' ' + zip (i.e. Los Angeles, California 90001) and after a selection display just the city (i.e Los Angeles).

I am trying to follow the documentation, but I keep getting an undefined result.

enter image description here

Here is the output from the console enter image description here

I am sure I am just not understanding how to use the templating.

  <script>
    $(document).ready(function () {
        $("#citySelect").select2({
            theme: 'bootstrap-5',
            placeholder: "Search for your city",
            dropdownAutoWidth: true,
            width: 'auto',
            minimumInputLength: 3,
            allowClear: true,
            async: true,
            templateResult: function (item) {
                console.log(item);
                return item.city + ', ' + item.state + ' ' + item.zip;
            },
            templateSelection: function (item) {
                return item.city
            },
            ajax: {
                url:
                    function (params) {
                        return '@GatewaySettings.Value.Url' + '/api/location/cities/' + params.term;
                    },
                contentType: "application/json; charset=utf-8",
                type: 'GET',
                cache: true,
                processResults: function (result) {
                    return {
                        results: $.map(result, function (item) {
                            return { id: item.id, text: item.city };
                        }),
                    };
                }
            }
        });
    });
</script>

Any help appreciated

Results from console after adding

console.log("RESULTS", JSON.stringify(result, null, 2));

RESULTS [
  {
    "id": 5039,
    "city": "Chandlers Valley",
    "state": "Pennsylvania",
    "zip": null
  },
  {
    "id": 14327,
    "city": "Chandlersville",
    "state": "Ohio",
    "zip": null
  },
  {
    "id": 15915,
    "city": "Chandler",
    "state": "Indiana",
    "zip": null
  },
  {
    "id": 19293,
    "city": "Chandler",
    "state": "Minnesota",
    "zip": null
  },
  {
    "id": 22001,
    "city": "Chandlerville",
    "state": "Illinois",
    "zip": null
  },
  {
    "id": 26294,
    "city": "Chandler",
    "state": "Oklahoma",
    "zip": null
  },
  {
    "id": 26686,
    "city": "Chandler",
    "state": "Texas",
    "zip": null
  },
  {
    "id": 29715,
    "city": "Chandler",
    "state": "Arizona",
    "zip": null
  },
  {
    "id": 29716,
    "city": "Chandler",
    "state": "Arizona",
    "zip": null
  },
  {
    "id": 29717,
    "city": "Chandler",
    "state": "Arizona",
    "zip": null
  }
]

Solution

  • Your $.map() is largely redundant and also excludes the properties you appear to want to use.

    All you really need to do is nest the array under a results property so Select2 can make use of it.

    templateResult: ({ city, state, zip }) =>
      `${city}, ${state} ${zip ?? ""}`.trim(),
    templateSelection: ({ city }) => city,
    ajax: {
      url: ({ term }) =>
        "@GatewaySettings.Value.Url" +
        `/api/location/cities/${encodeURIComponent(term)}`, // encode the term
      processResults: (results) => ({ results }),
    }
    

    Some notes about the ajax properties...

    • The default method (type) is GET
    • The default cache property is true
    • GET requests don't have content so don't require a contentType