skip to Main Content

I’m trying to serialize and post all form elements that may come from either witin a <form> element, or from within any other elements (div, tr, etc.).

In short, my form will come from either:

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

and sometimes, I have html TABLE so cannot have a <form> in them, therefor I use:

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

I can’t seem to figure out how to pull out and serialize all form elements (inputs, selects, etc.) FROM within a given element.

My code so far :

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

}

I had also tried adding a "data2post" class to all form elements in order get all the elements needed for post and serialize them:

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

but it doesn’t work: formData.serialize is not a function

As you can see from my JS snippet, I know having just

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

works, but this will only get the <INPUT…>. I need to be able to get all form elements regardless of type (inputs, select, textarea, etc.)

And even for the sake of it, might I ask at the same time, considering you folks see what I’m using this ajax for, in good practice, should I be getting the response.type, etc more in the .fail() section ? Not sure how I to do this yet in PHP, meaning trigger a failure. All I know is if I die() my script with JSON data, it’ll be sent as the response…

Thanks a million for your help.

Cheers, Pat

EDIT: here is an example of my SELECT inputs:

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

2

Answers


  1. try use $('#frm1').serialize();

    var data = $('#frm1').serialize();
    
    $.ajax({
      type: "POST",
      url: url,
      data: data,
      success: function(response){
         console.log(response);
      }
    });
    
    Login or Signup to reply.
  2. Its OK if you don’t have form element,

    Clone specified id element, either its div or anything:

    $('#myDiv').clone()
    

    Append into a form element:

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

    Below is working example, almost type of element included:

    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>

    Hope this help.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search