Select2:自定义匹配器使用选项的值属性对外部数据集

时间:2016-08-18 07:41:25

标签: jquery-select2 select2 jquery-select2-4

我有一组产品在select中显示为产品ID =>产品名称。例如:

<option value="44">Cambium ePMP Force 180</option>

问题是,除了按产品名称搜索外,我还想扫描条形码以使产品代码与产品相匹配。我有一个通过JSON检索的映射,其结构为产品ID =&gt;产品代码

mappings = {
    44: 'C050900C171A'
     ...
};

如何编写也搜索映射对象的自定义匹配器?

(如果automatically selects the matching option,则为奖励积分。)

2 个答案:

答案 0 :(得分:0)

我在这里写了一个基于默认匹配器的自定义匹配器:https://github.com/select2/select2/blob/c2326209c21862ed606e98213485a679e8ca0caf/src/js/select2/defaults.js#L272-L315

首先,通过远程数据源中的JSON获取映射:

$.getJSON('api/stock-code-mappings.json.php', function(mappings) {

这会将mappings设置为包含:

mappings = {
  44: 'C050900C171A'
  ...
};

可以通过以下方式访问默认匹配器:

$.fn.select2.defaults.defaults.matcher

在自定义匹配器中,遍历映射以检查该术语是否与产品代码映射匹配,如果匹配,请检查当前元素的id是否与产品ID匹配:

$.each(mappings, function(id, code) {
  if (code.toUpperCase() == term && id == data.id) foundStockCode = true;
});

全部放在一起:

$(function() {

  // Barcode Mappings:
  // Product ID => Product Code
  var mappings = {
    44: 'C050900C171A',
    100: 'AJSLCL-100XCL',
    200: 'L92FOO-1100M-200'
  };

  // Custom matcher
  function mappingsMatcher(params, data, firstLevel = true) {
    // Check the default matcher on the first level of recursion only.
    if (firstLevel) {
      var result = $.fn.select2.defaults.defaults.matcher(params, data);
      if (result) return result;
    }

    // This is the same recursion pattern of the default matcher.
    if (data.children && data.children.length > 0) {
      var match = $.extend(true, {}, data);
      for (var c = data.children.length - 1; c >= 0; c--) {
        var child = data.children[c];
        var matches = stockTypeMatcher(params, child, false);
        if (matches == null) {
          match.children.splice(c, 1);
        }
      }

      // If any children matched, return the new object
      if (match.children.length > 0) {
        return match;
      }

      // If there were no matching children, check just the plain object
      return stockTypeMatcher(params, match, false);
    }

    // Check against mappings
    var term = params.term.toUpperCase();
    var foundStockCode = false;
    $.each(mappings, function(id, code) {
      if (code.toUpperCase() == term && id == data.id) foundStockCode = true;
    });
    if (foundStockCode) return data;
    return null;
  }

  $('select').select2({
    placeholder: 'Product',
    allowClear: true,
    matcher: mappingsMatcher
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.full.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet"/>

<p>Search for the following mappings by copying a code into the search box:</p>
<ul>
  <li>C050900C171A</li>
  <li>AJSLCL-100XCL</li>
  <li>L92FOO-1100M-200</li>
</ul>

<select style="width: 20em">
  <option value=""></option>
  <option value="44">Cambium ePMP Force 180</option>
  <option value="100">Product One</option>
  <option value="200">Product Two</option>
</select>

答案 1 :(得分:0)

这是一种替代方案,如果通过条形码映射找到产品代码,则会立即更改值并关闭搜索框。

选择匹配条形码并关闭该框的行是:

$(data.element).closest('select')
  .val(data.id)
  .trigger('change')
  .select2('close');

$(function() {

  // Barcode Mappings:
  // Product ID => Product Code
  var mappings = {
    44: 'C050900C171A',
    100: 'AJSLCL-100XCL',
    200: 'L92FOO-1100M-200'
  };

  // Custom matcher
  function mappingsMatcher(params, data, firstLevel = true) {
    // Check the default matcher on the first level of recursion only.
    if (firstLevel) {
      var result = $.fn.select2.defaults.defaults.matcher(params, data);
      if (result) return result;
    }

    // This is the same recursion pattern of the default matcher.
    if (data.children && data.children.length > 0) {
      var match = $.extend(true, {}, data);
      for (var c = data.children.length - 1; c >= 0; c--) {
        var child = data.children[c];
        var matches = stockTypeMatcher(params, child, false);
        if (matches == null) {
          match.children.splice(c, 1);
        }
      }

      // If any children matched, return the new object
      if (match.children.length > 0) {
        return match;
      }

      // If there were no matching children, check just the plain object
      return stockTypeMatcher(params, match, false);
    }

    // Check against mappings
    var term = params.term.toUpperCase();
    var foundStockCode = false;
    $.each(mappings, function(id, code) {
      if (code.toUpperCase() == term && id == data.id) foundStockCode = true;
    });
    if (foundStockCode) {
      $(data.element).closest('select')
        .val(data.id)
        .trigger('change')
        .select2('close');
    }
    return null;
  }

  $('select').select2({
    placeholder: 'Product',
    allowClear: true,
    matcher: mappingsMatcher
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.full.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet"/>

<p>Search for the following mappings by copying a code into the search box:</p>
<ul>
  <li>C050900C171A</li>
  <li>AJSLCL-100XCL</li>
  <li>L92FOO-1100M-200</li>
</ul>

<select style="width: 20em">
  <option value=""></option>
  <option value="44">Cambium ePMP Force 180</option>
  <option value="100">Product One</option>
  <option value="200">Product Two</option>
</select>