【问题标题】:How to match beginning of two object values in jQuery UI autocomplete?如何在 jQuery UI 自动完成中匹配两个对象值的开头?
【发布时间】:2017-06-20 19:42:40
【问题描述】:

我已成功修改来自this blog post 的sn-p。

为了只匹配一个对象值的开头:

$.ui.autocomplete.filter = function(array, term) {
var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(term), "i");
return $.grep(array, function(value) {
return matcher.test(value.value);
});
};

我希望能够匹配两个对象值 - 对象 valuedescription,例如:搜索 "01" 应该返回对象的 1 和 3:

var array_of_objects = [
{value: "01000", product_desc: "a unique orange from spain"},
{value: "02000", product_desc: "a unique pear from spain 01"},
{value: "02001", product_desc: "01000 desc starts with number"}];

jsFiddle

编辑:

This answer 查找两个值,所以我可以将它与我的 jsFiddle 解决方案合并,但我只需要它来匹配开头。

编辑 2:

我有updated my original fiddle,它似乎正在做需要做的事情,但我不确定这是否是最有效的方法,或者它是否会大量混淆 dom:/。

【问题讨论】:

    标签: jquery-ui jquery-ui-autocomplete


    【解决方案1】:

    我想我想出了一些更酷的东西,并且与我实际需要做的事情更相关 - 它匹配 value 字符串的 开头anywhere product_desc 字符串。

    forked jsFiddle 被高度注释,因此那些只想查找两个值(匹配位于任一字符串的开头)的人可以注释掉一些行并实现该效果。

    我还实现了许多其他功能:

    • 匹配突出显示
    • 显示匹配数
    • 可滚动的结果区域
    • 用一个对象的多个值填充页面元素
    • 模板化结果
    • 一页上有多个实例

    这些也有大量注释,因此可以根据需要删除或修改它们。

    我仍然希望确认这是一个相对干净的解决方案,不会用两个很多 div 弄乱 dom(自动完成似乎会向 dom 添加很多未使用的 div?)

    JS

    // BEGIN show message prompt requiring 2 characters
    $(".my_lookup").on("keyup", function() {
      var product_container = $(this).parent();
      var $matches_count = product_container.find(".matches_count");
      var $matches_text = product_container.find(".matches_text");
      var input_length = $(this).val().length;
      if (input_length < 2 && input_length !== 0) {
        $(this).siblings(".matches_prompt").text("search requires min 2 characters").show();
        $matches_count.text("").hide();
        $matches_text.text("").hide();
      } else if (input_length === 0 || input_length >= 2) {
        $(this).siblings(".matches_prompt").hide();
      }
    });
    // END show message prompt requiring 2 characters
    
    // BEGIN look up on two values solution
    // see:  https://stackoverflow.com/a/15849692
    function lightwell(request, response) {
      // request.term is what you typed
      // response is the data to suggest to the user
      // added the 'match_type' argument to hasMatch() to:
      // - check for match at beginning of object's 'value' string
      // - check for match anywhere in object's 'product_desc' string
      // BEGIN hasMatch() function
      function hasMatch(s, match_type) {
        // to match beginning of string only,
        // use:  === 0
        // see:  https://stackoverflow.com/a/12482182
        // originally was !==-1 
        // to match anywhere in the string,
        // use !==-1
        // when match_type === "start",
        // below returns true if request.term is at the 0 index
        // of the object.value or object.product_desc string
        // when match_type === "anywhere",
        // returns true if at any index other than no index
        // original usage (anywhere) below
        // (remove 'match_type' argument and references to it):
        // return s.toLowerCase().indexOf(request.term.toLowerCase()) !== -1;
        // added conditional handling
        // BEGIN if match_type === "start"
        if (match_type === "start") {
          // check if typed in term is at the 0 index of object's 'value' string
          var is_at_start_of_string = s.toLowerCase().indexOf(request.term.toLowerCase()) === 0;
          if (is_at_start_of_string === true) {
            console.log("typed term is at start of value string");
          }
          return is_at_start_of_string;
        }
        // END if match_type === "start"
    
        // BEGIN if match_type === "anywhere"
        else if (match_type === "anywhere") {
          // check if typed in term is at any index of object's 'product_desc' string
          var exists_in_string = s.toLowerCase().indexOf(request.term.toLowerCase()) !== -1;
          if (exists_in_string === true) {
            console.log("typed term exists in product_desc string");
          }
          return exists_in_string;
        }
        // END if match_type === "anywhere"
      }
      // END hasMatch() function
    
      // declare variables, i and obj are undefined, matches is []
      var i, obj, matches = [];
    
      // BEGIN get the index of the input being used
      // see: https://stackoverflow.com/a/11278006/1063287
      var current_input_index = $(document.activeElement).parent().index() - 1;
      // END get the index of the input being used
    
      // BEGIN get refererences to dproduct relative dom elements
      var $product_container = $(".product_container").eq(current_input_index);
    
      var $matches_count = $product_container.find(".matches_count");
      var $matches_text = $product_container.find(".matches_text");
      // END get refererences to dproduct relative dom elements
    
      // BEGIN if the typed in term is nothing
      // pass an empty array to response()
      if (request.term === "") {
        console.log("this thing is happening");
        // hide the matches count display
        $matches_count.text("").hide();
        $matches_text.text("").hide();
        response([]);
        return;
      }
      // END if the typed in term is nothing
    
      // get length of array_of_objects
      var array_of_objects_length = array_of_objects.length;
    
      // for each object in the array, call the hasMatch() function
      // and pass it the object's 'value' and 'product_desc' strings
      for (i = 0; i < array_of_objects_length; i++) {
        obj = array_of_objects[i];
        // if either of the below conditions return true,
        // push the object to the matches array
        if (hasMatch(obj.value, "start") || hasMatch(obj.product_desc, "anywhere")) {
          matches.push(obj);
        }
      }
      // pass the matches array to response()
      // get the count of matches for display
      var matches_count = matches.length;
      console.log("matches length is: " + matches_count)
      if (matches_count === 0 || matches_count > 1) {
        var matches_text = " matches"
      } else if (matches_count === 1) {
        var matches_text = " match"
      }
      // display the count of matches
      $matches_count.text(matches_count).show();
      $matches_text.text(matches_text).show();
      response(matches);
    }
    // END look up on two values solution
    
    
    // BEGIN autocomplete
    $(".my_lookup").autocomplete({
      // only show 5 results with scrollbar
      // from:  http://anseki.github.io/jquery-ui-autocomplete-scroll
      maxShowItems: 5,
      source: lightwell,
      minLength: 2,
      // called on input blur if value has changed
      change: function(event, ui) {
        var product_container = $(this).closest(".product_container");
        var $matches_count = product_container.find(".matches_count");
        var $matches_text = product_container.find(".matches_text");
        $matches_count.text("").hide();
        $matches_text.text("").hide();
      },
      // called when selecting an option
      select: function(event, ui) {
    
        // get references to product relative selectors
        var product_container = $(this).closest(".product_container");
        var product_desc = product_container.find(".product_desc");
        var product_type = product_container.find(".product_type");
        var product_attr_01 = product_container.find(".product_attr_01");
        var product_attr_02 = product_container.find(".product_attr_02");
    
        var $matches_count = product_container.find(".matches_count");
        var $matches_text = product_container.find(".matches_text");
        $matches_count.text("").hide();
        $matches_text.text("").hide();
    
        // add object's values to relative product container inputs
        product_desc.val(ui.item.product_desc);
        product_type.val(ui.item.product_type);
        product_attr_01.val(ui.item.product_attr_01);
        product_attr_02.val(ui.item.product_attr_02);
    
        // BEGIN animate realtive inputs when selecting an option
        product_desc.animate({
          "backgroundColor": "#d0e4ff"
        }, {
          "queue": false,
          "duration": 800
        });
        product_desc.animate({
          "borderColor": "#7190dd"
        }, {
          "queue": false,
          "duration": 800
        });
        product_type.animate({
          "backgroundColor": "#d0e4ff"
        }, {
          "queue": false,
          "duration": 800
        });
        product_type.animate({
          "borderColor": "#7190dd"
        }, {
          "queue": false,
          "duration": 800
        });
        product_attr_01.animate({
          "backgroundColor": "#d0e4ff"
        }, {
          "queue": false,
          "duration": 800
        });
        product_attr_01.animate({
          "borderColor": "#7190dd"
        }, {
          "queue": false,
          "duration": 800
        });
        product_attr_02.animate({
          "backgroundColor": "#d0e4ff"
        }, {
          "queue": false,
          "duration": 800
        });
        product_attr_02.animate({
          "borderColor": "#7190dd"
        }, {
          "queue": false,
          "duration": 800
        });
        setTimeout(function() {
          product_desc.animate({
            "backgroundColor": "#ffff"
          }, {
            "queue": false,
            "duration": 800
          });
          product_desc.animate({
            "borderColor": "#cacaca"
          }, {
            "queue": false,
            "duration": 800
          });
          product_type.animate({
            "backgroundColor": "#ffff"
          }, {
            "queue": false,
            "duration": 800
          });
          product_type.animate({
            "borderColor": "#cacaca"
          }, {
            "queue": false,
            "duration": 800
          });
          product_attr_01.animate({
            "backgroundColor": "#ffff"
          }, {
            "queue": false,
            "duration": 800
          });
          product_attr_01.animate({
            "borderColor": "#cacaca"
          }, {
            "queue": false,
            "duration": 800
          });
          product_attr_02.animate({
            "backgroundColor": "#ffff"
          }, {
            "queue": false,
            "duration": 800
          });
          product_attr_02.animate({
            "borderColor": "#cacaca"
          }, {
            "queue": false,
            "duration": 800
          });
        }, 2000);
        // END animate realtive inputs when selecting an option
      },
      // show fontawesome loading animation when search starts
      search: function(event, ui) {
        console.log("search started");
        $(this).closest(".product_container").find(".fa-circle-o-notch").css("visibility", "visible");
      },
      // hide fontawesome loading animation when search finishes
      response: function(event, ui) {
        console.log("search finished");
        $(this).closest(".product_container").find(".fa-circle-o-notch").css("visibility", "hidden");
      },
    
      // BEGIN add styles to results
      // from:  https://gist.github.com/DBasic/9545690
      create: function() {
          $(this).data('ui-autocomplete')._renderItem = function(ul, item) {
    
            // create a new 'value' string for match highlighting
            // see: https://stackoverflow.com/a/9889056/1063287
            var newValueText = String(item.value).replace(
              // changed "gi" to i so that the match
              // on instance of search term is limited
              // to the first match, see:  
              // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
              new RegExp(this.term, "i"),
              "<span class='ui-state-highlight'>$&</span>");
    
            // create a new 'description' string for match highlighting
            var newDescText = String(item.product_desc.toUpperCase()).replace(
              new RegExp(this.term, "gi"),
              "<span class='ui-state-highlight'>$&</span>");
    
            return $("<li></li>")
              .data("ui-autocomplete-item", item)
              // newValueText below used to be: item.value.toUpperCase()
              // newDescText below used to be: item.product_desc.toUpperCase()
              .append("<div class=\"my_result\"><span class=\"helper\"></span><img class=\"result_img\" src=\"https://placeimg.com/30/30/nature\">" + newValueText + " - " + newDescText + "</div>")
              .appendTo(ul);
          }
        }
        // END add styles to results
    
    });
    // END autocomplete
    
    
    // new data set generated from https://github.com/Marak/faker.js
    
    var array_of_objects = [{
      "value": "020101",
      "product_desc": "Handmade Frozen Pants",
      "product_type": "Automotive",
      "product_attr_01": "106.00",
      "product_attr_02": "171.00"
    }, {
      "value": "010101",
      "product_desc": "Practical Fresh Hat",
      "product_type": "Movies",
      "product_attr_01": "589.00",
      "product_attr_02": "777.00"
    }, {
      "value": "7099",
      "product_desc": "Awesome Concrete Sausages",
      "product_type": "Grocery",
      "product_attr_01": "249.00",
      "product_attr_02": "167.00"
    }, {
      "value": "5740",
      "product_desc": "Sleek Plastic Pizza",
      "product_type": "Home",
      "product_attr_01": "924.00",
      "product_attr_02": "379.00"
    }, {
      "value": "7627",
      "product_desc": "Intelligent Plastic Mouse",
      "product_type": "Games",
      "product_attr_01": "71.00",
      "product_attr_02": "412.00"
    }, {
      "value": "6606",
      "product_desc": "Handmade Steel Pizza",
      "product_type": "Music",
      "product_attr_01": "71.00",
      "product_attr_02": "791.00"
    }, {
      "value": "0973",
      "product_desc": "Intelligent Granite Tuna",
      "product_type": "Industrial",
      "product_attr_01": "25.00",
      "product_attr_02": "441.00"
    }, {
      "value": "5453",
      "product_desc": "Generic Steel Sausages",
      "product_type": "Sports",
      "product_attr_01": "887.00",
      "product_attr_02": "786.00"
    }, {
      "value": "3871",
      "product_desc": "Refined Wooden Keyboard",
      "product_type": "Sports",
      "product_attr_01": "897.00",
      "product_attr_02": "402.00"
    }, {
      "value": "9646",
      "product_desc": "Incredible Soft Chicken",
      "product_type": "Kids",
      "product_attr_01": "849.00",
      "product_attr_02": "438.00"
    }, {
      "value": "2948",
      "product_desc": "Licensed Plastic Gloves",
      "product_type": "Baby",
      "product_attr_01": "608.00",
      "product_attr_02": "748.00"
    }, {
      "value": "1561",
      "product_desc": "Sleek Steel Towels",
      "product_type": "Music",
      "product_attr_01": "315.00",
      "product_attr_02": "332.00"
    }, {
      "value": "5012",
      "product_desc": "Licensed Rubber Computer",
      "product_type": "Electronics",
      "product_attr_01": "886.00",
      "product_attr_02": "738.00"
    }, {
      "value": "4827",
      "product_desc": "Unbranded Wooden Shoes",
      "product_type": "Shoes",
      "product_attr_01": "390.00",
      "product_attr_02": "753.00"
    }, {
      "value": "0056",
      "product_desc": "Handcrafted Fresh Sausages",
      "product_type": "Shoes",
      "product_attr_01": "26.00",
      "product_attr_02": "257.00"
    }, {
      "value": "0628",
      "product_desc": "Fantastic Steel Tuna",
      "product_type": "Tools",
      "product_attr_01": "881.00",
      "product_attr_02": "127.00"
    }, {
      "value": "8498",
      "product_desc": "Gorgeous Soft Fish",
      "product_type": "Toys",
      "product_attr_01": "105.00",
      "product_attr_02": "604.00"
    }, {
      "value": "9265",
      "product_desc": "Gorgeous Wooden Cheese",
      "product_type": "Clothing",
      "product_attr_01": "257.00",
      "product_attr_02": "438.00"
    }, {
      "value": "0666",
      "product_desc": "Small Soft Keyboard",
      "product_type": "Baby",
      "product_attr_01": "960.00",
      "product_attr_02": "852.00"
    }, {
      "value": "4628",
      "product_desc": "Intelligent Plastic Car",
      "product_type": "Music",
      "product_attr_01": "598.00",
      "product_attr_02": "339.00"
    }, {
      "value": "3341",
      "product_desc": "Intelligent Metal Mouse",
      "product_type": "Garden",
      "product_attr_01": "92.00",
      "product_attr_02": "371.00"
    }, {
      "value": "6547",
      "product_desc": "Awesome Concrete Shirt",
      "product_type": "Health",
      "product_attr_01": "344.00",
      "product_attr_02": "145.00"
    }, {
      "value": "0803",
      "product_desc": "Unbranded Metal Chair",
      "product_type": "Kids",
      "product_attr_01": "343.00",
      "product_attr_02": "700.00"
    }, {
      "value": "9769",
      "product_desc": "Awesome Granite Bike",
      "product_type": "Home",
      "product_attr_01": "545.00",
      "product_attr_02": "391.00"
    }, {
      "value": "3087",
      "product_desc": "Refined Wooden Tuna",
      "product_type": "Industrial",
      "product_attr_01": "58.00",
      "product_attr_02": "68.00"
    }, {
      "value": "3202",
      "product_desc": "Small Concrete Gloves",
      "product_type": "Kids",
      "product_attr_01": "846.00",
      "product_attr_02": "60.00"
    }, {
      "value": "9638",
      "product_desc": "Generic Rubber Ball",
      "product_type": "Garden",
      "product_attr_01": "160.00",
      "product_attr_02": "123.00"
    }, {
      "value": "4762",
      "product_desc": "Tasty Frozen Computer",
      "product_type": "Health",
      "product_attr_01": "698.00",
      "product_attr_02": "832.00"
    }, {
      "value": "6606",
      "product_desc": "Rustic Frozen Shirt",
      "product_type": "Automotive",
      "product_attr_01": "867.00",
      "product_attr_02": "92.00"
    }, {
      "value": "6853",
      "product_desc": "Ergonomic Steel Pants",
      "product_type": "Sports",
      "product_attr_01": "712.00",
      "product_attr_02": "378.00"
    }, {
      "value": "5418",
      "product_desc": "Awesome Cotton Cheese",
      "product_type": "Toys",
      "product_attr_01": "483.00",
      "product_attr_02": "918.00"
    }, {
      "value": "0230",
      "product_desc": "Licensed Cotton Towels",
      "product_type": "Clothing",
      "product_attr_01": "540.00",
      "product_attr_02": "415.00"
    }, {
      "value": "3975",
      "product_desc": "Sleek Granite Pants",
      "product_type": "Outdoors",
      "product_attr_01": "823.00",
      "product_attr_02": "331.00"
    }, {
      "value": "7581",
      "product_desc": "Ergonomic Concrete Bacon",
      "product_type": "Automotive",
      "product_attr_01": "640.00",
      "product_attr_02": "718.00"
    }, {
      "value": "8550",
      "product_desc": "Practical Granite Table",
      "product_type": "Shoes",
      "product_attr_01": "94.00",
      "product_attr_02": "487.00"
    }, {
      "value": "3358",
      "product_desc": "Fantastic Plastic Computer",
      "product_type": "Clothing",
      "product_attr_01": "448.00",
      "product_attr_02": "440.00"
    }, {
      "value": "4586",
      "product_desc": "Ergonomic Steel Table",
      "product_type": "Games",
      "product_attr_01": "218.00",
      "product_attr_02": "806.00"
    }, {
      "value": "6331",
      "product_desc": "Intelligent Wooden Gloves",
      "product_type": "Shoes",
      "product_attr_01": "236.00",
      "product_attr_02": "546.00"
    }, {
      "value": "2871",
      "product_desc": "Handcrafted Wooden Salad",
      "product_type": "Beauty",
      "product_attr_01": "546.00",
      "product_attr_02": "259.00"
    }, {
      "value": "1648",
      "product_desc": "Tasty Soft Pants",
      "product_type": "Kids",
      "product_attr_01": "641.00",
      "product_attr_02": "251.00"
    }, {
      "value": "8096",
      "product_desc": "Practical Steel Chair",
      "product_type": "Toys",
      "product_attr_01": "609.00",
      "product_attr_02": "374.00"
    }, {
      "value": "5810",
      "product_desc": "Refined Steel Chicken",
      "product_type": "Kids",
      "product_attr_01": "529.00",
      "product_attr_02": "705.00"
    }, {
      "value": "7057",
      "product_desc": "Tasty Metal Mouse",
      "product_type": "Garden",
      "product_attr_01": "911.00",
      "product_attr_02": "935.00"
    }, {
      "value": "2344",
      "product_desc": "Intelligent Cotton Pizza",
      "product_type": "Sports",
      "product_attr_01": "705.00",
      "product_attr_02": "220.00"
    }, {
      "value": "9188",
      "product_desc": "Awesome Wooden Ball",
      "product_type": "Movies",
      "product_attr_01": "896.00",
      "product_attr_02": "850.00"
    }, {
      "value": "1474",
      "product_desc": "Sleek Plastic Salad",
      "product_type": "Tools",
      "product_attr_01": "15.00",
      "product_attr_02": "668.00"
    }, {
      "value": "6513",
      "product_desc": "Small Soft Chips",
      "product_type": "Health",
      "product_attr_01": "433.00",
      "product_attr_02": "74.00"
    }, {
      "value": "4036",
      "product_desc": "Unbranded Wooden Soap",
      "product_type": "Grocery",
      "product_attr_01": "826.00",
      "product_attr_02": "920.00"
    }, {
      "value": "9226",
      "product_desc": "Licensed Fresh Cheese",
      "product_type": "Industrial",
      "product_attr_01": "144.00",
      "product_attr_02": "102.00"
    }, {
      "value": "1944",
      "product_desc": "Fantastic Rubber Shoes",
      "product_type": "Electronics",
      "product_attr_01": "820.00",
      "product_attr_02": "808.00"
    }, {
      "value": "9379",
      "product_desc": "Small Wooden Tuna",
      "product_type": "Baby",
      "product_attr_01": "199.00",
      "product_attr_02": "160.00"
    }, {
      "value": "7888",
      "product_desc": "Handcrafted Frozen Sausages",
      "product_type": "Electronics",
      "product_attr_01": "70.00",
      "product_attr_02": "419.00"
    }, {
      "value": "1941",
      "product_desc": "Fantastic Granite Car",
      "product_type": "Grocery",
      "product_attr_01": "821.00",
      "product_attr_02": "853.00"
    }, {
      "value": "8322",
      "product_desc": "Licensed Wooden Fish",
      "product_type": "Games",
      "product_attr_01": "998.00",
      "product_attr_02": "703.00"
    }, {
      "value": "5586",
      "product_desc": "Fantastic Cotton Salad",
      "product_type": "Games",
      "product_attr_01": "887.00",
      "product_attr_02": "841.00"
    }];
    
    /* code to generate the above data set,
    from: https://github.com/Marak/faker.js
    
    var array_of_objects = [];
    
    for (i = 0; i < 5; i++) {
        var obj = {}; 
        obj['value'] = faker.fake("{{finance.mask}}");
        obj['product_desc'] = faker.fake("{{commerce.productName}}");
        obj['product_type'] = faker.fake("{{commerce.department}}");
        obj['product_attr_01'] = faker.fake("{{commerce.price}}");
        obj['product_attr_02'] = faker.fake("{{commerce.price}}");
        array_of_objects.push(obj);
    }
    
    */
    

    【讨论】:

      猜你喜欢
      • 2019-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-22
      • 1970-01-01
      • 1970-01-01
      • 2012-05-08
      相关资源
      最近更新 更多