When i click click_profile_list i get error
or Uncaught SyntaxError: Unexpected identifier
function click_profile_list(choice, profileid, i_array) {
if(choice==0) {
alert("Profile", i_array.firstname);
}
else {
alert("Profile 2" , i_array.firstname);
}
}
for(var key in msg.db) {
var bypass = {
firstname: msg.db[key].firstname,
lastname: msg.db[key].lastname,
email: msg.db[key].user_email,
};
//html = '<div class="rows" onclick=click_profile_list(' + input + ',' + msg.db[key].id + ',' + bypass + ');>' ;
html = '<div class="rows" onclick="click_profile_list(' + input + ',' + msg.db[key].id + ',' + bypass + ');">' ;
html += msg.db[key].id + ' - ';
html += msg.db[key].firstname + ' - ';
html += msg.db[key].lastname + ' - ';
html += msg.db[key].fallback;
html += '</div>' ;
$('#show_list_window_body').append(html);
}
EDIT: , is removed, onclick="function();" added
$('#show_list_window_body').html(html);
for(var key in msg.db) {
var bypass = {
firstname: msg.db[key].firstname,
lastname: msg.db[key].lastname,
email: msg.db[key].user_email
};
var tmp_id = 'iDontKnow' + msg.db[key].id;
html = '<div class="rows" id="' + tmp_id + '">' ;
html += msg.db[key].id + ' - ';
html += msg.db[key].firstname + ' - ';
html += msg.db[key].lastname;
html += '</div>' ;
$('#show_list_window_body').append(html);
let $elem = $("<div class='rows' id='" + tmp_id + "'>");
$elem.click( () => click_profile_list(input, msg.db[key].id, bypass) );
}
Remove the extra comma at the end of your object :
var bypass = {
firstname: msg.db[key].firstname,
lastname: msg.db[key].lastname,
email: msg.db[key].user_email, // <-- Remove this comma
};
Then, add double quotes around your onclick function :
html = '<div class="rows" onclick="click_profile_list(' + input + ',' + msg.db[key].id + ',' + bypass + ');">'
Or (much) better, attach a click handler instead of inline javascript :
let $elem = $("<div class='rows'>")
$elem.click( () => click_profile_list(input, msg.db[key].id, bypass) )
let $clickme = $("<div>Click me!</div>")
$clickme.click(() => alert("it works!"))
$("#main").append($clickme)
#main * {
font-size: x-large;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main"></div>
Here's a proper jQuery solution:
const msg = {};
msg.db = {
alice: {
firstname: "Alice",
lastname: "Bob",
user_email: "alice#bob.com",
id: 1,
fallback: "fallback"
},
charlie: {
firstname: "Charlie",
lastname: "Delta",
user_email: "charlie#delta.com",
id: 2,
fallback: "fallback2"
}
};
function click_profile_list(e) {
$el = $(e.target);
var choice = 0; // get from whatever sets this
var user = msg.db[$el.data("key")];
if (choice == 0) {
alert(user.firstname);
}
}
var input = 0;
for (var key in msg.db) {
var user = msg.db[key];
$user = $("<div>").addClass("rows").data("key", key);
$user.text([user.id, user.firstname, user.lastname, user.fallback].join(" - "));
$('#show_list_window_body').append($user);
}
$('#show_list_window_body').on("click", ".rows", click_profile_list);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="show_list_window_body"></div>
The list doesn't get awkward inline onclick code that tries to pass an object; instead each list item gets a data-key attribute referencing the database key. When clicked, the key is read back; this is used to grab the relevant data from the db.
You have two syntactical mistakes. One in your JavaScript and one in the HTML markup you produce.
JS
var bypass = {
firstname: msg.db[key].firstname,
lastname: msg.db[key].lastname,
email: msg.db[key].user_email, // <--- here is your issue, you should not use a comma after the last object element
};
HTML
html = '<div class="rows" onclick=click_profile_list(' + input + ',' + msg.db[key].id + ',' + bypass + ');>' ;
You must wrap the value of the attribute onclick with single or double quotes. In your code, just wrap it with double quotes onclick="...;"
Look #Jeremy Thille's answer for a better way to do this.
Related
Currently I'm using checkmarx to find vulnerabilities on mi code.
The javascript files aparently haev some potential xss vulnerabilites when I use jquery val() function and then try to append this val. How should I solve, sanitize or encode this to avoid this problem?
Here some examples about what checkmarx mark as vulnerability:
function insertContactToTable(table) {
var ContactId = jQuery("#select_contacts").val();
var ContactName = jQuery("#select_contacts option:selected").text();
var Type = jQuery("#select_contact_type").val();
if (ContactId != "" && Type != "") {
var ID = ContactId + "_" + Type;
var Img = "<img class='image pointer-item' src='/app/assets/img/icon-package/cross.png' alt='cross' onClick='removeTableLine(\"" + ID + "\")'/>";
if (jQuery("#" + table + " tbody tr:last").length > 0) {
jQuery("#" + table + " tbody tr:last").after("<tr id='" + ID + "' name='" + ID + "'><td id='" + ID + "' name='contact_list'>" + ContactName + "</td><td>" + Type + "</td><td>" + Img + "</td></tr>");
} else {
jQuery("#" + table + " tbody").html("<tr id='" + ID + "' name='" + ID + "'><td id='" + ID + "' name='contact_list'>" + ContactName + "</td><td>" + Type + "</td><td>" + Img + "</td></tr>");
}
}
...
It marks the following error:
The application's insertContactToTable embeds untrusted data in the generated output with after, at line 542 of app\assets\js\administration.js. This untrusted data is embedded straight into the output without proper sanitization or encoding, enabling an attacker to inject malicious code into the output.
The line 542 is the jQuery("#select_contacts").val(); but it happens the same with the others lines that use .val() and .text() function.
Also, on other functions happens the same while getting this .val() or .text() functions and trying to use them with append() or html() functions.
Finally, I also have same issue while getting ajax response and try to append it with append() o html().
Note: I'm using php on my project, sanitizing most of the variables with it.
Edit
I changed to DOM object as suggested in comments and the code now looks like this:
var ContactId = jQuery("#select_contacts").val();
var ContactName = jQuery("#select_contacts option:selected").text();
var Type = jQuery("#select_contact_type").val();
if (ContactId != "" && Type != "") {
var ID = ContactId + "_" + Type;
var Img = jQuery("<img>", { "class": 'image pointer-item', alt: 'cross', "src": '/app/assets/img/icon-package/cross.png'
}).on("click", function() {
removeTableLine(ID);
});
var row = $("<tr>", { id:"TR_" +ID , name: ID })
.append($("<td>", { id: ID, name: 'contact_list', text: ContactName }))
.append($("<td>", { text: Type }))
.append($("<td>").append(Img));
$("#" + table + " tbody").append(row);
}
but I still have the problem
Don't create a string of HTML, create a DOM object and set its attributes.
if (ContactId != "" && Type != "") {
var ID = ContactId + "_" + Type;
var Img = jQuery("<img>", {
"class": 'image pointer-item',
alt: 'cross'
}).click(function() {
removeTableLine(ID);
});
var row = $("<tr>", {
id: ID,
name: ID
})
.append($("<td>", {
id: ID,
name: 'contact_list',
text: ContactName
}))
.append($("<td>").append(Img))
$("#" + table + " tbody").append(row);
}
You don't need different code depending on whether there's already a last row or not. Just append the new row to the table body.
You have another problem, you're using the same ID for the <tr> and first <td> in the row. If you really need them both to have an ID, they should have different IDs.
Use the DOMPurify library to sanitize the val() and text() return values before .append-ing it to the DOM
var ContactId = DOMPurify.sanitize(jQuery("#select_contacts").val());
var ContactName = DOMPurify.sanitize(jQuery("#select_contacts option:selected").text());
var Type = DOMPurify.sanitize(jQuery("#select_contact_type").val());
if (ContactId != "" && Type != "") {
var ID = ContactId + "_" + Type;
var Img = jQuery("<img>", { "class": 'image pointer-item', alt: 'cross', "src": '/app/assets/img/icon-package/cross.png'
}).on("click", function() {
removeTableLine(ID);
});
var row = $("<tr>", { id:"TR_" +ID , name: ID })
.append($("<td>", { id: ID, name: 'contact_list', text: ContactName }))
.append($("<td>", { text: Type }))
.append($("<td>").append(Img));
$("#" + table + " tbody").append(row);
}
If there are attributes or tags you want to be allowed, you can pass a second parameter to the sanitize function to define that whitelist:
// allow only <b> and <q> with style attributes
var clean = DOMPurify.sanitize(dirty, {ALLOWED_TAGS: ['b', 'q'], ALLOWED_ATTR: ['style']});
I am attempting to build a 9 divs (cards) dynamically containing information about store branch locations. Each card has a unique URL associated with it that links to each branches specific URL.
This approach, within the function, appends the first (0) URL to all the cards:
$("div").click(function() {
window.location = $(this).find("a").attr("href");
return false;
});
This approach appends the last URL (8) to all the cards:
branch.addEventListener("click", function(e){
e.preventDefault();
window.open(prop.pages_url);
})
Code I'm working with:
function buildLocationList(data) {
for (i = 0; i < 9; i++) {
var currentFeature = data.features[i];
var prop = currentFeature.properties;
//Create Card
var branches = document.getElementById('branches');
var url = branches.appendChild(document.createElement('a');
url.setAttribute('href', prop.pages_url);
)
var branch = branches.appendChild(document.createElement('div'));
branch.className = 'card';
branch.id = "branch-" + i;
branch.url = prop.pages_url;
branch.addEventListener("click", function(e){
e.preventDefault();
window.open(prop.pages_url);
})
//Append Branch Card Details
v
var company = branch.appendChild(document.createElement('h5'));
company.innerHTML = prop.name + '<br />';
var distancePhone = branch.appendChild(document.createElement('p'));
if (prop.distance) {
var roundedDistance = Math.round(prop.distance * 100) / 100;
distancePhone.innerHTML = '<span class="miles">Approx. ' + roundedDistance + ' miles</span>' + '<span class="location-phone">' + prop.phone_number + '</span>';
}
else {
distancePhone.innerHTML = prop.phone_number;
}
var address = branch.appendChild(document.createElement('p'));
if (prop.address_line_2) {
address.innerHTML += prop.address_line_1 + ', ' + prop.address_line_2 + '<br />';
}
else {
address.innerHTML += prop.address_line_1 + '<br />';
};
address.innerHTML += prop.address_city + ', ' + prop.address_state + ' ' +prop.address_postal_code + '</p>';
}
}
I would like the card to be clickable with a redirect to each branch's unique URL.
You're storing the URL on the card element:
branch.url = prop.pages_url
All you need to do in the click handler is access the property:
branch.addEventListener("click", function(e){
e.preventDefault();
window.open(e.currentTarget.url);
})
In the context of the event handler, e.currentTarget is the element to which the handler is attached. If you were interested in which element fired the event, you'd use e.target.
Here's your code snippet modified below. I don't think the links will open on here though due to the sandboxed iframe.
function buildLocationList(data) {
for (i = 0; i < data.features.length; i++) {
var currentFeature = data.features[i];
var prop = currentFeature.properties;
//Create Card
var branches = document.getElementById('branches');
var url = branches.appendChild(document.createElement('a'));
url.setAttribute('href', prop.pages_url);
var branch = branches.appendChild(document.createElement('div'));
branch.className = 'card';
branch.id = "branch-" + i;
branch.url = prop.pages_url;
branch.addEventListener("click", function(e){
e.preventDefault();
console.log(e.currentTarget.url);
window.open(e.currentTarget.url);
})
//Append Branch Card Details
var company = branch.appendChild(document.createElement('h5'));
company.innerHTML = prop.name + '<br />';
var distancePhone = branch.appendChild(document.createElement('p'));
if (prop.distance) {
var roundedDistance = Math.round(prop.distance * 100) / 100;
distancePhone.innerHTML = '<span class="miles">Approx. ' + roundedDistance + ' miles</span>' + '<span class="location-phone">' + prop.phone_number + '</span>';
}
else {
distancePhone.innerHTML = prop.phone_number;
}
var address = branch.appendChild(document.createElement('p'));
if (prop.address_line_2) {
address.innerHTML += prop.address_line_1 + ', ' + prop.address_line_2 + '<br />';
}
else {
address.innerHTML += prop.address_line_1 + '<br />';
};
address.innerHTML += prop.address_city + ', ' + prop.address_state + ' ' +prop.address_postal_code + '</p>';
}
}
buildLocationList({features:[{
properties: {
distance: 100,
name: 'Google',
pages_url: 'https://www.google.com',
phone_number: '123-456-7890',
address_line_1: '1234 Street',
address_city: 'Citytown',
address_state: 'State',
address_postal_code: '12345'
}
},{
properties: {
distance: 200,
name: 'Microsoft',
pages_url: 'https://www.microsoft.com',
phone_number: '123-456-7890',
address_line_1: '1234 Street',
address_city: 'Citytown',
address_state: 'State',
address_postal_code: '12345'
}
}]})
.card {
border: 1px solid #ccc;
padding: 10px;
max-width: 50%;
margin: 10px;
}
<div id="branches"></div>
<div>
w3schools
</div>
<script>
$("div").click(function() {
window.location = $(this).find("a").data("value");
});
</script>
I'm trying to do the next thing:
getChatListMessageString: function(dateObject, userID, userName, userRole, messageID, messageText, channelID, ip) {
var rowClass = this.DOMbufferRowClass,
userClass = this.getRoleClass(userRole),
colon = ': ';
if(messageText.indexOf('/action') === 0 || messageText.indexOf('/me') === 0 || messageText.indexOf('/privaction') === 0) {
userClass += ' action';
colon = ' ';
}
if (messageText.indexOf('/privmsg') === 0 || messageText.indexOf('/privmsgto') === 0 || messageText.indexOf('/privaction') === 0) {
rowClass += ' private';
}
var dateTime = this.settings['dateFormat'] ? '<span class="dateTime">'
+ this.formatDate(this.settings['dateFormat'], dateObject) + '</span> ' : '';
return '<div id="'
+ this.getMessageDocumentID(messageID)
+ '" class="'
+ rowClass
+ '">'
+ this.getDeletionLink(messageID, userID, userRole, channelID)
+ dateTime
//start of the code i added
+ '<a href="http://hostname.x/report_chat.php?usernameR='
+ userName
+ '/&useridR='
+ userID
+ '">'
+ '<img src="img/excl.png"></img></a>'
// end of the code i added
+ '<a href="http://www.hostname.x/'
+ userID
+ '" target="_blank"'
+ this.getChatListUserNameTitle(userID, userName, userRole, ip)
+ ' dir="'
+ this.baseDirection
+ '" onclick="ajaxChat.insertText(this.firstChild.nodeValue);">'
+ userName
+ '</a>'
+ colon
+ this.replaceText(messageText)
+ '</div>';
},
If I remove the portion that I added , the page works just fine. When I add it back , I get an Aw Snap error(cache reloaded -> incognito mode )
I'm pretty new with javascript so I can't really tell what I did wrong.
Thank you!
EDIT: THE AW SNAP ERROR comes from the <img> tag for whatever reason.
//Here a simple test
var Obj = (function(){
return{
DOMbufferRowClass : 'DOMbufferRowClass',
getRoleClass : function()
{
return 'roleClass';
},
settings : '',
getMessageDocumentID : function(){
return '123';
},
getDeletionLink : function(messageID, userID, userRole, channelID)
{
return 'DeletiongLink'
},
replaceText : function()
{
},
getChatListMessageString : function(dateObject, userID, userName, userRole, messageID, messageText, channelID, ip) {
var rowClass = this.DOMbufferRowClass,
userClass = this.getRoleClass(userRole),
colon = ': ';
if(messageText.indexOf('/action') === 0 || messageText.indexOf('/me') === 0 || messageText.indexOf('/privaction') === 0) {
userClass += ' action';
colon = ' ';
}
if (messageText.indexOf('/privmsg') === 0 || messageText.indexOf('/privmsgto') === 0 || messageText.indexOf('/privaction') === 0) {
rowClass += ' private';
}
var dateTime = this.settings['dateFormat'] ? '<span class="dateTime">'
+ this.formatDate(this.settings['dateFormat'], dateObject) + '</span> ' : '';
return `<div id="${this.getMessageDocumentID(messageID)}" class="${rowClass}">
${this.getDeletionLink(messageID, userID, userRole, channelID)} ${dateTime}
<a href="http://hostname.x/report_chat.php?usernameR='${userName}/&useridR=${userID}">
<img src="img/excl.png"/></a><a href="http://www.hostname.x/${userID} target="_blank"
this.getChatListUserNameTitle(userID, userName, userRole, ip) dir="{this.baseDirection}
onclick="ajaxChat.insertText(this.firstChild.nodeValue);">${userName}</a>${colon}${this.replaceText(messageText)}</div>`;
}
};
})();
console.log(Obj.getChatListMessageString("05102017", '1234',"admin", '456', 'Test','11', '127.0.0.1'));
I would simplify your code with template literals and avoiding all the concatenation mess.
getChatListMessageString : function(dateObject, userID, userName, userRole, messageID, messageText, channelID, ip) {
var rowClass = this.DOMbufferRowClass,
userClass = this.getRoleClass(userRole),
colon = ': ';
if(messageText.indexOf('/action') === 0 || messageText.indexOf('/me') === 0 || messageText.indexOf('/privaction') === 0) {
userClass += ' action';
colon = ' ';
}
if (messageText.indexOf('/privmsg') === 0 || messageText.indexOf('/privmsgto') === 0 || messageText.indexOf('/privaction') === 0) {
rowClass += ' private';
}
var dateTime = this.settings['dateFormat'] ? '<span class="dateTime">'
+ this.formatDate(this.settings['dateFormat'], dateObject) + '</span> ' : '';
return `<div id="${this.getMessageDocumentID(messageID)}" class="${rowClass}">
${this.getDeletionLink(messageID, userID, userRole, channelID)} ${dateTime}
<a href="http://hostname.x/report_chat.php?usernameR='${userName}/&useridR=${userID}">
<img src="img/excl.png"/></a><a href="http://www.hostname.x/${userID} target="_blank"
this.getChatListUserNameTitle(userID, userName, userRole, ip) dir="{this.baseDirection}
onclick="ajaxChat.insertText(this.firstChild.nodeValue);">${userName}</a>${colon}${this.replaceText(messageText)}</div>`;
}
Ouch! The best approach is not to build your HTML elements in this manner in the first place and use the DOM to construct and inject them into your document.
This makes the code MUCH easier to read and modify and removes the concatenation issue entirely.
Now, if you have errors, you can focus on the values your are assigning to the properties and not the syntax of the HTML.
// Create the div element in memeory
var div = document.createElement("div");
// Configure the attributes of that div
div.id = this.getMessageDocumentID(messageID);
div.classList.add(rowClass);
// Now, begin populating the div
div.innerHTML = this.getDeletionLink(messageID, userID, userRole, channelID) + dateTime;
// A new element belongs inside the div. Repeat the process:
var a1 = document.createElement(a);
a1.href = "http://hostname.x/report_chat.php?usernameR=" + userName + "/&useridR=" + userID;
var img = document.createElement("img");
img.src = "img/excl.png";
// Place the image into the anchor
a1.appendChild(img);
// Place the anchor into the div
div.appendChild(a1);
// Another anchor is now needed
var a2 = document.createElement(a);
a2.href = "http://www.hostname.x/" + userID;
a2.target = "_blank";
// It is unclear what the following line is based on the fact that whatever it returns, you have that
// being inserted where attributes go. It is commented here for that reason.
//this.getChatListUserNameTitle(userID, userName, userRole, ip) + " dir='" + this.baseDirection;
// Set up event handler for the anchor
a2.addEventListener("click", function(){
ajaxChat.insertText(this.firstChild.nodeValue);
});
// Populate the anchor
a2.innerHTML = userName;
// Insert this anchor into the div
div.appendChild(a2);
// Insert the final contents into the div
div.innerHTML += colon + this.replaceText(messageText);
// Return the final construct
return div;
Basically, I'm using JavaScript to dynamically generate a form that allows from multiple entries within a single submission. Here's the code I'm using for that:
function addEvent()
{
var ni = document.getElementById('myDiv');
var numi = document.getElementById('theValue');
var num = (document.getElementById('theValue').value - 1) + 2;
numi.value = num;
var divIdName = 'my' + num + 'Div';
var newdiv = document.createElement('div');
newdiv.setAttribute('id', divIdName);
newdiv.innerHTML = '<table id="style" style="background-color: #ffffff;"><tr><td colspan="2">Entry ' + num + '<hr \/><\/td><\/tr><tr><td><label>Item 1: <\/td><td><input name="item1_' + num + '" value="" type="text" id="item1" \/><\/label><\/td><\/tr><tr><td><label>Item 2: <\/td><td><input name="item2_' + num + '" type="text" id="item2" \/><\/label><\/td><\/tr><tr><td><label>Item 3: <\/td><td><input type="text" name="item3_' + num + '" id="item3" \/><\/label><\/td><\/tr><tr><td><label>Item 4: <\/td><td><select name="item4_' + num + '" id="item4"><option value="---">---<\/option><option value="opt_1">1<\/option><option value="opt_2">2<\/option><option value="opt_3">3<\/option><option value="opt_4">4<\/option><\/select><\/label><\/td><\/tr><\/table>';
ni.appendChild(newdiv);
}
This works just fine, generating the entries fields I need. Using console in-browser, I've even verified all the names are correct. The issue is that I need to then take the selections and generate output. I've tried several methods, but everything resulted in null values.
function generateVideo()
{
var entries = document.getElementById('theValue').value;
var item1 = {};
var item2 = {};
var item3 = {};
var item4 = {};
for(i = 1; i <= entries; i++)
{
item1[i - 1] = document.getElementById('item1_' + i);
item2[i - 1] = document.getElementById('item2_' + i);
item3[i - 1] = document.getElementById('item3_' + i);
item4[i - 1] = document.getElementById('item4_' + i);
}
var code = 'Copy code and paste it into Notepad<br \/>"Save as" filename.html<br \/><textarea name="" cols="45" rows="34">header template\n';
for(i = 0; i < entries; i++)
{
if(i != (entries - 1))
{
code = code + ' ["' + item1[i] + '", "' + item2[i] + '", "' + item3[i] + '", "' + item4[i] + '"],\n';
}
else
{
code = code + ' ["' + item1[i] + '", "' + item2[i] + '", "' + item3[i] + '", "' + item4[i] + '"]\n';
}
}
code = code + 'footer template<\/textarea>';
var result = document.getElementById("result");
result.innerHTML = code;
}
The output is as follows:
Copy code and paste it into Notepad<br />"Save as" CourseName_Unit_Chapter.html<br /><textarea name="" cols="45" rows="34">header template
["null", "null", "null", "null"]
footer template</textarea>
Now, certain fields can be null, that's fine (I'll do form validation after I get it working), but I'm getting null for every field regardless of what is entered.
I, originally, had the .value on the getElementByIds, but that only results in the script not running when the entries variable is greater than 0 (default), which is why I tried removing them.
function generateVideo()
{
var entries = document.getElementById('theValue').value;
var item1 = {};
var item2 = {};
var item3 = {};
var item4 = {};
for(i = 1; i <= entries; i++)
{
item1[i - 1] = document.getElementById('item1_' + i).value;
item2[i - 1] = document.getElementById('item2_' + i).value;
item3[i - 1] = document.getElementById('item3_' + i).value;
item4[i - 1] = document.getElementById('item4_' + i).value;
}
var code = 'Copy code and paste it into Notepad<br \/>"Save as" filename.html<br \/><textarea name="" cols="45" rows="34">header template\n';
for(i = 0; i < entries; i++)
{
if(i != (entries - 1))
{
code = code + ' ["' + item1[i] + '", "' + item2[i] + '", "' + item3[i] + '", "' + item4[i] + '"],\n';
}
else
{
code = code + ' ["' + item1[i] + '", "' + item2[i] + '", "' + item3[i] + '", "' + item4[i] + '"]\n';
}
}
code = code + 'footer template<\/textarea>';
var result = document.getElementById("result");
result.innerHTML = code;
}
I've also tried variations of multidimensional arrays, instead of four arrays, but got the same results.
The output, as indicated by the removal of the .value on the getElementByIds, is good. Basically, there is something wrong with my attempts to populate the arrays using the dynamically generated forms.
I suspect that the issue with the declaration of the element ID, but I'm not sure how else to declare it. This style of scripting is not my norm. ^^'
Anyone have any ideas on how to fix the for loop to generate the array?
replace all occurences of
itemN[i]
with
itemN[i].value
if that doesnt work add
console.log( itemN[i] )
and see what it outputs
Is this the optimal way to load form data into a string and then to localStorage ?
I came up with this on my own, and I am not good in programming. It works, for what I need, but I am not sure if it's a bulletproof code?
<script>
var sg = document.getElementById("selectedGateway");
var sd = document.getElementById("selectedDestination");
var dm = document.getElementById("departureMonth");
var dd = document.getElementById("departureDay");
var dy = document.getElementById("departureYear");
var rm = document.getElementById("returnMonth");
var rd = document.getElementById("returnDay");
var ry = document.getElementById("returnYear");
var ad = document.getElementById("adults");
var ch = document.getElementById("option2");
$("#searchRequestForm").submit(function() {
var string = 'From: ' + sg.value + ' \nTo: ' + sd.value + ' \nDeparture: ' + dm.value + '/' + dd.value + '/' + dy.value + ' \nReturn: ' + rm.value + '/' + rd.value + '/' + ry.value + ' \nNumber of adults: ' + ad.value + ' \nNumber of children: ' + ch.value;
localStorage.setItem("string", string);
});
</script>
I would use something like the following so that I could deal with an object and its properties rather than a big string. Note that other than the jQuery selectors, this is pure JavaScript.
Demo: http://jsfiddle.net/grTWc/1/
var data = {
sg: $("#selectedGateway").val(),
sd: $("#selectedDestination").val()
// items here
};
localStorage.setItem("mykey", JSON.stringify(data));
To retrieve the data:
var data = JSON.parse(localStorage["mykey"]);
alert(data.sg);
See Also:
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/stringify
http://api.jquery.com/jQuery.parseJSON/
I prefer a table driven approach so there is no repeated code (DRY):
var ids = [
"selectedGateway", "From: ",
"selectedDestination", "\nTo :",
"departureMonth", "\nDeparture: ",
"departureDay", "/",
"departureYear", "/",
"returnMonth", " \nReturn: ",
"returnDay", "/",
"returnYear", "/",
"adults", " \nNumber of adults: ",
"option2", " \nNumber of children: "];
var submitStr = "";
for (var i = 0; i < ids.length; i+=2) {
submitStr += ids[i+1] + document.getElementById(ids[i]).value;
}
localStorage.setItem("string", submitStr);
You could define a function such as the one below to directly get the values by id so then it would be simpler when you build your string.
function form(id) {
return document.getElementById(id).value;
}