3

我需要使用 javascript(+Mootools) 从 HTML 表单中提取数据,其嵌套对象格式与发布表单时 PHP 会看到的嵌套对象格式相同。

我只是不擅长谷歌搜索,还是真的没有本地或众所周知的方法来实现这一目标?我看到许多其他人在不同的论坛上问过同样的问题,但到目前为止,所有人都接受了 jQuery serializeArray 等解决方案。

我用 jsFiddle http://jsfiddle.net/7quxe/尝试了 serializeArray,结果令人失望。

我之前自己为此编写了一个脚本,它工作得很好,除了当表单有重叠的混合键类型字段时它有一些问题(<input name="foo[bar]" value="1"> and <input name="foo[]" value="2"。我已经开始研究一个更好的版本,但是当我发现自己重新开始并且再次,我心想:有很多很棒的 js 库,旨在解决许多基本的日常问题。难道真的希望从格式正确的对象中提取数据并不常见吗?

这是我正在尝试的示例:

<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>

下面是 PHP 会如何看待这个:

$_POST = array(
    'test' => 'test',
    'nested' => array(
        'a' => 'a',
        'b' => 'b',
        'c' => 'c',
    ),
    'arraytest' => array(
        0 => 'foo1',
        1 => 'foo2',
        2 => 'foo3'
    )
)

这就是我想在 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'
    }
}
4

6 回答 6

3
FormData data= new FormData();

数据由您的所有表单数据组成如果您特别想要,那么您需要使用

data.get("fieldName");
于 2018-07-27T10:39:34.397 回答
1

从你的回答。我制作了 jquery 脚本来提取输入元素,它只适用于输入一维数组,如“input[string]”和“input[]”,欢呼
jsfiddle

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

  $.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;
    });
  });​
于 2012-11-16T16:13:43.110 回答
1

您可以使用该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;
}
于 2012-11-16T11:56:41.290 回答
0

dojo 有一个简洁的方法,称为dojo.formToObject()。顾名思义,它将所有表单元素(输入、选择、...)转换为对象。例如,您可以轻松地将其转换为 JSON 并通过 AJAX 通过网络发送。

于 2012-11-16T17:27:12.540 回答
0

我对此很着迷,然后又迷上了:D

这是我的解决方案:http: //jsfiddle.net/sLZZr/3/

随意借用它。如果您觉得它有帮助,请告诉我(不是要求,只是好奇。我的电子邮件在源代码中:)


回答需要格式化的代码,所以这里是:

/**
 * FormAccess
 * 
 * @description Manipulate data in forms and element collections. Currently only reading supported.
 *
 * @version     0.8
 *
 * @license     MIT License
 * 
 * @author      Jani Peltoniemi <jani@olio-labs.fi>
 * 
 * @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;
    }
});
于 2012-11-16T17:14:38.950 回答
0
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>

        )
    }
}

这是反应我认为你也可以使用 js 实现同样的事情

于 2018-07-27T10:49:47.483 回答