Read from serialize to populate form - javascript

I did serialize() on my form and saved the string, is there any function which can populate values back to the form from serialized string?

Here is the updated version of Explosion Pills' answer with the additional suggestions in the comments applied:
$.each(serialized.split('&'), function (index, elem) {
var vals = elem.split('=');
$("[name='" + vals[0] + "']").val(decodeURIComponent(vals[1].replace(/\+/g, ' ')));
});

Check out http://phpjs.org/functions/unserialize:571
I recommend instead of serializing data for communication with javascript, you use JSON. PHP should have json_encode() and json_decode() to help with this, and javascript also has built in JSON handling functions, which you may not even need. For example, if $.getJSON gets a valid JSON string from the server, it will be transformed into a javascript object automatically.
EDIT: assuming you are talking about jQuery's $.serialize(), that I know of there's no function to undo this (I'm not even sure why that would ever be necessary..) but this should work:
$.each(serialized.split('&'), function (index, elem) {
var vals = elem.split('=');
$("[name='" + vals[0] + "']").val(vals[1]);
});

Based on previous answers, if you have checkbox or radio buttons:
$.each(serialized.split('&'), function (index, elem) {
var vals = elem.split('=');
var $elem = $formularioEquipo.find("[name='" + vals[0] + "']");
var value = decodeURIComponent(vals[1].replace(/\+/g, ' '));
if ($elem.is(':radio,:checkbox')) {
$elem.prop('checked', ($elem.val() === value));
} else {
$elem.val(value);
}
});

Related

jQuery command other than appendTo

I am trying to clear an LI tag's previous data.
Is there another command that will work other than appendTo?
Here is what my code currently looks like:
var obj = JSON.parse(data);
$.each(obj, function(index, item)
{
$('<li>').
text(item.datestamp+' - '+item.comment).
appendTo($('#pCodeComment'));
});
I asked a similar question not too long ago. I just want to know if there is another command other than appendTo that will clear out the previous data.
You should empty the list before you loop to populate it, then just continue doing what you are already doing.
var obj = JSON.parse(data);
$('#pCodeComment').empty();
$.each(obj, function(index, item)
{
$('<li>').
text(item.datestamp+' - '+item.comment).
appendTo($('#pCodeComment'));
});
And after optimizing a little bit:
var obj = JSON.parse(data); // i'm assuming `obj` is an array
var htmlToInsert = obj.map(function (item) {
return '<li>' + item.datestamp + ' - ' + item.comment + '</li>';
}).join('');
$('#pCodeComment').html(htmlToInsert);
Note: the above is vulnerable to XSS. See this so question for ways to fix it, or just use the original.
$.replaceWith()
might be what you are looking for, or as Kevin B pointed out
$.html()
replaceWith would need an element selected to replace. whilst html will populate a parent element to insert a new dom fragment into.

Passing string element to data key

I have a function that checks for a div, and if it exists it fills it with the matching data from a JSON array. The Div and the data have the same id & key, so I want to be able to put those in a string for a more elegant solution. However, the final element of trying to apply the string element to the data key doesn't seem to be working. I get "Cannot read property '0' of undefined"
Original code:
$.getJSON('myDataUrl', function(data) {
if ($("#title").length){document.getElementById("title").innerHTML=data.title};
if ($("#noun").length){document.getElementById("noun").innerHTML=data.noun};
if ($("#_id").length){document.getElementById("_id").innerHTML=data._id};
if ($("#owner_id").length){document.getElementById("owner_id").innerHTML=data.owner_id};
});
The more 'elegant' solution I'm trying to reach:
$.getJSON('myDataUrl', function(data) {
var contentString = "name,noun,_id,owner_id";
var splitContent;
splitContent = contentString.split(",");
for(i = 0; i < splitContent.length; i++)
{if ($("#" + splitContent[i]).length){
document.getElementById(splitContent[i]).innerHTML=data.splitContent[i];
};
}
Looks like should be enough:
$.getJSON('myDataUrl', function (data) {
for (var k in data) {
$("#" + k).html(data[k]);
}
});
The problem is data.splitContent[i]. That should be data[splitContent[i]]. That is, you want to use the current key (e.g. name) as a key in the data object.
You could also use jQuery's Map.
$.map(data, function(value, key) {
$("#" + key).html(value);
});
Here's the working JSBin : http://jsbin.com/tocege/2/edit?html,js,output

JS Object values start with 'undefined'

I am trying to use an array as a key value type scenario and it is working with the exception that every value starts with 'undefined'. I believe this is due to the initial assignment being a += operator however I am not sure how to resolve it.
This is the code stripped of a lot of string concats....
var phasehtml = {};
$.each(json, function (i, item) {
phasehtml[item.Phase] += 'item:'+item.ID;
});
Basically I am trying to append the string to the appropriate key....
You can change the code to only append the ID if there's already IDs:
var phasehtml = {};
$.each(json, function (i, item) {
// Use the existing value for the phase, or an empty string that we can append to
var existingValue = (phasehtml.hasOwnProperty(item.Phase) ? phasehtml[item.Phase] : "");
phasehtml[item.Phase] = existingValue + 'item:' + item.ID;
});
That's assuming that you want phasehtml to contain an appended lists of the form "item:1item:2" for each phase.
The array you have posted is empty.
var phasehtml = {};
It seems that is the cause the following statement
phasehtml[item.Phase]
is being evaluated to "undefined".
Hmmm,
got the problem.
In your code you are trying to add with that value which is previously not defined that's why this error is occur.
In your code you have not initialize the variable that you are adding.
So try this:
var phasehtml = {};
$.each(json, function (i, item) {
phasehtml[item.Phase] = "";
phasehtml[item.Phase] += 'item:'+item.ID;
});
In this first assign some value, here is blank and then use that index of array.

jQuery deserialize form

I am using jQuery Serialize to serialize my form elements and would like to deserialize them back. Unfortunately can't find any working jQuery deserializer, any suggestions?
I wrote a version of jQuery.deserialize that supports serialized data generated from the serialize, serializeArray and serializeObject functions. It also supports all form element types, including checkboxes and radio buttons.
Try this:
function deparam(query) {
var pairs, i, keyValuePair, key, value, map = {};
// remove leading question mark if its there
if (query.slice(0, 1) === '?') {
query = query.slice(1);
}
if (query !== '') {
pairs = query.split('&');
for (i = 0; i < pairs.length; i += 1) {
keyValuePair = pairs[i].split('=');
key = decodeURIComponent(keyValuePair[0]);
value = (keyValuePair.length > 1) ? decodeURIComponent(keyValuePair[1]) : undefined;
map[key] = value;
}
}
return map;
}
I was very interested in trying JQuery.deserialize, but it didn't seem to handle checkboxes at all, so it didn't serve my purposes. So I wrote my own. It turned out to be easier than I thought, because the jQuery val() function does most of the work:
jQuery.fn.deserialize = function (data) {
var f = this,
map = {},
find = function (selector) { return f.is("form") ? f.find(selector) : f.filter(selector); };
//Get map of values
jQuery.each(data.split("&"), function () {
var nv = this.split("="),
n = decodeURIComponent(nv[0]),
v = nv.length > 1 ? decodeURIComponent(nv[1]) : null;
if (!(n in map)) {
map[n] = [];
}
map[n].push(v);
})
//Set values for all form elements in the data
jQuery.each(map, function (n, v) {
find("[name='" + n + "']").val(v);
})
//Clear all form elements not in form data
find("input:text,select,textarea").each(function () {
if (!(jQuery(this).attr("name") in map)) {
jQuery(this).val("");
}
})
find("input:checkbox:checked,input:radio:checked").each(function () {
if (!(jQuery(this).attr("name") in map)) {
this.checked = false;
}
})
return this;
};
You should be able to use this like this:
$("#myform").deserialize(data);
Where data is a parameter list such as what $("#myform").serialize() would produce.
It affects all fields in the form, and it will clear the values of fields that are not contained in the data. But you can also pass any selector to affect only specific fields, as you can with the serialize function. E.g.:
$("select").deserialize(data);
Half of jQuery Serialize is param(), so half of something that deserializes a query string is going to be a deparam. Unfortunately I haven't been able to find a good standalone deparam. For now I recommend getting the jQuery BBQ library and using that. If you don't need the other stuff you can remove them. I read somewhere that Ben Alman (cowboy) planned to extract deparam into its own module.
For the rest of deserializing, you'll just need to loop through the object that deparam returns and for each key and value pair in the object, select the form element based on the key, and set the form elements value to the value.
Bit late on this one, but somebody might find this useful.
function fetchInput(identifier) {
var form_data = identifier.serialize().split('&');
var input = {};
$.each(form_data, function(key, value) {
var data = value.split('=');
input[data[0]] = decodeURIComponent(data[1]);
});
return input;
}
I'm not now answering your question but my guess is that you want to serialize it and send back to server and then use the serialized data which is why you have to deserialize it?
If that's the case you should consider using .serializeArray(). You can send it as POST data in ajax, and then access later as well because you will have object.
May be a bit late, but perhaps you are looking for something like JQuery.deserialize. Problems: no support for checkboxes or radio buttons.
Using Jack Allan's deparam function with jQuery, you can change this line:
map[key] = value;
to
$('input[name=' + key + ']').val(value);
Which will load the data back into your form fields.
this code returns an array when same key is spotted multiple times in the serialized string
chaine="single=Single1&multiple=Multiple&multiple=Multiple1&multiple=Multiple2&multiple=Multiple3&check=check2&radio=radio1"
function deserialize(txt){
myjson={}
tabparams=chaine.split('&')
var i=-1;
while (tabparams[++i]){
tabitems=tabparams[i].split('=')
if( myjson[decodeURIComponent(tabitems[0])] !== undefined ){
if( myjson[decodeURIComponent(tabitems[0])] instanceof Array ){
myjson[decodeURIComponent(tabitems[0])].push(decodeURIComponent(tabitems[1]))
}
else{
myjson[decodeURIComponent(tabitems[0])]= [myjson[decodeURIComponent(tabitems[0])],decodeURIComponent(tabitems[1])]
}
}
else{
myjson[decodeURIComponent(tabitems[0])]=decodeURIComponent(tabitems[1]);
}
}
return myjson;
}
Needed all in a single string, which can be stored in maybe COOKIE, and later read and fill the same form with input values.
Input elements seperator: ~ (use any seperator)
Input attributes seperator: | (use any seperator)
input type | input name | input value ~ input2 type | input2 name | input2 value
var formData = '';
$('#form_id').find('input, textarea, select').each(function(i, field) {
formData += field.type+'|'+field.name+'|'+field.value+'~';
});
Example:
hidden|vote_id|10~radio|option_id|~radio|option_id|427~radio|option_id|428~
If what you want is to remove the standard URL-encoded notation, you can use JavaScript's decodeURIComponent(), which will give you a regular string, just like this:
var decodedString = decodeURIComponent("Http%3A%2F%2FHello%3AWorld");
alert(decodedString);
In this case, decodedString will look like Http://Hello:World, here's a working fiddle.
Got all of this searching for this same issue, and found the answer here: How can I decode a URL with jQuery?
I know this is an old question, but doing some searches for jQuery deserialize got me here, so I might as well try to give a different approach on the issue for people with the same problem.

JSON result containing only one item

I'm likely missing something with json and javascript.
[{"commentText":"Testing 123","userPosted":"maxfridbe"},
{"commentText":"Testing 23","userPosted":"maxfridbe"}]
Sometimes I get multiple responses which works with this code:
function(data)
{
var sel = this;
jQuery.each(data,
function()
{
sel.append("<li>"+ this.userPosted+ "-" + this.commentText + "</li>");
});
};
Sometimes I only get one response which breaks the above code:
[{"commentText":"another test again welcom","userPosted":"maxfridbe"}]
I know this is because the response is being treated differently than a list.
Looking for the answer to this I get a bit of a runaround. Any solution would be greatly appreciated.
In the second example you provide, it seems to be an array with only one item, if it's like that, it should work, but I think that you're getting only a single object like:
{"commentText":"another test again welcom","userPosted":"maxfridbe"}
If it's a single object $.each iterates over the object properties.
You could check if your data variable is not an array using $.isArray, and if is not, you can wrap it into a single element array, so the $.each function will still work as expected:
//..
if (!jQuery.isArray(data)) data = [data]; // if isn't an array, wrap it
jQuery.each(data, function() {
sel.append("<li>"+ this.userPosted+ "-" + this.commentText + "</li>");
});
//..
I think you should user some optional parameters in your each() function:
function(data)
{
var sel = this;
jQuery.each(data,
function(i, item)
{
sel.append("<li>"+ item.userPosted+ "-" + item.commentText + "</li>");
});
};
using THIS keyword creates confusion in your case
Hope this helps
Playing around with CMS's solution made me realize that data was just a string somehow so:
if (!jQuery.isArray(data)) data = eval(data);
worked because then the data was an object. Not sure why when there are multiple results it does an eval for you.

Categories