Why can't jQuery update array data before ajax post? - javascript

I am trying to create an array and get all values of a form submission and put them in that array. I need to do this because during the .each function of this code I must do additional encryption to all the values per client. This is a form with hundreds of fields that are changing. So it must be an array to work. I tried to do following and several other types like it in jQuery but no dice. Can anyone help? Thanks.
Edit: Posted my working solution. Thanks for the help.
Edit 2: Accept sabithpocker's answer as it allowed me to keep my key names.

var inputArray = {};
//jQuery(this).serializeArray() = [{name: "field1", value:"val1"}, {name:field2...}...]
jQuery(this).serializeArray().each(function(index, value) {
inputArray[value.name] = encrypt(value.value);
});
//now inputArray = [{name: "field1", value:"ENCRYPTED_val1"}, {name:field2...}...]
//now to form the POST message
postMessages = [];
$(inputArray).each(function(i,v){
postMessages.push(v.name + "=" + v.value);
});
postMessage = postMessages.join('&');
Chack serializeArray() to see the JSON array format.
http://jsfiddle.net/kv9U3/
So clearly the issue is that this in your case is not the array as you suppose. Please clarify what this pointer refers to, or just verify yourselves by doing a console.log(this)
As you updated your answer, in your case this pointer refers to the form you submitted, how do you want to iterate over the form? what are you trying to achieve with the each?
UPDATE
working fiddle with capitalizing instead of encrypting
http://jsfiddle.net/kv9U3/6/
$('#x').submit(function (e) {
e.preventDefault();
var inputArray = [];
console.log(jQuery(this).serializeArray());
jQuery(jQuery(this).serializeArray()).each(function (index, value) {
item = {};
item[value.name] = value.value.toUpperCase();
inputArray[index] = item;
});
console.log(inputArray);
postMessages = [];
$(inputArray).each(function (i, v) {
for(var k in v)
postMessages[i] = k + "=" + v[k];
console.log(i, v);
});
postMessage = postMessages.join('&');
console.log(postMessage);
return false;
});

The problem is that #cja_form won't list its fields using each. You can use serialize() instead:
inputArray = jQuery(this).serialize();
Further edition, if you need to edit each element, you can use this:
var input = {};
$(this).find('input, select, textarea').each(function(){
var element = $(this);
input[element.attr('name')] = element.val();
});
Full code
jQuery(document).ready(function($){
$("#cja_form").submit(function(event){
$("#submitapp").attr("disabled","disabled");
$("#cja_status").html('<div class="cja_pending">Please wait while we process your application.</div>');
var input = {};
$(this).find('input, select, textarea').each(function(){
var element = $(this);
input[element.attr('name')] = element.val();
});
$.post('../wp-content/plugins/coffey-jobapp/processes/public-form.php', input)
.success(function(result){
if (result.indexOf("success") === -1) {
$("#submitapp").removeAttr('disabled');
$("#cja_status").html('<div class="cja_fail">'+result+'</div>');
}
else {
page = document.URL;
if (page.indexOf('?') === -1) {
window.location = page + '?action=success';
}
else {
window.location = page + '&action=success';
}
}
})
.error(function(){
$("#submitapp").removeAttr('disabled');
$("#cja_status").html('<div class="cja_fail"><strong>Failed to submit article! Check your internet connection.</strong></div>');
});
event.preventDefault();
event.returnValue = false;
return false;
});
});
Original answer:
There are no associative arrays in javascript, you need a hash/object:
var input = {};
jQuery(this).each(function(k, v){
input[k] = v;
});

Here is my working solution. In this example it adds cat to all the entries and then sends it to the PHP page as an array. From there I access my array via $_POST['data']. I found this solution on http://blog.johnryding.com/post/1548511993/how-to-submit-javascript-arrays-through-jquery-ajax-call
jQuery(document).ready(function () {
jQuery("#cja_form").submit(function(event){
jQuery("#submitapp").attr("disabled","disabled");
jQuery("#cja_status").html('<div class="cja_pending">Please wait while we process your application.</div>');
var data = [];
jQuery.each(jQuery(this).serializeArray(), function(index, value) {
data[index] = value.value + "cat";
});
jQuery.post('../wp-content/plugins/coffey-jobapp/processes/public-form.php', {'data[]': data})
.success(function(result){
if (result.indexOf("success") === -1) {
jQuery("#submitapp").removeAttr('disabled');
jQuery("#cja_status").html('<div class="cja_fail">'+result+'</div>');
} else {
page = document.URL;
if(page.indexOf('?') === -1) {
window.location = page+'?action=success';
} else {
window.location = page+'&action=success';
}
}
})
.error(function(){
jQuery("#submitapp").removeAttr('disabled');
jQuery("#cja_status").html('<div class="cja_fail"><strong>Failed to submit article! Check your internet connection.</strong></div>');
});
event.preventDefault();
event.returnValue = false;
});
});

Related

jQuery check multiple CSV lists

To simplify my problem i rewrote the code without the parsing of CSV, but instead with a variable that holds the data.
--CODE EDIT---
$(document).ready(function() {
var qID = 'xxx';
var source = ['text1', 'text2', 'etc3'];
var source2 = ['text4', 'text5', 'etc6'];
$('#question' + qID + ' input[type="text"]').change(function() {
var validVal = 0;
var inputVal = $(this).val();
// Loop through the text and test the input value
$(source).each(function(i) {
if (inputVal == this) { // If a match is found...
validVal = 1;
}
});
// If a valid text was entered
if (validVal == 1) { // A valid input
alert("GOOD");
} else { // An invalid input
alert("NOT GOOD");
}
var validVal2 = 0;
var inputVal2 = $(this).val();
$(source2).each(function(j) {
if (inputVal2 == this) { // If a match is found...
validVal2 = 1;
}
});
// If a valid text was entered
if (validVal2 == 1) { // A valid input
alert("GOOD2");
} else { // An invalid input
alert("NOT GOOD2");
}
});
});
The script works fine for one source (var source) but i want to check in the same text field 2 variables (source, source2) that will produce different alerts.
The script is run through a limesurvey form and the input is a simple [type="text"] field.
How do I check for 2 different arrays of text in the same text field?
Whenever you find yourself putting counters on variable names to create a series, you need to stop and think about what you are actually doing there. Making counted variable names is always wrong.
Use arrays.
var qID = 'xxx';
var source = [];
source.push(['text1', 'text2', 'etc']);
source.push(['text1', 'text2', 'etc44']);
source.push(['text15', 'text25', 'etc454']);
$('#question' + qID + ' input[type="text"]').change(function() {
var valid = false;
var inputVal = $(this).val();
$.each(source, function(i, terms) {
$.each(terms, function(i, term) {
valid = inputVal === term;
return !valid; // returning false stops the .each() loop
});
return !valid;
});
if (valid) {
alert("GOOD");
} else {
alert("NOT GOOD");
}
});
A more appealing way to express the nested loop above uses built-in methods of Array.
var valid = source.some(function (terms) {
return terms.includes(inputVal);
});
in ES6 syntax this can be made a one-liner:
var valid = source.some(terms => terms.includes(inputVal));

Can't update javaScript global variable

Here I have global variable userId, and i want to update it inside signInUserFunction(), to use is in other function. I have tried to define it using var, window, But all these didn't help. This variable doesn't update. As i see its about AJAX async. So, what can i do with it?
And yes, I know that its not good to make authentication with JS, I am quite new to it. So, I am just creating random methods to improve.
var userId = 1;
function signInUser() {
$.getJSON('http://localhost:8887/JAXRSService/webresources/generic/getAllUsers', function(data) {
var items = [];
var i = 0;
$.each(data, function(firstname, value) {
var str = JSON.stringify(value);
data = JSON.parse(str);
var innerId;
for (p in data) {
innerId = data[p].id;
if ($('#nameSignIn').val() == data[p].first_name && $('#passwordSignIn').val() == data[p].password) { //
userId = innerId;
window.location.href = "content.html";
break;
} else {
i++;
if (i == data.length) {
alert("Ощибка в логине или пароле!")
}
}
}
});
});
}
How are you determining whether or not it has been set? It looks like immediately after you set it, you navigate to a different page. When you get to that page, you will have an entirely new window.
Try alerting the value before navigating away.
EDITED: Here is how you could pass it to the other page (but you shouldn't do this in a real app)
window.userId=innerId;
alert(window.userId);
//this isn't a very secure way to do this. I DON'T recommend this
window.location.href = "content.html?id=" + innerId ;
Then in the other page, you could access it off the document.location:
alert(document.location.toString().split("?id=")[1]);
After reading my comments, you may want to try this:
var userId = 1;
function signInUser(){
$.getJSON('http://localhost:8887/JAXRSService/webresources/generic/getAllUsers', function(data){
var items = [], actors = data.Actors, l = 0;
$.each(actors, function(i, o){
l++;
if($('#nameSignIn').val() === o.first_name && $('#passwordSignIn').val() === o.password){
userId = o.id;
// this will redirect before any other code runs -> location = 'content.html';
if(l === actors.length){
alert('End of Loop');
}
}
});
});
}
signInUser();
I would not store sensitive data in JSON such as passwords. Use a database. There is no need to get all the data at the same time either.
Using the idea #mcgraphix proposed (and giving you the same warning...this would certainly not be the way to transfer data like this in a production environment), here is one way to do it:
function signInUser() {
var url = 'http://localhost:8887/JAXRSService/webresources/generic/getAllUsers';
var userId;
$.getJSON(url, function(data) {
$.each(data.Actors, function(index, actor) {
// Cache the values of the #nameSignIn and #passwordSignIn elements
var name = $('#nameSignIn').val();
var password = $('#passwordSignIn').val();
if (actor.first_name === name && actor.password === password) {
// We have found the correct actor.
// Extract its ID and assign it to userId.
userId = actor.id;
window.location.href = "content.html?userId=" + userId;
}
});
// This alert should only be reached if none of the actor objects
// has a name and password that matches your input box values.
alert("Ощибка в логине или пароле!");
});
}
// On the next page...
// Top answer from http://stackoverflow.com/questions/2090551/parse-query-string-in-javascript
// This approach can handle URLs with more than one query parameter,
// which you may potentially add in the future.
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split('&');
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split('=');
if (decodeURIComponent(pair[0]) == variable) {
return decodeURIComponent(pair[1]);
}
}
console.log('Query variable %s not found', variable);
}
var userId = getQueryVariable('userId');
Thanks you for help.Ended it all with usage of:
sessionStorage.getItem('label')
sessionStorage.setItem('label', 'value')

Persist cookie form values across multiple pages

The setting: I have a form that captures$thisSearch.val(), saves it as a cookie, and pushes to an array. The form is an overlay triggered from a menu item in the header so this can appear on any page in the site.
The issue is that it only seems to save/persist the input values on/from that page it was entered on. I'm trying to collect all these values into one list.items() array that can be entered anywhere in the site.
I've tried pushing the string to the array myself instead of the add function and moved the dom around for the search form.
I can update question when I know what to specifically ask. Any pointers / concepts I should be aware of for this would be great.
var cookieList = function(cookieName) {
var cookie = $.cookie(cookieName);
var items = cookie ? cookie.split(/,/) : new Array();
return {
"add": function(val) {
items.push(val);
$.cookie(cookieName, items.join(','));
},
"items": function() {
return items;
}
}
}
var list = new cookieList("PreviousSearches");
$searchSubmit.on('click', function() {
var $thisSearch = $(this).prev().find($searchInput);
if( $thisSearch.val() == '' ) {
alert('Please enter a search term');
console.log( list );
return false;
} else {
searchTerm = $thisSearch.val()
list.add( searchTerm );
}
});
var searchTerms = list.items();
var total = searchTermsFiltered;
var searchTermsFiltered = searchTerms.filter(Boolean).slice( - 5 ).reverse();
var searchtermClean = searchTermsFiltered.join();
$.each($(searchTermsFiltered), function(i,v){
if (!window.location.origin)
window.location.origin = window.location.protocol+"//"+window.location.host;
var lastURLRaw = window.location.origin+'/bch/?s='+v;
var lastURL = lastURLRaw.replace(/ /g, '+');
listItem = '<li>'+v+'</li>';
$('.tags, .search-tags').append(listItem );
});
I found the path specifier from jquerys $.cookie in this top answer below.
$.cookie(cookieName, items.join(',') , { path: '/' }); from my code.
why are my jquery cookies not available across multiple pages?

Show contents of localStorage into div

I have this basic function :
pid = 1;
$(function() {
if (localStorage["key"+pid] != null) {
var contentsOfDiv = localStorage.getItem("key"+pid);
$("#Div").html(contentsOfdDiv);
}
});
The problem is that the pid value will change eventually and I don't want to overwrite the contents of the key.
How can I proceed to stack every Div content that localStorage is saving for me ?
You can iterate on localStorage entries just like on any object properties :
for (var key in localStorage) {
console.log(key, localStorage[key]);
}
So your code could be :
$(function() {
var lines = [];
for (var key in localStorage) {
if (/^key/.test(key)) { // does the key start with "key"
lines.push(key.slice(3) + ' = ' + localStorage[key]);
}
}
$("#Div").html(lines.join('<br>'));
});
If I have understood well, you want to use pid to loop over the object.
Best way to do this and avoid for in chain prototypical problems is the following:
(I think for this case you are better with an array rather than with an object)
http://jsfiddle.net/hqkD9/
var localStorage = ['aaaa', 'bbbbb', 'cccc', 'dddd']; // don't forget to declare with var
var html_string = '';
$.each(localStorage, function(index, value) {
html_string += value + '<br>';
});
$('#my_div').html(html_string);

Dynamic arrays in Javascript/JQuery

Why does my array length always come out to 0 even though var email is equal to a string. (I've alerted out var email and the data is there).
var emails = new Array();
//get all the emails
$('.emailBox input').each(function (i)
{
var email = $(this).val();
if(email != '')
{
emails[email] = email;
alert(emails.length);
}
});
Because you're adding a property to the array.
var a = [];
a.foo = 42;
a.length === 0; // true
Instead try
emails.push(email);
This is the same as emails[emails.length] = email
As an aside:
var emails = new Array();
Is bad. You should be using [] instead of new Array() mainly because it's more terse and readable.
if (email != '') {
The above can be replace with if (email) { in case jQuery ever returns undefined or null
To make the entire code more elegant you should use
var emails = $('.emailBox input').map(function() {
return this.value;
}).filter(function (k, v) { return v; }).get();
Or without jQuery
var emails = [].map.call(document.querySelectorAll(".emailBox input"), function (v) {
return v.value;
}).filter(function (v) { return v; });
Although you'll need a QSA shim and a ES5 shim for legacy platform support.
Edit:
If you want the array to be unique then reduce it.
var arr = arr.reduce(function (memo, val, key, arr) {
// if the first index of the value is the index then add it.
// if the first index is different then we already have it.
if (arr.indexOf(val) === key) {
memo.push(val);
}
return memo;
}, []);
You could do all of that using a few jQuery methods.
var emails = $('.emailBox input')
.map(function() { return $(this).val() || null; })
.get();
jsFiddle.
emails[email] = email isn't doing what you want it to do. Try
emails.push(email);

Categories

Resources