使用纯JavaScript将HTML表单序列化为JSON

igsr9ssn  于 2023-01-04  发布在  Java
关注(0)|答案(4)|浏览(164)

我见过这种将表单序列化为JSON的方法,效果很好。我的问题是:我怎样才能不使用任何jQuery代码而使用纯JavaScript实现这一点呢?如果这个问题很愚蠢,我很抱歉,但我仍在学习中,所以如果有人能帮助我,我将不胜感激。

(function ($) {
    $.fn.serializeFormJSON = function () {

        var objects = {};
        var anArray = this.serializeArray();
        $.each(anArray, function () {
            if (objects[this.name]) {
                if (!objects[this.name].push) {
                    objects[this.name] = [objects[this.name]];
                }
                objects[this.name].push(this.value || '');
            } else {
                objects[this.name] = this.value || '';
            }
        });
        return objects;
    };
})(jQuery);

$('form').submit(function (e) {
    e.preventDefault();
    var data = $(this).serializeFormJSON();
    console.log(data);

    /* Object
        email: "value"
        name: "value"
        password: "value"
     */
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="#" method="post">
    <div>
        <label for="name">Name</label>
        <input type="text" name="name" id="name" />
    </div>
    <div>
        <label for="email">Email</label>
        <input type="text" name="email" id="email" />
    </div>
    <div>
        <label for="password">Password</label>
        <input type="password" name="password" id="password" />
    </div>
    <p>
        <input type="submit" value="Send" />
    </p>
</form>

另外,在jQuery中,这是将用户输入的多个JSON对象作为一个字符串发送的正确方法吗?因为我正在寻找这样做的方法。

jxct1oxe

jxct1oxe1#

你可以试试这样的方法:

function formToJson(){
        var formElement = document.getElementsByTagName("form")[0],
            inputElements = formElement.getElementsByTagName("input"),
            jsonObject = {};
        for(var i = 0; i < inputElements.length; i++){
            var inputElement = inputElements[i];
            jsonObject[inputElement.name] = inputElement.value;

        }
        return JSON.stringify(jsonObject);
    }

这个解决方案只有在页面上只有一个表单时才有效,为了使它更通用,函数可以将表单元素作为参数。

xfb7svmp

xfb7svmp2#

您可以使用Array.reduce,类似于

// get array of all fields and/or selects (except the button)
const getFields = () => Array.from(document.querySelectorAll("input, select"))
    .filter(field => field.type.toLowerCase() !== "button");

// get id, name or create random id from field properties
const getKey = field => field.name 
  || field.id 
  || `unknown-${Math.floor(1000 * Math.random()).toString(16)}`;

// get data, simple object
const getFormData = () => getFields()
    .reduce( (f2o, field) => ({...f2o, [getKey(field)]: field.value}), {} );

// log the result
const logResult = txt => document.querySelector("#result").textContent = txt;

// get data, array of field objects
const getMoreFormData = () => getFields()
  .reduce( (f2o, field) =>
    f2o.concat({
        id: field.id || "no id",
        name: field.name || "no name",
        idGenerated: getKey(field),
        type: field.type, 
        value: field.value }
      ),
    [] );

// handling for buttons
document.addEventListener("click", evt => {
  if (evt.target.nodeName.toLowerCase() === "button") {
    console.clear();
    logResult(/simple/.test(evt.target.textContent)
     ? JSON.stringify(getFormData(), null, " ")
     : JSON.stringify(getMoreFormData(), null, " ")
    );
  }
} );
<form action="#" method="post">
  <div>
    <label for="name">Name</label>
    <input type="text" name="name" id="name" value="Pete"/>
  </div>
  <div>
    <label for="email">Email</label>
    <input type="text" name="email" id="email" value="pete@here.com"/>
  </div>
  <div>
    <label for="password">Password</label>
    <input type="password" name="password" id="password" />
  </div>
  <div>
    <label>Field without name or id</label>
    <input type="number" value="12345" />
  </div>
</form>

<p>
  <button>Data simple object</button> <button>Data fields array</button>
</p>

<pre id="result"></pre>
bogh5gae

bogh5gae3#

请记住,对于复选框,value属性可以是onoff字符串。这是不需要的。下面是我的解决方案,基于this codepen

let json = Array.from(form.querySelectorAll('input, select, textarea'))
    .filter(element => element.name)
    .reduce((json, element) => {
        json[element.name] = element.type === 'checkbox' ? element.checked : element.value;
        return json;
    }, {});

let json = {};
Array.from(form.querySelectorAll('input, select, textarea'))
    .filter(element => element.name)
    .forEach(element => {
        json[element.name] = element.type === 'checkbox' ? element.checked : element.value;
    });

OR(带 typescript )

export type FormJson = {[key: string]: boolean | string};

export const toJson = (form: HTMLFormElement): FormJson => 
    Array.from(form.querySelectorAll<HTMLFormElement>('input, select, textarea'))
        .filter(element => element.name)
        .reduce<FormJson>((json, element) => {
            json[element.name] = element.type === 'checkbox' ? element.checked : element.value;
            return json;
        }, {});
iq0todco

iq0todco4#

要序列化您的form,您可以这样做(注意,我在form标记中添加了一个onsubmit):
HTML和JavaScript:

function serializeForm(e) {
    e.preventDefault(); // prevent the page to reload

    let form = e.target; // get the form itself
    let data = new FormData(form); // serialize input names and values

    let objSerializedForm = {}; // creating a new object
    for (let [name, value] of data) { // iterating the FormData data
        objSerializedForm[name] = value; // appending names and values to obj
    }
    
    console.log(objSerializedForm);
}
<form action="#" method="post" onsubmit="serializeForm(event)">
    <div>
        <label for="name">Name</label>
        <input type="text" name="name" id="name" />
    </div>
    <div>
        <label for="email">Email</label>
        <input type="text" name="email" id="email" />
    </div>
    <div>
        <label for="password">Password</label>
        <input type="password" name="password" id="password" />
    </div>
    <p>
        <input type="submit" value="Send" />
    </p>
</form>

然后,您可以对objSerializedForm执行任何您想要的操作,通过调用objSerializedForm.name获取每个值。

相关问题