jquery: how to remove blank fields from a form before submitting?
Asked Answered
E

7

32

I have a page with a set of forms on it, used for API testing. For reasons not worth explicating, I generally don't want to include empty fields in the submission to the server. How do I delete empty fields from the data before submitting?

For example, if I have a form with two fields, foo and bar, and the user leaves bar blank, I want the server to see the submission as if the only field were foo.

My first stab at that involved looping through the fields using jquery with

$("form").submit(function() {
    $(this).children(':input').each(...)
}

And removing the field. But that a) didn't work, and b) seems like it would delete the field from the visible form on the page which is not what I want.

Another approach might be to loop through the fields and construct the submit string manually with fields that have values other than "". Will that work? Any better ideas?

Ecchymosis answered 5/5, 2011 at 21:43 Comment(0)
D
43

One way would be to set the "disabled" attribute on those fields, which prevents their values from being serialized and sent to the server:

$(function()
{
    $("form").submit(function()
    {
        $(this).children(':input[value=""]').attr("disabled", "disabled");

        return true; // ensure form still submits
    });
});

If you have client-side validation, you'll also want to re-enable these fields in the event of a validation failure:

$(':input').removeAttr("disabled");

EDIT: repaired bug

Decanal answered 5/5, 2011 at 21:46 Comment(10)
That is really elegant... only it doesn't seem to work. What am I missing? In particular, on submission via http get so I can see what's going on, I still see something like 'api/userattributes/?action=read_by_user&name=&value=' where name and value were left blank, but still show up as submitting variables.Ecchymosis
On further investigation, ':input[value=""]' isn't finding anything. Walking through with a debugger after I split out the attr() call onto another line via each() shows that it never gets there, so disabled is never getting set.Ecchymosis
On further further investigation, this works beautifully if my form isn't inside a table, but not if it is. That sounds like a separate issue, so I'll mark this as accepted. Thanks for a quick and accurate answer.Ecchymosis
@Dave: I suspect that if you change $(this).children to $(this).find, it'll work in either place.Decanal
@FelipeTadeo: It should, because it's not using the "input" selector, but rather ":input", which is a jQuery-specific way to target inputs, textareas, selects, etc. However, the [value=""] part of the selector may not work with textarea. Best way might be to use a filtering function, similar to this: .children(':input').filter(function(item){ return !!$(item).val(); /* untested */ })Decanal
I think you are missing a closing bracket from your code. This works: $(function() { $("form.notification_search").submit(function() { $(this).children(':input[value=""]').attr("disabled", "disabled"); return true; // ensure form still submits }); });Germ
Recent versions of jQuery include the prop method. They recommend using that method rather than the attr method to set the disabled attribute so @LukeDennis code should be updated to $(this).children(':input[value=""]').prop('disabled', true);Pimbley
The method of using $(this).children(':input[value=""]') never worked at picking out the right elements for me. However, using .filter() to check the value works, as shown here: https://mcmap.net/q/202533/-selecting-empty-text-input-using-jqueryEquiprobable
@LukeDennis Could you tell me how to target a select option with value "" ?Kinnard
It's restricted to input fields, no selects or others are taken care of.Engage
G
25

Combining the answers here, with this question regarding finding empty input I arrived at this solution.

$(function() {
   $("form").submit(function() {
      $(this).find(":input").filter(function(){ return !this.value; }).attr("disabled", "disabled");
      return true; // ensure form still submits
    });
});

So starts form @Luke's solution, adds his suggestion of using find instead of children (my form is in a table), and then uses @gdoron's filter technique to isolate the empty elements.

Germ answered 11/9, 2013 at 9:32 Comment(3)
No - I think they are a figment of an over-imaginative mind.Germ
This should be the accepted answer. The accepted answer basically checks the input value when initially rendered (which may change), this answer checks the live input value when submitted.Ulna
This worked great for me, a clean and elegant solution @Germ +1Kenlay
I
6

I generally will just agree with @Luke, but the solution below should take care of any empty value regardless if it is an input tag or not, just remember to add a name property on all your form children elements if you want them to get serialized;

The HTML:

<form action="yourUrl.php" name="myForm" id="myForm">
input1: <input type="text" name="field1" /><br /><br />
input2: <input type="text" name="field2" /><br /><br />
input3: <input type="text" name="field3" /><br /><br />
input4: <input type="text" name="field4" /><br /><br />
select: <select name="selectField">
    <option value="">empty value</option>
    <option value="option2">option2</option>
    <option value="option3">option3</option>
</select><br /><br />
<input type="submit" name="submit" value="submit" />
</form>    

The jQuery:

$("#myForm").submit (function (e) {
    e.preventDefault();
    var _form = $(this);
    var data = {};
    var formData = _form.serializeArray();
    $.each(formData, function (index, value) {
        var data_name = formData[index].name;
        var data_value = formData[index].value;
        if (data_value !== "") {
            data[data_name] = data_value;
        }
    });
    // now with ajax you can send the sanitize data object
    $.post(_form.attr("action"), data, function(res, textStatus, jqXHR) {
        // do something
    });
});
Irritative answered 5/5, 2011 at 22:43 Comment(0)
C
2

The top voted answer did not work for me. I believe the selectors weren’t specific enough. Here's what worked for me:

$(function() {
  $("#myForm").submit(function() {
    $("#myForm *").filter(":input").each(function(){
      if ($(this).val() == '')
        $(this).prop("disabled", true);
    });

    return true; // ensure form still submits
  });
});
Ceja answered 5/1, 2016 at 15:24 Comment(0)
A
1

Removing empty fields on submit

$(function() {
    $('form').submit(function () {
        var $empty_fields = $(this).find(':input').filter(function () { 
            return $(this).val() === '';
        });
        $empty_fields.prop('disabled', true);
        return true;
    });
});

Combining several features and subjective styles, especially:

  • .find() goes deeper than .children().
  • .val() === '' works for textarea and changed attributes, [value=""] does not.
  • .prop() over .attr().
Augite answered 29/9, 2017 at 12:50 Comment(0)
K
1

Adding to Luke Dennis accepted answer. In case someone uses the Python/Django framework this script might help if you use the django-filters app. In this example I had multiple filters that had an input and selector html element. However, the script also worked on single input filters as well as multiplechoice filters.

$(function()
{
    var form = $( 'form' )[0];
    $( form ).submit(function() 
    { 
        $('input, select').each(function()
        {
            if ($(this).val().length === 0) 
            {
                $(this).prop('disabled', true);
                $(this).next().prop('disabled', true);
            }
        });
    });
});
Kaitlin answered 1/7, 2021 at 13:30 Comment(1)
Except for the nex() line this answer is the most versatile. And it works, also nice.Engage
U
0

Maybe not the best solution but this should be a quick and easy way to achieve what you're after

$("form").submit(function() {
    $(this).children('input[value=""]').each(function(){
        // Rename the name attribute to something else if the value is "" to it isn't submitted
        $(this).attr('blank', $(this).attr('name'));
        $(this).removeAttr('name');

    });
}

Then if you are using vlient side validation or are posting via ajax, then you need to set the name attribute back so the next submission will work correctly...

$(this).attr('name', $(this).attr('blank'));
$(this).removeAttr('blank');
Underpants answered 5/5, 2011 at 21:54 Comment(1)
@Luke just beat me to it with an almost identical answer, I prefer Luke's solution. :)Underpants

© 2022 - 2024 — McMap. All rights reserved.