Search code examples
javascriptjqueryform-data

How to get a form to build a FormData() object without using an id as a selector


I'm trying to get a form that is inside a "modal-body" div and create a FormData() object when the user clicks on a modal button. For special reasons I can't get this form by id or class, so I'm doing it like this:

$('.save-form').click(function() {
    var myform = $(this).parent().parent().find('.modal-body').html();
    var fd = new FormData(myform);
}

By using .html() or .contents() I get the error: "Failed to construct 'FormData': parameter 1 is not of type 'HTMLFormElement'".

It works fine if I use an id as a selector, but as I said I cannot get it by it's id. Apparently FormData() is not liking what I'm passing to it. So my question is: Do I need to get the form thru another way or do I need to make a conversion or something first? I will appreciate any help.

This is my html:

<div id="myModal" class="modal fade" tabindex="-1" role="dialog">
    <div class="modal-dialog modal-xl" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">My Title</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                <div class="modal-body">
                    <form>
                        <input type="checkbox" name="item-1">
                        <label>Item 1</label>
                        <input type="checkbox" name="item-2">
                        <label>Item 2</label>
                        <input type="checkbox" name="item-3">
                        <label>Item 3</label>
                        <input type="checkbox" name="item-4">
                        <label>Item 4</label>
                    </form>            
                </div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
                <button type="button" class="btn btn-primary save-form">Save</button>
            </div>
        </div>
    </div>
</div>

Solution

  • You need to use plain JavaScript or de-reference the jQuery Object when referencing the <form> tag. FormData() Object does not recognize jQuery Objects. Any of the following should work:

    De-reference jQuery Object

    $('form')[0];
    $('form').get(0);
    

    Plain JavaScript

    document.forms[0];
    document.querySelector('form');
    document.getElementsByTagName('form')[0];
    

    All of the above will get the first <form> tag on the webpage without any attributes.

    Demo

    $('.save-form').click(function() {
      const form = $('form')[0];
      const fd = new FormData(form);
      console.log(fd);
    });
    <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
    
    <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#xModal">
      Modal
    </button>
    
    <div id="xModal" class="modal fade" tabindex="-1" role="dialog">
      <div class="modal-dialog modal-xl" role="document">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title">My Title</h5>
            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
          </div>
          <div class="modal-body">
            <div class="modal-body">
              <form>
                <input type="checkbox" name="item-1">
                <label>Item 1</label>
                <input type="checkbox" name="item-2">
                <label>Item 2</label>
                <input type="checkbox" name="item-3">
                <label>Item 3</label>
                <input type="checkbox" name="item-4">
                <label>Item 4</label>
              </form>
            </div>
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
            <button type="button" class="btn btn-primary save-form">Save</button>
          </div>
        </div>
      </div>
    </div>
    
    <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js'></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>