Jimmy Adaro
Jimmy Adaro

Reputation: 1405

jQuery UI Autocomplete - Also search in title

I have this code for add autocomplete to an input. Is working fine, but the user should be able of search also in the titles (a.k.a "area").

$(document).ready(function() {
    "use strict";

    //Autocomplete
    $(function() {
        $.widget( "custom.catcomplete", $.ui.autocomplete, {
            _create: function() {
                this._super();
                this.widget().menu("option", "items", "> :not(.ui-autocomplete-area)");
            },

            _renderMenu: function(ul,items) {
                var that = this,
                    currentarea = "";

                $.each( items, function(index,item) {
                    var li;
                    if (item.area !== currentarea) {
                        ul.append("<li class='ui-autocomplete-area' aria-label='"+item.area+"'>" + item.area + "</li>");
                        currentarea = item.area;
                    }

                    li = that._renderItemData(ul,item);

                    if (item.area) {
                        li.attr("aria-label", item.area + ":" + item.label);
                    }
                });
            }
        });

        var data = [
            //Title : Value
            { area: "Something", label: "ST A" },
            { area: "Something", label: "ST B" },
            { area: "Other thing", label: "OT A" },
            { area: "Other thing", label: "OT B" },
            { area: "This thing", label: "TT A" }
        ];

        $( "#the_things" ).catcomplete({
            delay: 0,
            source: data
        });
    });
});

So, if the user writes "Something" should appear the title and the related value. Now is only searching in the values ("label").

MCVE: https://jsfiddle.net/p91w9y1o/

What I need to do for make it search in both places?

Upvotes: 0

Views: 747

Answers (1)

Twisty
Twisty

Reputation: 30893

There are a few ways you can do this. One way is to provide a function to your Source instead of data.

Function: The third variation, a callback, provides the most flexibility and can be used to connect any data source to Autocomplete. The callback gets two arguments:

  • A request object, with a single term property, which refers to the value currently in the text input. For example, if the user enters "new yo" in a city field, the Autocomplete term will equal "new yo".

  • A response callback, which expects a single argument: the data to suggest to the user. This data should be filtered based on the provided term, and can be in any of the formats described above for simple local data. It's important when providing a custom source callback to handle errors during the request. You must always call the response callback even if you encounter an error. This ensures that the widget always has the correct state.

When filtering data locally, you can make use of the built-in $.ui.autocomplete.escapeRegex function. It'll take a single string argument and escape all regex characters, making the result safe to pass to new RegExp().

See more: http://api.jqueryui.com/autocomplete/#option-source

This might look like this:

JavaScript

$(function() {
  $.widget("custom.catcomplete", $.ui.autocomplete, {
    _create: function() {
      this._super();
      this.widget().menu("option", "items", "> :not(.ui-autocomplete-area)");
    },

    _renderMenu: function(ul, items) {
      var that = this,
        currentarea = "";

      $.each(items, function(index, item) {
        var li;
        if (item.area !== currentarea) {
          ul.append("<li class='ui-autocomplete-area' aria-label='" + item.area + "'>" + item.area + "</li>");
          currentarea = item.area;
        }

        li = that._renderItemData(ul, item);

        if (item.area) {
          li.attr("aria-label", item.area + ":" + item.label);
        }
      });
    }
  });

  var data = [{
    area: "Something",
    label: "ST A"
  }, {
    area: "Something",
    label: "ST B"
  }, {
    area: "Other thing",
    label: "OT A"
  }, {
    area: "Other thing",
    label: "OT B"
  }, {
    area: "This thing",
    label: "TT A"
  }];

  $("#the_things").catcomplete({
    delay: 0,
    source: function(req, resp) {
      var results = [];
      $.each(data, function(k, v) {
        if (v.area.toLowerCase().search(req.term) !== -1) {
          results.push(v);
        }
        resp(results);
      })
    }
  });
});

Working Example: https://jsfiddle.net/Twisty/ofnt86r9/

Update

New Working Example: https://jsfiddle.net/Twisty/ofnt86r9/2/

  $("#the_things").catcomplete({
    delay: 0,
    source: function(req, resp) {
      var results = [];
      $.each(data, function(k, v) {
        if ((v.area.toLowerCase().search(req.term.toLowerCase()) !== -1) || (v.label.toLowerCase().search(req.term.toLowerCase()) !== -1)) {
          results.push(v);
        }
        resp(results);
      })
    }
  });

This will check both area and label of the term.

Upvotes: 1

Related Questions