Reputation: 1102
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?
Upvotes: 32
Views: 46773
Reputation: 13
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);
}
});
});
});
Upvotes: 1
Reputation: 17204
$(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()
.Upvotes: 1
Reputation: 8212
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.
Upvotes: 25
Reputation: 48
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
});
});
Upvotes: 2
Reputation: 14550
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
Upvotes: 43
Reputation: 1302
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
});
});
Upvotes: 6
Reputation: 3780
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');
Upvotes: 0