【问题标题】:AJAX how to serialize and post all form elements from within an elementAJAX如何从一个元素中序列化和发布所有表单元素
【发布时间】:2020-06-28 12:36:46
【问题描述】:

我正在尝试序列化和发布所有可能来自

元素或来自任何其他元素(div、tr 等)的表单元素。

简而言之,我的表单将来自:

<form id="frm1">
  Name: <input ...>
  Gender: <select ...>
  <input type="button" value="Submit" onClick="submitFormData('frm1')"/>
</form>

有时,我有 html TABLE,所以其中不能有

,因此我使用:
<table>
  <tr id="frm1">
    <td><input type...></td>
    <td><select...></td>
    <td><input type="button" value="Submit" onClick="submitFormData('frm1')"/></td>
  </tr>
  <tr id="frm2">
    <td><input type...></td>
    <td><select...></td>
    <td><input type="button" value="Submit" onClick="submitFormData('frm2')"/></td>
  </tr>
</table>

我似乎无法弄清楚如何从给定元素中提取和序列化所有表单元素(输入、选择等)。

到目前为止我的代码:

const ERROR_TYPE_FATALERROR = 1;
const ERROR_TYPE_INPUTERROR = 2;
const ERROR_TYPE_GLOBALMESSAGE = 3;

function submitFormData(formid) {

  var formNode = document.getElementById(formid);

  $.ajax({
    type: 'POST',
    url: $(location).attr('href'),
    // data: jQuery('#' + formid + ' input').serialize(), // this works, but will only get <INPUT...>s
    data: formNode.serialize(), // this doesn't work
    dataType : "json",
  }).done(function(response) {

    // If we have response, then it's PHP that returned an error!
    if(response) {

      // error type
      switch (response.type) {

        case ERROR_TYPE_GLOBALMESSAGE:
          // unhide informational box (i.e. "Data saved!")
          $('#globalMessage').addClass('d-block');
          $('#globalMessagePH').empty();
          $('#globalMessagePH').append(response.message);

          break;

        case ERROR_TYPE_FATALERROR:
          // unhide form fatal error message box showing response.message
          $('#fatalError').addClass('d-block');
          $('#fatalErrorMessagePH').empty();
          $('#fatalErrorMessagePH').append(response.message);

          break;

        case ERROR_TYPE_INPUTERROR:
          // unhide form input error messages based on response.field
          break;

        default:
          // ...
      }
    }

    // Successful post, but not response came back !?
    else {
      console.error("Post sent, but no response came back!?");
    }
  }).fail(function(response) {
    console.error("Unknown Error!"); // not sure yet how I'd get here... ?
  });

}

我还尝试向所有表单元素添加“data2post”类,以便获取发布所需的所有元素并对其进行序列化:

var formNode = document.getElementById(formid);
var formData = formNode.getElementsByClassName('data2post');
...
  data: formData.serialize()
...

但它不起作用:formData.serialize 不是函数

正如你从我的 JS sn-p 中看到的,我知道刚刚

data: jQuery('#' + formid + ' input').serialize()

有效,但这只会得到 。无论类型如何(输入、选择、文本区域等),我都需要能够获取所有表单元素

即使为了它,我也可以同时问一下,考虑到你们看到我使用这个 ajax 的目的,在良好的实践中,我是否应该在 .失败()部分?不确定我如何在 PHP 中执行此操作,这意味着触发失败。我所知道的是,如果我用 JSON 数据 die() 我的脚本,它将作为响应发送...

感谢您的帮助。

干杯,帕特

编辑:这是我的 SELECT 输入的示例:

<tr id="row_1">
  <!-- STATUS -->
  <td class="text-nowrap">
    <select name="isActive" id="isActive" class="form-control pl-2" aria-label="Account Status" aria-describedby="isActiveReq" required>
      <option value="1"  selected>Enabled</option>
      <option value="0" >Disabled</option>
    </select>

    <!-- missing field: add 'is-invalid' to the <input>'s classes to show OR 'was-validated' to the form's classes -->
    <div id="isActiveReq" class="pl-1 invalid-feedback">
      This field is required! 
    </div>
  </td>
  <td><input type="button" name="btnSave" value="Save" onClick="submitFormData('row_1')"></td>
</tr>

【问题讨论】:

    标签: javascript jquery ajax


    【解决方案1】:

    尝试使用$('#frm1').serialize();

    var data = $('#frm1').serialize();
    
    $.ajax({
      type: "POST",
      url: url,
      data: data,
      success: function(response){
         console.log(response);
      }
    });
    

    【讨论】:

    • 如果我的表单位于
      标记内,这将非常有用,但如果我的表单位于表格行 或任何其他
      元素内,则此方法将不起作用。
    【解决方案2】:

    没有表单元素也没关系,

    克隆指定的 id 元素,可以是它的 div 或任何东西:

    $('#myDiv').clone()
    

    附加到form 元素中:

    $('<form>').append($('#myDiv').clone()).serialize();
    

    以下是工作示例,包括几乎类型的元素:

    function getSerialize(id){
    
        let element = $("#"+id);
    
        // if you are using form element
        if( element.prop("tagName") === "FORM" ){
            var data = element.serialize();
        }
    
        // if your are using another elements
        else{
            var myInputs = element.clone();
            // this is the bug getting select box selected value when clone, so we have selected value in clone using this hack.
            element.find('select').each(function(i) {
                myInputs.find('select').eq(i).val($(this).val())
            })
            var data = $('<form>').append(myInputs).serialize();
        }
    
        // you can return 'data' variable from here.
        console.log(data);
    
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <h1>Div Serialize</h1>
    <div id="myDiv">
        <input type="text" name="name" placeholder="Name"><br><br>
        <select name="age" placeholder="Age">
            <option value="">Age</option>
            <option value="18+">18+</option>
        </select><br><br>
        <textarea name="about" placeholder="About"></textarea><br><br>
        <button onClick="getSerialize('myDiv')">Get Serialize</button>
    </div>
    
    <h1>Form Serialize</h1>
    <form id="myDivForm" action="" onSubmit="return false;">
        <input type="text" name="name" placeholder="Name"><br><br>
        <select name="age" placeholder="Age">
            <option value="">Age</option>
            <option value="18+">18+</option>
        </select><br><br>
        <textarea name="about" placeholder="About"></textarea><br><br>
        <button onClick="getSerialize('myDivForm')">Get Serialize Form</button>
    </form>

    希望对您有所帮助。

    【讨论】:

    • 不完全是。我认为它确实有两个问题:1)这只有在我不使用
      标签时才有效。如果我尝试使用表格行,我需要使我的函数与
      或 等一起工作 2):var myInputs = $(' #'+formid).clone(); var data = $('').append(myInputs).serialize();控制台.log(数据);我得到输出: id=1&isActive=1&days=156&months=18 isActive 是一个具有 2 个可能值的 SELECT:0 或 1。无论我选择什么,输出仍然是 isActive=1 !其他输入虽然似乎显示了正确的数据
    • @Pat,好的,我已经更新了答案,如果您使用过form,它会检测到,如果您使用过任何other element,它会检测到。
    • 是的。该标准有效。我刚刚发现,但是使用 'instanceof HTMLFormElement' 代替......但是,clone() 似乎没有得到正确的表单 SELECT 值.. 它坚持我的测试用例中的第一个值......跨度>
    • 我刚刚遇到stackoverflow.com/questions/742810/…。这是 jQuery 的一个已知错误!?有没有一种方法可以让我简单地在我想要提交的字段(输入、选择、文本区域等)上添加一个说“data2post”的类,而不管表单控件的类型是什么?然后使用 formNode.getElementsByClassName('data2post');我猜我将有义务循环返回的数组(如果它总是一个数组?)然后 $newForm.append(input)... 或什么?
    • 你能在你的问题中添加你的选择代码吗,如果可能的话我会帮忙的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-21
    • 2018-04-19
    • 1970-01-01
    • 1970-01-01
    • 2020-04-07
    • 1970-01-01
    • 2011-11-26
    相关资源
    最近更新 更多