3

I have forms similar to this:

<form class="submission-form" method="POST" action="/post/create/">
  <input type="text" name="title">
  <textarea name="post_content"></textarea>
  <select name="visibility" class="form-control">
    <option value="1">Public</option>
    <option value="2">Private</option>
  </select>
  <input class="submit-button" type="button" value="Publish">
</form>

The various fields in the form are not known beforehand and can change; what is known is the fact that every form that needs processing has a submission-form class on it, and it contains a button with the class submit-button.

I'm trying to add an event listener on the input.submit-button that will traverse on the form its contained in, find all the fields, and create an object from it. For example, in the above case, the object created might look like:

{
  title: "My first post",
  post_content: "Hello there!",
  visibility: 1
}

How should I go about doing this?

3 Answers3

1

Iterate through input, textarea and select elements and create an object with properties from element name and value:

$('.submit-button').on('click', function() {
  var o = {};
  $(this).closest('form')
    .find('input, textarea, select')
    .not(':button')
    .each(function() {
      o[$(this).attr('name')] = $(this).val()
    });
  console.log(o);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class="submission-form" method="POST" action="/post/create/">
  <input type="text" name="title" />
  <textarea name="post_content"></textarea>
  <select name="visibility" class="form-control">
    <option value="1">Public</option>
    <option value="2">Private</option>
  </select>
  <input class="submit-button" type="button" value="Publish" />
</form>

References

.closest()

.not()

.each

Alex Char
  • 32,879
  • 9
  • 49
  • 70
  • `.closest()` is better than `.parents()`. It stops as soon as it finds the first match, instead of searching the entire DOM hierarchy. – Barmar Sep 18 '16 at 09:26
  • @Barmar In DOM structure like this one doesn't really matter. In any case closest is faster so I replaced it :) – Alex Char Sep 18 '16 at 09:29
0

You could use serializeArray() and then use reduce() on that array to return desired object.

$("form").submit(function(event) {
  var data = $(this).serializeArray().reduce(function(r, e) {
    r[e.name] = e.value;
    return r;
  }, {})
  console.log(data)
  event.preventDefault();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class="submission-form">
  <input type="text" name="title">
  <textarea name="post_content"></textarea>
  <select name="visibility" class="form-control">
    <option value="1">Public</option>
    <option value="2">Private</option>
  </select>
  <input class="submit-button" type="submit" value="Publish">
</form>
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
0

Use serializeArray() to create and array of objects for name value pairs and loop through them to create a single object.

$('form').submit(function(e){
  e.preventDefault();
  var obj = $(this).serializeArray()
  
  var final= {};
  $.each(obj, function(index,object){
    
      final[object.name] = object.value;
    
  });
  console.log(final);
  
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class="submission-form" method="POST" action="/post/create/">
  <input type="text" name="title">
  <textarea name="post_content"></textarea>
  <select name="visibility" class="form-control">
    <option value="1">Public</option>
    <option value="2">Private</option>
  </select>
  <input class="submit-button" type="submit" value="Publish">
</form>
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400