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

问题描述 投票:1回答:5

示例代码:

<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()不起作用。有任何想法吗?

javascript jquery forms
5个回答
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>

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);
});

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>

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。

也可以仅使用qazxsw poi方法和正则表达式来解决问题,但它需要浏览器中的lookbehind断言支持。


0
投票

您可以收集所有选中的拳击手和serialize()弦的不同部分。这可能不是最干净或最有效的解决方案,但它的工作原理。我用一个按钮来触发连接。在代码中查看我的评论。

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 
	})
})
© www.soinside.com 2019 - 2024. All rights reserved.