使用 javascript 将带有数组的表单转换为逗号分隔的无重复查询字符串

Use javascript to convert form with arrays to comma separated query strings without duplicates

我想更改来自

的查询字符串

?firstArray[]=0001&firstArray[]=0002&secondArray[]=0003&secondArray[]=0004?firstArray=0001,0002&secondArray=0003,0004

我想我快到了,但我遇到的问题是,在我的 javascript 处理完表单后,两个数组的数组值相同。表格如下:

<form method="get" action="" class="productFilter">
    <input type="checkbox" name="firstArray[]" id="" value="0001">0001
    <input type="checkbox" name="firstArray[]" id="" value="0002">0002
    <input type="checkbox" name="secondArray[]" id="" value="0003">0003
    <input type="checkbox" name="secondArray[]" id="" value="0004">0004
    <input type="submit" name="submit" value="test">
</form>

这里是 javacript/jquery:

$('.productFilter').on('submit', function() {

var newVal = [];
var seen = {};

// Gather values into array.
$('input[name$="[]"]:checked').each(function() {
    newVal.push($(this).val());
});

// Make comma-separated list of values.
var commaSeparated = newVal.join(',');
console.log(commaSeparated);

// Remove duplicates so an 'array' is only listed once in the query string.
$('input[name$="[]"]:checked').each(function() {
    var name = $(this).attr('name');
    if (seen[name]) {
        $(this).remove();
    }
    else {
        seen[name] = true;
    }
    $(this).attr('name', name.slice(0, -2)).val(commaSeparated);
});

});

我明白为什么我的 'commaSeparated' var 包含 firstArray 和 secondArray 输入的值,所以当我选中所有框时,生成的查询字符串是:

?firstArray=0001,0002,0003,0004&secondArray=0001,0002,0003,0004 当我想要它的时候 ?firstArray=0001,0002&secondArray=0003,0004

虽然我不确定如何修复它。我需要将表单数组的值存储在单独的变量中,对吗?需要注意的是,我不知道在我的生产代码中会有多少个表单元素以及它们将被调用。

我的策略是

  • 首先,收集所有属于数组的输入字段,
  • 使用数组名称作为键,通过将它们推送到数组来收集散列中的值
  • 从 DOM
  • 中删除它们
  • 然后,在第二步中,通过其键遍历散列,
  • 正在输入新的表单字段,将数组名称设置为名称属性,将哈希元素值设置为值属性 = 包含用户检查的所有值的数组。

这样,服务器将为每个数组接收一个字段,其中包含该数组的检查值的逗号分隔列表。

  $('.productFilter').on('submit', function() {

       var arrayValues = {};

      // Gather values into a hash, the keys being the array names
      $('input[name$="[]"]').each(function(index,item) {
          if (item.checked) {
            var arrayName = item.name.replace(/\[\]$/,"");
            if (!arrayValues.hasOwnProperty(arrayName)) arrayValues[arrayName] = [];
            arrayValues[arrayName].push(item.value);
          }
          $(item).remove();
      });

      // Create new form fields with the collected values per array
      Object.keys(arrayValues).forEach( function(key) { 
        $("form").append( 
           $('<input type="hidden"></input>')
              .val(arrayValues[key])
              .attr("name",key) );
      });    

  });

我认为一个有趣的方法可能是使用对象属性来帮助独特地整理您的参数和值。此代码对一组已检查的输入使用 reduce,但如果需要,您可以使用更传统的循环来完成。

$('.productFilter').on('submit', function() {
  // -----------------------
  // convert our select results to an array
  // -----------------------
  var checkedInputs = $.makeArray($('input[name$="[]"]:checked'));
  // -----------------------

  // -----------------------
  // convert the array of inputs into an object with nested properties
  // -----------------------
  var checkedInputsObj = checkedInputs.reduce(function(obj, item){
    obj[item.name] = (obj[item.name] || {});
    obj[item.name][item.value] = true;
    return obj
  }, {});
  // -----------------------
  
  // -----------------------
  // Build our querystring
  // -----------------------
  var qs = (function(obj){
    var _qs = "?";

    for (var param in obj){
      _qs += param.slice(0, -2) + "=";
      for (var val in obj[param]){ _qs += val + ","; }
      _qs = _qs.slice(0, -1) + "&";
    }

    return _qs.slice(0, -1);

  })(checkedInputsObj);
  // -----------------------

  console.log(qs)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="get" action="" class="productFilter">
  <input type="checkbox" name="firstArray[]" id="" value="0001">0001
  <input type="checkbox" name="firstArray[]" id="" value="0002">0002
  <input type="checkbox" name="secondArray[]" id="" value="0003">0003
  <input type="checkbox" name="secondArray[]" id="" value="0004">0004
  <input type="submit" name="submit" value="test">
</form>

   var checked_first = []
    $("input[name='firstArray[]']:checked").each(function ()
    {
        checked_first.push($(this).val());
    });

var checked_second = []
    $("input[name='secondArray[]']:checked").each(function ()
    {
        checked_second.push($(this).val());
    });

获取每个数组selected的值

使用纯 JS(没有 jQuery)执行此操作的一种方法可能是;

var    f = document.querySelector("form"),
    cba1 = Array.from(f.querySelectorAll("input[name='firstArray[]']")),
    cba2 = Array.from(f.querySelectorAll("input[name='secondArray[]']"));
f.onsubmit = function(e){
var fStr = cba1.reduce((p,c) => c.checked ? p.concat(c.value) : p,[]).join(","),
    sStr = cba2.reduce((p,c) => c.checked ? p.concat(c.value) : p,[]).join(","),
    qStr = !!fStr || !!sStr ? "?" : "";
!!fStr && (qStr+= "firstArray=" + fStr);
!!fStr && !!sStr && (qStr+="&");
!!sStr && (qStr+= "secondArray=" + sStr);
  console.log(qStr);
}
<form method="get" action="" class="productFilter">
    <input type="checkbox" name="firstArray[]" id="" value="0001">0001
    <input type="checkbox" name="firstArray[]" id="" value="0002">0002
    <input type="checkbox" name="secondArray[]" id="" value="0003">0003
    <input type="checkbox" name="secondArray[]" id="" value="0004">0004
    <input type="submit" name="submit" value="test">
</form>

您可以根据 firstArraysecondArray 选择尽可能多的复选框。如果您希望在 Safari 和 IE 上工作,我建议您用常规函数替换箭头(减少回调)。