简体   繁体   中英

Jquery Autocomplete w/ Categories search, limited to Category chosen by user

The jquery Autocomplete demo page with category shows the following :

屏幕截图1

I want the user to choose the category (Products or People) in a separate button (dropdown list), and then the jquery search to return only the matches in the category chosen by user.

Expected result :

screenshot 2

I am new to jquery, but according to my research I think this could be possible using "functions" as inputs, as said in the answer here (even though the question was different) :

Jquery UI Autocomplete: search from multiple attributes of one array

However I don't know what to do next.

My current code is the code from official doc :

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>jQuery UI Autocomplete - Categories</title>
  <link rel="stylesheet" href="//code.jquery.com/ui/1.12.0/themes/base/jquery-ui.css">
  <link rel="stylesheet" href="/resources/demos/style.css">
  <style>
  .ui-autocomplete-category {
    font-weight: bold;
    padding: .2em .4em;
    margin: .8em 0 .2em;
    line-height: 1.5;    
  }
  </style>
  <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
  <script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
  <script>
  $( function() {
    $.widget( "custom.catcomplete", $.ui.autocomplete, {
      _create: function() {
        this._super();
        this.widget().menu( "option", "items", "> :not(.ui-autocomplete-category)" );
      },
      _renderMenu: function( ul, items ) {
        var that = this,
          currentCategory = "";
        $.each( items, function( index, item ) {
          var li;
          if ( item.category != currentCategory ) {
            ul.append( "<li class='ui-autocomplete-category'>" + item.category + "</li>" );
            currentCategory = item.category;
          }
          li = that._renderItemData( ul, item );
          if ( item.category ) {
            li.attr( "aria-label", item.category + " : " + item.label );
          }
        });
      }
    });
    var data = [
      { label: "anders", category: "" },
      { label: "andreas", category: "" },
      { label: "antal", category: "" },
      { label: "annhhx10", category: "Products" },
      { label: "annk K12", category: "Products" },
      { label: "annttop C13", category: "Products" },
      { label: "anders andersson", category: "People" },
      { label: "andreas andersson", category: "People" },
      { label: "andreas johnson", category: "People" }
    ];

    $( "#search" ).catcomplete({
      delay: 0,
      source: data    
    });
  } );
  </script>
</head>
<body>

<label for="search">Search: </label>
<input id="search">

</body>
</html>

Using the example data, there was a bit more work to be done to setup the data to work better for this. If you have control over the data format, you can prepare it before hand to work better.

Working example: https://jsfiddle.net/Twisty/uy5f2fta/

HTML

<label>Search:</label>
<select id="categories">
  <option value="none"></option>
</select>
<input id="search">

jQuery

var data = [{
  label: "anders",
  category: ""
}, {
  label: "andreas",
  category: ""
}, {
  label: "antal",
  category: ""
}, {
  label: "annhhx10",
  category: "Products"
}, {
  label: "annk K12",
  category: "Products"
}, {
  label: "annttop C13",
  category: "Products"
}, {
  label: "anders andersson",
  category: "People"
}, {
  label: "andreas andersson",
  category: "People"
}, {
  label: "andreas johnson",
  category: "People"
}];

$(function() {
  // Set Variables
  var cats = [],
    labels = {},
    sel = $("#categories"),
    search = $("#search");

  // Sift out specific Categories
  $.each(data, function(k, v) {
    if (v.category !== "") {
      cats.push(v.category);
      console.log("Found Cat: " + v.category);
    }
  });
  $.unique(cats);
  console.log("All Cats: ", cats);

  // Set Categories into Select element
  $.each(cats, function(k, v) {
    sel.append("<option value='" + v + "'>" + v + "</option>");
  });

  // Create Object of various data
  labels.none = [];
  $.each(cats, function(k, v) {
    labels[v] = [];
  });
  for (var i = 0; i < data.length; i++) {
    $.each(cats, function(k, v) {
      if (data[i].category == "") {
        labels.none.push(data[i].label);
      }
      if (data[i].category == v) {
        labels[v].push(data[i].label);
      }
    });
  }
  $.each(labels, function(k, v) {
    $.unique(labels[k]);
  });
  console.log("All Labels: ", labels);

  // Set Autocomplete with variable data based on category selection
  search.autocomplete({
    delay: 0,
    source: function(req, res) {
      var cat = sel.val();
      var data = labels[cat];
      var results = [];
      $.each(data, function(k, v) {
        if (v.indexOf(req.term) == 0) {
          results.push(v);
        }
      });
      res(results);
    }
  });
});

I first sifted out the categories that we knew would be in the data. This was then used to populate the Select element with a special "none" option. You could go back and adjust the none data to include all labels.

Next we parse all the labels and sort them into an object that has child arrays with the name of each category as the index. We will populate each array with the data for that category.

Finally, we use a function for the source so that we can pick which data set we want to read from. req.term is the data that was entered in the field, and we need to return an array of the matching data. The use of indexOf() is helpful here. This will return 0 when the term is at the beginning of the string. We then pass the resulting array to our res callback function.

So using your example, if category is "none" and we type "an", we get a resulting 'anders', 'andreas', and 'antal'. If we then type "and", the results drop to 'ansders' and 'andreas' as expected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM