Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignoring empty form fields #28

Closed
ruiquelhas opened this issue Dec 2, 2014 · 8 comments
Closed

Ignoring empty form fields #28

ruiquelhas opened this issue Dec 2, 2014 · 8 comments

Comments

@ruiquelhas
Copy link

As far as I could understand, there is no way to ignore empty form fields, excluding them from the resulting object. If so, is this feature on the roadmap or are you open to a pull request?

@marioizquierdo
Copy link
Owner

The method serializeJSON works on any set of jQuery elements.
You could filter your jQuery object to keep only what you want to serialize, i.e.:

$someForm.not('[value=""]').serializeJSON();

And there's also the :skip type, that could be used on input names in order to filter them out (feature added in version 2.4.0). For example:

<input type="text" name="you[are]" value="in"/>
<input type="text" name="I[am]:skip" value="out"/>
$('input').serializeJSON();
// returns =>
{ "you": {"are": "in"}} // Note that {"I": {"am": "out"}} is not included

Does this work for you?

@ruiquelhas
Copy link
Author

The first alternative would fit my use-case, but I tried it, and it does not seem to be working as I expected, the empty fields are still added to the object as empty strings. I've also added a test for it, and it fails.

The second one does not fit my use-case, because I just want fields to be optional, not skipped entirely, in order to avoid sending dummy data through the wire.

@marioizquierdo
Copy link
Owner

There must be something wrong with your jQuery object.
Make sure you have selected only the fields you want because serializeJSON acts only on those elements.

I've checked StackOverflow and this seems to be a good answer:
http://stackoverflow.com/questions/608730/how-do-i-use-jquerys-form-serialize-but-exclude-empty-fields

$("#myForm :input[value!='']").serializeJSON()

@ruiquelhas
Copy link
Author

I've added the following test case to your suite.

describe('options', function () {
    beforeEach(function () {
       // ... 
    });

    // ...

    describe('filters empty values using proper selector', function () {
      it('does not return any value', function () {
        obj = $form.not('[value=""]').serializeJSON();
        expect(obj).toEqual({
          "Numeric 0":     "0",
          "Numeric 1":     "1",
          "Numeric 2.2":   "2.2",
          "Numeric -2.25": "-2.25",
          "Bool true":     "true",
          "Bool false":    "false",
          "Null":          "null",
          "String":        "text is always string",
          // I want the following to not be included in the result
          // "Empty":         ""
        });
      });
    });
});

This fails. Am I missing something?

@marioizquierdo
Copy link
Owner

I see. Well, it turns out that selecting the right inputs from jQuery is not that easy after all.

In this case, you can not apply .not('value=""') to the form, because that a jQuery object with a single matched element (the <form>), which obviously doesn't have an empty value.
What you want to do is to match the inputs with no empty value, for example:

obj = $form.find('input').not('[value=""]').serializeJSON();
// or
obj = $form.find(':input[value!=""]').serializeJSON();

Note that the selector would be somehow different if you also had textareas or select tags.

This is a general jQuery problem, but I've seen others having the same issue. Maybe an option that is able to filter them out would help. I probably implement that in a future release. But for now, just make sure you are selecting the fields that you want to serialize.

@ruiquelhas
Copy link
Author

Yes, it works that way, thanks!

I'm not a big user of jQuery, so I thought find and the general $ selector would have the same behaviour, but apparently not.

Anyway, I've actually implemented that option in a fork, in case you fancy a pull request.

@danielkummer
Copy link

@marioizquierdo solution doesn't work for me if I'm using array elements, but I found this solution quite satisfying:

obj = $form.find(':input').filter(function () {
                    return $.trim(this.value).length > 0
                }).serializeJSON();

@brock
Copy link
Contributor

brock commented Mar 11, 2015

@marioizquierdo +1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants