jQuery serialize HTML5 data attributes
Asked Answered
E

3

10

Couldn't find this anywhere, maybe someone knows or can make a suggestion.

I had a form with lots of <inputs>, I wanted to send that form with jQuery $.ajax functionality, so I did $('#myform').serialize() and send this as json.

Now my form is more advanced and has HTML5 data- attributes, that I want to send too, but .serialize() doesn't see them.

I tried putting them in <form> tag, <input> tags - nothing works.

What is the best practice to grab them and send with all the form data? I know about .serializeArray(), but how do I get all of the data- attributes that my <form> tag has attached serialized?

Emulous answered 23/8, 2012 at 22:8 Comment(11)
You need to define how you expect these attributes to get serialised. Do you just want data-foo="bar" to get mapped to foo=bar ? Also, is there any reason they can't go into hidden input tags?Schwerin
Since data- attributes can be called anything, you'll also need to specify which ones you want to serialize.Anacardiaceous
Technically - yes, I want to think of an easy way to do this, so that I could do $('#myform').serialize() and the string would have input values and data- attribute values serialized and escaped. It could be a custom function.Emulous
@MikeRobinson all data attributes, if I would want to take only few, I would do it by hardcodingEmulous
It's certainly doable, but there are a lot of questions still. How will you handle duplicate data attributes (e.g. data-id=1, data-id=2) on different elements. Should they be sent as an array, or associated with the name of the input element they were on?Anacardiaceous
@MikeRobinson never heard that it is valid to do so, but in any case, just make the last one overwrite the others. (as an easiest option)Emulous
@Alnitak's idea of using hidden inputs seems like the right approach to me.Onerous
@Onerous it is a really common solution used for years now and that's not what the point of the question is.Emulous
possible duplicate of: #5560793Phthisis
@FrançoisWahl could you please tell me, where do you see the word serialize in the topic you've linked?Emulous
@Vlakarados: As far as I can tell you are trying to post data located in data attributes. You want to serialise them automatically, which as far as a I know is not possibly automatically. The question I linked discusses the problems with posting data-attribute data and indicates hidden fields being in that case the best solution (not a work-around). If you don't like hidden fields, you can apply a work-around by writing your own function to read each data attribute into an object property, then serialise that object and post that along with your form data.Phthisis
E
9

Here's how it can be done. It might not be the best way, but it works the way it should work.

http://jsfiddle.net/Bvzqe/12/

HTML:

<form id="frm" data-id="123" data-list[one]="first" data-list[two]="second">

The serialization:

    var form = $('#frm');
    var dataarr = new Array();
    for(var i in form.data()) {
        var subarr = new Array();
        subarr['name'] = i;
        subarr['value'] = form.data()[i];
        dataarr.push(subarr);
    }
    var serialized = $.param(form.serializeArray().concat(dataarr));

It even allows you to have arrays of data- attributes such as

data-list[one]="first" data-list[two]="second"

URL encoded it may seem wrong, as it escapes square brackets, but I've tested this on the server side - it parses everything exactly as it should.

This is only for those that don't want to use <input type="hidden">

Emulous answered 24/8, 2012 at 9:42 Comment(3)
This works and is the right way to go. I've used this sort of code in a couple of helper methods. A new "serializeDataArray()" jQuery extension and an AJAX post back method which includes three parts... the original form serialize array then serialize data attributes for both form and source/post back control. Not sure what the HTML 5 rules are on this but I think data attributes from both the (more global) form and (contextual) source element are necessary is most cases.Corinnecorinth
Thanks for reminding me you can just use a hidden input lolBorszcz
Hello how to deserilize a JSON to data - attributes the reverse wayNittygritty
S
6

If at all possible you should store your additional values as hidden input fields (one per value) rather than as meta-data on other input fields. They'll then get serialized automatically as part of the form.

I won't write a serializer for you, as I think it's a bad idea. If you insist on sending the values to the browser as data- fields you could do this, though, to convert those data- fields into hidden inputs.

$('#myform:input').each(function() {
    var input = this;
    $.each($(input).data(), function(key, value) {
        $('<input>', {type: hidden, name: key, value: value}).insertAfter(input);
    });
});

Hey presto, hidden input fields that'll be automatically serialized!

Be aware that jQuery also uses .data() to store things like events. To avoid iterating over those objects you'd have to use the native DOM functions to retrieve the data- attributes, and not any data-related properties that have been stored on the elements.

Schwerin answered 23/8, 2012 at 22:24 Comment(15)
Sorry, that just will not do. That is not the answer to my question, that is a workaround.Emulous
@Vlakarados no, putting your data in data- fields is the workaround. Using hidden fields is the standard way of including additional (non-visible) data in a form submission.Schwerin
it is a workaround for my question, rather than solution. I know that it is the standard way, but I asked how to serialize data- attributes not 'how to hide data from displaying on screen'. Hidden inputs were invented only because there were no js back then, no ajax. For a high-load project writing <input type="hidden" name="key" value="value"> instead of ` data-key="value"` is using more bandwidth, greater load times. And I'm not even saying about ease of manipulating such data in JS.Emulous
@Vlakarados yup, that's what I call a work around. You've invented a scheme for storing additional information in the form (because of minor concerns about page load times) that is not supported by W3C <form> tags and then complain when the means to serialise that data doesn't exist?! Hidden fields weren't invented "because there was no AJAX", they were invented because that's how you supply extra information in a form!Schwerin
@Vlakarados and FWIW, I could trivially write what you require - it would be around a dozen lines of code. But IMHO it would not be useful to do so. You are manufacturing a problem of your own making for no good reason.Schwerin
Gotta side with @Schwerin on this, the bandwidth introduced by additional inputs is incredibly trivial. Hidden inputs will also work regardless of whether javascript is enabled (or broken).Anacardiaceous
Ok, guys, I've asked a normal question - "how can I seriealize data attributes". How do you think, are hidden inputs the answer to this question? I also mentioned that I've done a research on this topic and it's not covered anywhere.Emulous
@Vlakarados don't you realise that the reason it's not covered anywhere is because it's not a good idea!Schwerin
@Schwerin I'm sure you've heard of other frameworks like knockout.js, that mostly use data- attributes for even basic things. What if in my current project all frontend system is based on these attributes, should I rewrite everything and use inputs? I see your point, I really do, but I did not ask if it was a good idea or not, I did not ask what other possibilities exist.Emulous
@Vlakarados: Your question was What is the best practice to grab them and send with all the form data?. The answer is hidden fields. But you can apply a work-around and iterate throguh all data-attributes yourself and create an object to send along with your form post. Or use a framework if it exists that does it for you. If you find one, please post it as an answer as it definelty will help others in the future.Phthisis
@Vlakarados sure, there are plenty of uses for data- attributes and properties. Knockout.js uses them, jQuery uses them. Using them to store form data isn't a valid use case for them! The very fact that those frameworks do use them is even more reason for you not to!Schwerin
Thank you for an edit, that's not what I wanted to see, but this IS an answer to my question, so thank you and upvoting of course.Emulous
@Vlakarados you should note that I'm not getting any rep for this - I already hit the daily limit. I'm putting this much effort in because I seriously believe that your current implementation is incorrect.Schwerin
That's why I'm arguing too, I hope you take no offenseEmulous
I have to side the Sergey here. I'm running up against the same challenge right now. Even though using hidden input elements is considered the standard, de facto way of tacking on additional data to a form, the big problem inherent in that method is that one can no longer associate data-* values with a particular form element. That is to say, once serialized, you end up with a flat map whose structure does not represent associations. What I'm probably going to end up doing is to write my own serializer that creates a JSON tree of the form.Undetermined
M
0

here is my func, get all data-* of element + support ignore array

Data2Params: function (el, ignoredAtt) {
    ignoredAtt = typeof ignoredAtt !== 'undefined' ? ignoredAtt : [];

    var data = {};
    for (var key in el.data()) {
        if (ignoredAtt.indexOf(key) === -1)
            data[key] = el.data(key);
    }
    return data;
}
Mississippian answered 1/8, 2018 at 10:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.