javascript 如何使用javascript提取HTML表单数据?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13415890/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to extract HTML form data with javascript?
提问by jpeltoniemi
I need to extract data from an HTML form with javascript(+Mootools) in the same kind of nested object format that PHP would see it when the form is posted.
我需要使用 javascript(+Mootools) 从 HTML 表单中提取数据,该格式与 PHP 在发布表单时会看到的嵌套对象格式相同。
Am I just bad at googling or is there really no native nor a well-known way to achieve this? I see many others have asked the same question in different forums but so far all have accepted solutions like jQuery serializeArray and such.
我只是不擅长谷歌搜索还是真的没有本地或众所周知的方法来实现这一目标?我看到许多其他人在不同的论坛上问过同样的问题,但到目前为止,所有人都接受了 jQuery serializeArray 等解决方案。
I tried out serializeArray with jsFiddle http://jsfiddle.net/7quxe/and the results were disappointing.
我用 jsFiddle http://jsfiddle.net/7quxe/尝试了 serializeArray,结果令人失望。
I've previously written a script for this myself and it worked quite well except it had some problems when the form had overlapping mixed key type fields (<input name="foo[bar]" value="1"> and <input name="foo[]" value="2"
. I've already started working on a better version but as I found myself starting over again and again, I thought to myself: There are lots of great js libraries out there that aim to solve many basic everyday problems. Can it really be that wanting to extract data from a form in a properly formatted object is not that common?
我以前为此自己编写了一个脚本,它运行得很好,只是当表单具有重叠的混合键类型字段时出现了一些问题(<input name="foo[bar]" value="1"> and <input name="foo[]" value="2"
。我已经开始研究更好的版本,但是当我发现自己重新开始时再一次,我心想:有很多很棒的 js 库旨在解决许多基本的日常问题。想要从表单中提取格式正确的对象中的数据真的不是很常见吗?
Here is an example of what I'm attempting:
这是我正在尝试的示例:
<form method="post" action="/">
<input name="test" value="test">
<input name="nested[a]" value="a">
<input name="nested[b]" value="b">
<input name="nested[c]" value="c">
<input name="arraytest[]" value="foo">
<input name="arraytest[]" value="foo">
<input name="arraytest[]" value="foo">
</form>
Here's how PHP would see this:
以下是 PHP 将如何看待这一点:
$_POST = array(
'test' => 'test',
'nested' => array(
'a' => 'a',
'b' => 'b',
'c' => 'c',
),
'arraytest' => array(
0 => 'foo1',
1 => 'foo2',
2 => 'foo3'
)
)
and this is what I'd like to get in js:
这就是我想在 js 中得到的:
{
test : 'test',
nested : {
a : 'a',
b : 'b',
c : 'c'
},
arraytest : { // This could also be an array ['foo1','foo2','foo3']
0 : 'foo1',
1 : 'foo2',
2 : 'foo3'
}
}
采纳答案by jpeltoniemi
I got obsessed about this and then some more :D
我对这个很着迷,然后还有一些:D
Here's my solution: http://jsfiddle.net/sLZZr/3/
这是我的解决方案:http: //jsfiddle.net/sLZZr/3/
Feel free to borrow it. If you find it helpful, please let me know (not a requirement, just curious. My email's in the source :)
随意借用。如果您觉得它有帮助,请告诉我(不是要求,只是好奇。我的电子邮件在源中:)
Answering requires formatted code, so here goes:
回答需要格式化的代码,所以这里是:
/**
* FormAccess
*
* @description Manipulate data in forms and element collections. Currently only reading supported.
*
* @version 0.8
*
* @license MIT License
*
* @author Jani Peltoniemi <[email protected]>
*
* @copyright 2012 Jani Peltoniemi
*/
/**
* FormAccess main class
*
*/
FormAccess = new Class({
formElm : null, // The form element this instance will be linked to
/**
* Constructs the class and adds the quick access method "extractData" to formElm
*
* @param Form element
*/
initialize:function(formElm) {
this.formElm = document.id(formElm);
this.formElm.extractData = this.extractData.bind(this);
},
/**
* Calls the static extractData function with the linked form's inputs
*
* @returns Extracted form data in nested object
*/
extractData : function() {
var inputElms = this.formElm.getElements('input,textarea,select');
return this.$constructor.extractData(inputElms);
}
});
/**
* FormAccess static functions
*
* Currently only reading available. Filling forms according to data in an object will come later.
*
*/
FormAccess.extend({
/**
* Extracts the data from given elements
*
* Notes :
* - Converts empty keys to numeric. If (non-converted)numeric keys are already present, empty key becomes <largest key>+1.
* - Elements are handled from top to bottom. When converting empty keys between other numeric keys the largest key means largest key _up to that point_.
* - Inputs with empty names are not included in results.
* - Checkboxes' value attribute is ignored and only their checked state is included in results.
* - Multi-selectboxes return the selected values in an array
*
* @param Selector, element or element collection - everything that $$() takes in.
*
* @returns Extracted form data in nested object
*/
extractData : function(inputElms) {
// Normalize the input / query DOM
inputElms = $$(inputElms);
var that = this;
var result = {};
// Data from input elements is collected here for easier handling
var inputData = [];
// Collect inputData
inputElms.each(function(inputElm) {
if (!inputElm.name)
return;
// Explode the input name into an array path
var path = that.parseName(inputElm.name);
inputData.push({
path:path,
value:inputElm.value ? inputElm.value : '',
elm:inputElm
});
});
// Index tracking variable. Used to find next free numeric keys
var maxIndex;
inputData.each(function(data,i) {
var path = data.path;
// Last element of the path needs special treatment. Pop it out.
var last = path.pop();
// Working var
var current = result;
path.each(function(part) {
// Assign a numeric key if the key is empty
if (part == '') {
// Reset the index tracker
maxIndex = -1;
// Loop through the current position in result set
Object.each(current,function(val,key) {
// Convert key to int and make sure it is a proper number
var intKey = key.toInt();
if (intKey == key && intKey > maxIndex) {
// Key is greater than known largest key.
maxIndex = intKey;
}
});
// Set the key to largest found key + 1
part = maxIndex + 1;
}
// If the next position is not defined or is not an object, overwrite it.
if (typeOf(current[part]) != 'object')
current[part] = {};
// Update the position
current = current[part];
});
var lastWasEmpty = false;
// Evaluate the last part separately
if (last == '') {
lastWasEmpty = true;
// Reset the index tracker
maxIndex = -1;
// Loop through the current position in result set
Object.each(current,function(val,key) {
// Convert key to int and make sure it is a proper number
var intKey = key.toInt();
if (intKey == key && intKey > maxIndex) {
// Key is greater than known largest key.
maxIndex = intKey;
}
});
// Set the key to largest found key + 1
last = maxIndex + 1;
}
// Element-specific value handling
switch (data.elm.tagName.toLowerCase()) {
// Case for Select, since they allow multiple selections
case 'select':
if (data.elm.multiple) {
// A <value> = <selected> format was considered here but rejected due to long values being bad keys
current[last] = data.elm.getSelected().get('value');
} else
current[last] = data.value;
break;
// Inputs have a couple of special cases that need to be handled differently
case 'input':
switch (data.elm.type) {
// Only the value of the checked radiobutton is included in results.
// If none is checked, the result will display null
case 'radio':
// Only set the value if radiobutton is checked
// Otherwise check if this key is not already in results and then set it to null
if (data.elm.checked)
current[last] = data.value;
else if (current[last] == undefined)
current[last] = null;
break;
// Checkboxes' value attribute is ignored and the checked state is included in results
case 'checkbox':
current[last] = data.elm.checked;
break;
// All others
default:
current[last] = data.value;
break;
}
break;
// All other elements are handled here.
default:
current[last] = data.value;
break;
}
});
return result;
},
/**
* Explodes the name attribute.
*
* Example:
* name="testinput[foo][bar][]" -> ['testinput','foo','bar','']
*
* @param Input name
*
* @returns Exploded input name
*/
parseName : function(name) {
var path = [name.match(/^[^\[]*/)[0]];
var pathRegExp = /\[(.*?)\]/g;
var part = '';
while (true) {
part = pathRegExp.exec(name);
if (part !== null)
path.push(part[1]);
else
break;
}
return path;
},
/**
* Applies the FormData object to chosen form elements.
*
* If falsy argument is given, FormData is applied to all forms
*
* @param Selector, element or element collection - everything that $$() takes in.
*
* @returns Element collection
*/
apply : function(elements) {
if (!elements)
elements = 'form';
elements = $$(elements);
elements.each(function(element) {
element.formAccess = new FormAccess(element);
});
return elements;
}
});
回答by Matt Brock
You can do this with straight JavaScript using the form.elements
object. Here's an example that will convert any form into string of URL parameters:
您可以使用form.elements
对象直接通过 JavaScript 执行此操作。这是一个将任何形式转换为 URL 参数字符串的示例:
function getParameters(form) {
var parameters = "";
for (var x=0, y=form.elements.length; x < y; x++) {
var field = form.elements[x];
if (field.name && field.type !== "submit") {
parameters += "&" + encodeURIComponent(field.name) + "=" + (field.type == "radio" || field.type == "checkbox" ? (field.checked == "checked") : encodeURIComponent(field.value));
}
return parameters;
}
回答by Kotzilla
from your answer. i've made jquery script to extract input element and it will work only with input one dimension array like "input[string]" and "input[]" only, cheers
jsfiddle
从你的回答。我已经制作了 jquery 脚本来提取输入元素,它只适用于输入一维数组,如“input[string]”和“input[]”,欢呼
jsfiddle
HTML
HTML
<h2>Form</h2>
<form action="" name="form" method="post">
<input name="test" value="test">
<input name="nested[a]" value="a">
<input name="nested[b]" value="b">
<input name="nested[c]" value="c">
<input name="arraytest[]" value="foo">
<input name="arraytest[]" value="foo">
<input name="arraytest[]" value="foo">
<p><input type="submit" /></p>
</form>
<h2>JSON output</h2>
<pre id="result"></pre>??????
jQuery
jQuery
$.fn.serializeObject = function()
{
var o = {}, a = this.serializeArray();
$.each(a, function() {
if (/(\[\]$|\[.+\]$)/.test(this.name)) {
var match = /(.+)(\[\]|\[(.+)\])/.exec(this.name);
if (match[3] !== undefined)
{
var index = match[3];
if (o[match[1]] === undefined)
o[match[1]] = {};
if (o[match[1]][index] === undefined)
o[match[1]][index] = [o[match[1]][index]];
o[match[1]][index] = this.value || '';
} else {
if (o[match[1]] === undefined)
o[match[1]] = new Array;
o[match[1]].push(this.value || '');
}
} else {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
}
});
return o;
};
$(function() {
$('form').submit(function() {
$('#result').text(JSON.stringify($('form').serializeObject()));
return false;
});
});?
回答by Manjunath H
FormData data= new FormData();
Data consists of your all form data If you want specifically then you need to use
数据由您的所有表单数据组成 如果您特别想要,那么您需要使用
data.get("fieldName");
回答by Manjunath H
export default class Article extends Component{
handlesubmit(e)
{
e.preventDefault();
const data = new FormData(e.target);
let userid=qs.parseUrl(window.location.search).query.id;
data.append("userid",userid);
if(document.cookie.split(';')[0]=='login=true')
fetch('/api/medium/article',{
method: 'POST',
body:data
})
.then(Response=>{
console.log(Response);
return Response.json();
})
.then(Response=>{
console.log(Response);
window.location.pathname='/medium';
return Response;
})
.catch(err=>{
return err;
});
else{
alert("please login again");
window.location.pathname='/medium';
}
}
render()
{
return (
<div className="create-article">
<form encType="multipart/form-data" className="articleCreating" onSubmit={this.handlesubmit} >
<div className="form-group">
<select className="custom-select" autoFocus required name='category'>
<option value="">Select Category</option>
<option value="TECHNOLOGY">Technology</option>
<option value="NATURE">Nature</option>
<option value="FOOD">Food</option>
</select>
</div>
<div className="input-group">
<input type="text" className="form-control" aria-label="Title" placeholder="Title"
maxLength="70" spellCheck="true" name="title" required />
</div>
<div className="input-group">
<input type="text" className="form-control" aria-label="Subtitle" placeholder="Subtitle"
spellCheck="true" name="description" required />
</div>
<div className="input-group has-error">
<textarea className="form-control" aria-label="With textarea" placeholder="Description" cols="10"
rows="10" spellCheck="true" name="article" required>
</textarea>
</div>
<div className="fileinput">
<span><input type="file" name="image"/></span>
</div>
<div className="article-submit">
<button className="btn btn-raised btn-success" type='submit'>Create Article</button>
</div>
</form>
</div>
)
}
}
this is in react I think u can achieve the same thing using js also
这是在反应我认为你也可以使用 js 实现同样的事情
回答by DanMan
dojo has a neat method for that called dojo.formToObject(). As the name suggests, it converts all form element (inputs, selects, ...) into an object. You could then easily convert it into JSON and send it over the wire via AJAX, for example.
dojo 有一个简洁的方法,称为dojo.formToObject()。顾名思义,它将所有表单元素(输入、选择、...)转换为一个对象。例如,您可以轻松地将其转换为 JSON 并通过 AJAX 通过网络发送。