2017-06-16 238 views
0

我已成功修改this blog post的片段。如何匹配jQuery UI自动完成中两个对象值的开始?

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

$.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中很多:/。

回答

0

我想我想出了更酷,更相关的是我真正需要做的事情 - 它在开始value字符串product_desc字符串的任何地方匹配。

forked jsFiddle受到高度评论,所以那些只想对两个值进行查找(匹配在字符串的开始处),可以注释掉一些行并实现该效果。

我还实施了一系列的其它特征:

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

这些也受到很多评论,因此如果需要可以删除或修改它们。

我仍然会欣赏的确认,这是一个相对干净的解决方案,不与两个many的div(自动完成,似乎大量未使用的div添加到DOM?)

弄乱DOM 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); 
} 

*/