提交前如何连接表单数组输入?

时间:2018-10-14 08:02:52

标签: javascript jquery forms

示例代码:

<form method="get">
<input type="checkbox" name="anythingOne[]" value='one'> <!-- checked -->
<input type="checkbox" name="anythingOne[]" value='two'>
<input type="checkbox" name="anythingOne[]" value='three'> <!-- checked -->

<input type="checkbox" name="otherThingTwo[]" value='Forty'>
<input type="checkbox" name="otherThingTwo[]" value='Fifty'> <!-- checked -->
</form>

提交表单时,URL应如下所示:

http://some-website.tld/action?anythingOne=one,three&otherThingTwo=Fifty

我现在正在观察的是

http://some-website.tld/action?anythingOne=one&anythingOne=three&otherThingTwo=Fifty

在这种情况下serialize()serializeArray()无法正常工作。有什么想法吗?

5 个答案:

答案 0 :(得分:0)

您可以收集所有选中的拳击手和join字符串的不同部分。这可能不是最整洁或有效的解决方案,但它可以工作。我使用了一个按钮来触发串联。在代码中查看我的评论。

$(document).ready(function(){
	$("button").click(function(){
		/* concatenate anythingOne form*/
		//collect anythingOne input
		var joined_serialized = []
		var anythingOne = [];
		$.each($("input[name='anythingOne[]']:checked"), function(){            
			anythingOne.push($(this).val());
		});
		//join otherThingTwo input
		var anythingOne_serialized = "";
		if(anythingOne.length > 0){ //only collect if checked
			anythingOne_serialized =  "anythingOne=" + anythingOne.join(",");
			joined_serialized.push(anythingOne_serialized)
		}
		
		/* concatenate otherThingTwo form*/
		//collect otherThingTwo input
		var otherThingTwo = []
		$.each($("input[name='otherThingTwo[]']:checked"), function(){            
			otherThingTwo.push($(this).val());
		});
		//join otherThingTwo input
		var otherThingTwo_serialized = "";
		if(otherThingTwo.length > 0){ //only collect if checked
			otherThingTwo_serialized =  "otherThingTwo=" + otherThingTwo.join(",");
			joined_serialized.push(otherThingTwo_serialized)
		}
		
		/*join different form names*/
		var joined_serialized = joined_serialized.join("&")
		
		if(joined_serialized.length == 1){ //remove last & if only one form is checked
			joined_serialized = joined_serialized.slice(0, -1)
		}
		
		/*concatenated forms with website*/
		var result = "http://some-website.tld/action?"+joined_serialized
		console.log(result) //E.g. when Two, Three and Forty are checked: http://some-website.tld/action?anythingOne=two,three&otherThingTwo=Forty 
	})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="get">
    <input type="checkbox" name="anythingOne[]" value='one'> <!-- checked -->
    <input type="checkbox" name="anythingOne[]" value='two'>
    <input type="checkbox" name="anythingOne[]" value='three'> <!-- checked -->
    <input type="checkbox" name="otherThingTwo[]" value='Forty'>
    <input type="checkbox" name="otherThingTwo[]" value='Fifty'> <!-- checked -->      
</form>
<button>submit<button/>

答案 1 :(得分:0)

您可以获取.serializeArray的结果并将其转换为所需的格式:

$(function() {
  $('form').on('submit', function(e) {
    e.preventDefault();
    var data = $(this).serializeArray();
    
    var dataByKey = data
      .reduce((result, entry) => {
        var name = entry.name.replace(/\[\]$/, '');
        (result[name] || (result[name] = [])).push(entry.value);
        return result;
      }, {});
      
    Object.keys(dataByKey)
      .forEach((key, _) => dataByKey[key] = dataByKey[key].join(','));
    
    console.log(dataByKey);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="get">
  <fieldset>
    <input type="checkbox" name="anythingOne[]" value='one'>1
    <input type="checkbox" name="anythingOne[]" value='two'>2
    <input type="checkbox" name="anythingOne[]" value='three'>3
  </fieldset>

  <fieldset>
    <input type="checkbox" name="otherThingTwo[]" value='Forty'>40
    <input type="checkbox" name="otherThingTwo[]" value='Fifty'>50
  </fieldset>
  
  <input type="submit" />
</form>

答案 2 :(得分:0)

如果需要,您也可以使用不带jQuery的纯JavaScript来获取所有选中的复选框的值http://jsfiddle.net/jx76dpkh/1/

<form id="myForm" method="get">
         <input type="checkbox" name="anythingOne[]" value='one'>1
         <input type="checkbox" name="anythingOne[]" value='two'>2
         <input type="checkbox" name="anythingOne[]" value='three'>3
         <input type="checkbox" name="otherThingTwo[]" value='Forty'>40
         <input type="checkbox" name="otherThingTwo[]" value='Fifty'>50
         <input type="submit" />
</form>

JS:

const myForm = document.getElementById('myForm');
myForm.addEventListener('submit', (e) => {
     e.preventDefault();
     let checkboxes = Array.from(myForm.querySelectorAll('input[type="checkbox"]:checked');// build the array like element list to an array
     let anythingOne = checkboxes.filter( box => box.name === 'anythingOne[]').map(item => item.value);
     let otherThingTwo = checkboxes.filter( box => box.name === 'otherThingTwo[]').map(item => item.value);
});

答案 3 :(得分:0)

您可以使用serializeArray()方法获取查询字符串参数。然后使用reduce()按名称对参数值进行分组,然后使用map()获取键值对数组。然后可以使用join()方法来连接由&分隔的对。例如,以下代码段使用action形式的实际值(默认为当前URL)和选中的复选框的值来创建目标URL:

$('form').submit(function() {
  var queryString = $(this).serializeArray()
    .reduce(function(transformed, current) {
      var existing = transformed.find(function(param) {
        return param.name === current.name;
      });
      if (existing)
        existing.value += (',' + current.value);
      else
        transformed.push(current);
      return transformed;
    }, [])
    .map(function(param) {
      return param.name + '=' + param.value;
    })
    .join('&');
  var action = $(this).prop('action');
  var delimiter = (~action.indexOf('?')) ? '&' : '?';
  $(this).prop('action', action + delimiter + queryString);
  
  // Only for display result. Remove on real page.
  var url = $(this).prop('action');
  console.log(url);
  return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="GET">
  <input type="checkbox" name="anythingOne" value='one'>
  <input type="checkbox" name="anythingOne" value='two'>
  <input type="checkbox" name="anythingOne" value='three'>

  <input type="checkbox" name="otherThingTwo" value='Forty'>
  <input type="checkbox" name="otherThingTwo" value='Fifty'>

  <button type="submit">Show target URL</button>
</form>

最后3行仅用于防止表单发送和显示结果URL。

也可以仅使用serialize() Mathod和正则表达式来解决问题,但是它需要在浏览器中使用后置断言支持。

答案 4 :(得分:0)

以防万一,您可以更改html,这是使用隐藏字段的解决方案。

function updateChecks() {

  $.each(['anythingOne', 'otherThingTwo'], function(i, field) {
    var values = $('input[type=checkbox][data-for=' + field + ']:checked').map(function() {
      return this.value;
    }).get().join(',');
    $('input[type=hidden][name=' + field + ']').val(values);

  });
}
$(function() {
  $('form').on('submit', function(e) {
    updateChecks();
  });
  updateChecks();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="get">
  <input type="hidden" name="anythingOne" value='' />
  <input type="hidden" name="otherThingTwo" value='' />
  <input type="checkbox" data-for="anythingOne" value='one' checked='' />
  <input type="checkbox" data-for="anythingOne" value='two' />
  <input type="checkbox" data-for="anythingOne" value='three' checked='' />
  <input type="checkbox" data-for="otherThingTwo" value='Forty' />
  <input type="checkbox" data-for="otherThingTwo" value='Fifty' checked='' />
</form>