Use a FOR loop within an AJAX call - javascript

So, what i'm trying to do is to send an AJAX request, but as you can see i have many fields in my form, and i use an array to make validations, i would like to use the same array, to pass the values to be sent via AJAX:
I never used the for loop in JS, but seems familiar anyway.
The way the loop is made, obviously wont work:
for (i=0;i<required.length;i++) {
var required[i] = $('#'+required[i]).attr('value');
This will create the variables i want, how to use them?
HOPEFULLY, you guys can help me!!! Thank you very much!
required = ['nome','sobrenome','endereco','codigopostal','localidade','telemovel','email','codigopostal2','localidade2','endereco2','nif','entidade','codigopostal3','localidade3','endereco3','nserie','modelo'];
function ajaxrequest() {
for (i = 0; i < required.length; i++) {
var required[i] = $('#' + required[i]).attr('value');
var dataString = 'nome=' + required[0] + '&sobrenome=' + required[1];
}
$.ajax({
type: "POST",
url: "ajaxload/como.php",
data: dataString,
success: function() {
$(".agendarleft").html("SUCESS");
}
});

To help ensure that the appropriate element IDs and values are passed, loop through the various elements and add the data to an object first.
jQuery:
required = ['nome', 'sobrenome', 'endereco', 'codigopostal', 'localidade', 'telemovel', 'email', 'codigopostal2', 'localidade2', 'endereco2', 'nif', 'entidade', 'codigopostal3', 'localidade3', 'endereco3', 'nserie', 'modelo'];
function ajaxrequest() {
var params = {}; // initialize object
//loop through input array
for (var i=0; i < required.length; i++) {
// set the key/property (input element) for your object
var ele = required[i];
// add the property to the object and set the value
params[ele] = $('#' + ele).val();
}
$.ajax({
type: "POST",
url: "ajaxload/como.php",
data: params,
success: function() {
$(".agendarleft").html("SUCESS");
}
});
}
Demo: http://jsfiddle.net/kPR69/

What would be much cleaner would be to put a class on each of the fields you wish to save and use this to iterate through them. Then you wouldn't need to specify the input names either and you could send a json object directly to the Service;
var obj = {};
$('.save').each(function () {
var key = $(this).attr('id');
var val = $(this).val();
if (typeof (val) == "undefined")
val = "''"
obj[key] = val;
}
Then send obj as the data property of your AJAX call....

There are a few issues with your code. 'required' is being overwritten and is also being re-declared inside of the loop.
I would suggest using pre-written library, a few I included below.
http://jquery.malsup.com/form/#validation
https://github.com/posabsolute/jQuery-Validation-Engine
Otherwise the follow would get you close. You may need to covert the array into a string.
var required = ['nome','sobrenome'];
function ajaxrequest() {
var values;
for (i = 0; i < required.length; i++) {
var values[i] = $('#' + required[i]).attr('value');
}
$.ajax({
type: "POST",
url: "ajaxload/como.php",
data: values,
success: function() {
$(".agendarleft").html("SUCESS");
}
});
}

Related

Pass var from js to php using ajax not working

I'm making a calculator web app in PHP. The front end is using HTML, CSS, and JS. In my JS file, I am trying to pass a var to PHP using ajax. Here's what I have so far:
// Get all the keys from document
var keys = document.querySelectorAll('#calc span');
var operators = ['+', '-', 'x', '÷'];
var decimalAdded = false;
// Add onclick event to all the keys and perform operations
for(var i = 0; i < keys.length; i++) {
keys[i].onclick = function(e) {
// Get the input and button values
var input = document.querySelector('.screen');
var inputVal = input.innerHTML;
var btnVal = this.innerHTML;
// Now, just append the key values (btnValue) to the input string and finally use javascript's eval function to get the result
// If clear key is pressed, erase everything
if(btnVal == 'C' || btnVal == 'AC') {
input.innerHTML = '';
decimalAdded = false;
}
// If eval key is pressed, calculate and display the result
else if(btnVal == '=') {
var equation = inputVal;
var lastChar = equation[equation.length - 1];
// Replace all instances of x and ÷ with * and / respectively. This can be done easily using regex and the 'g' tag which will replace all instances of the matched character/substring
equation = equation.replace(/x/g, '*').replace(/÷/g, '/');
$.ajax({
type: "GET",
url: "calc.php",
data: {'passVal': equation},
success: function(data) {
alert(data);
}
});
I'm not seeing anything in my alerts and it's also not posting to php file I specified. If I do the following on the other hand, I get my data in the alert but still not sure how to pass to php file:
....rest of code
$.ajax({
type: "POST",
url: "calc.php",
data: {'passVal': equation},
success: function(data) {
alert(equation);
}
});
In Javascript (because I think that this is what you are looking for) :
var elementValue = document.querySelector('span').value;
//or var elementValue = document.getElementById('idhere').value;
<span class="on">AC</span>
<span>(</span>
<span>)</span>

An efficient way to call type specific functions

this is my situation:
I have a Field.js file which contains a bunch of classes (made with this plugin) each corresponding to a datatype on the page.
An example of a class:
$.Class("Types_UserId_Js",{
init_done : false,
validate : function (value){
return true;
}
},{
container : "",
UserIdDisplay : function (){
var associations = [];
var uid = 0;
$( container ).find(".userid_display").each(function(index,el){
uid = $( this ).find(".userid_value").val();
url = siteurl + "/dname?";
$.ajax({
type: "POST",
url: url,
data: ajaxData,
dataType: "json",
success: function(result, status){
associations[uid] = result;
}
});
});
},
init : function ( container ) {
if(container.length > 0 && !Types_UserId_Js.init_done){
this.container = container;
this.UserIdDisplay();
Types_UserId_Js.init_done = true;
}
};
});
(It's a dummy class for now).
I also have some html code that renders the types UI, in a standard format.
In the end, I have a page with a bunch of different types of inputs, and they all need their specific init function to be called in order to render properly.
What I did up to now is simply invoke EVERY init function in the Field.js file, like so:
$( document ).ready(function(ev){
var cont = $("#container");
var uid = new Types_UserId_Js(cont);
var text = new Types_Text_Js(cont);
// And so forth
});
I'd really like to know if there is a more efficient way to call every init function in the file without having to call them individually.
The Field.js is part of the main framework, and it is maintained by a third party developer so, while I can and do edit it to my leisure, I'd prefer to keep the generic structure that they imposed.
Thank you,
I think you'd need some mapping field <-> function. You can add data-attributes to the fields with the name of the fields init function. Then you can just loop over your fields, get the value and execute the function.
Check the following snippet:
// helper function borrowed from http://stackoverflow.com/a/12380392/4410144
var getFunctionFromString = function(string) {
var scope = window;
var scopeSplit = string.split('.');
for (i = 0; i < scopeSplit.length - 1; i++) {
scope = scope[scopeSplit[i]];
if (scope == undefined) return;
}
return scope[scopeSplit[scopeSplit.length - 1]];
}
var myFunction = function() {
console.log('myFunction');
}
var myOtherFunction = function() {
console.log('myOtherFunction');
}
$('input').each(function() {
var initFunction = getFunctionFromString($(this).data('function'));
initFunction();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input data-function="myFunction" />
<input data-function="myOtherFunction" />

Setting Localstorage Variable Name to a Variable's value

I am using a javascript loop to create localstorage variables. For some reason, all the localstorage values are null except for the last one. Does anyone know why?
Here is my code:
function setValues() {
var json = jQuery.parseJSON(data);
for (var i=0; i<json.length; i++)
{
var id = json[i].id;
$.ajax({
url: url,
crossDomain: true,
type: 'post',
data: {
'theid': id
},
success: function (data2) {
window.localStorage['club'+id] = data2;
},
});
}
}
function getValue(id) {
console.log(window.localStorage.getItem('club'+id));
}
I call getValue() else where in the code, it is irrelevant to the issue. If the 'id' is the last id that was used for adding to the localstorage, it isn't null. However, it seems as if all the previous values are overwritten.
How can I fix this issue? Any help would be appreciated. Thanks!
ANSWER REWRITE BASED UPON THE OP's QUESTION CHANGE
This is actually a very common JavaScript issue and almost impossible to search for unless you already know the answer the magic words involved.
Because your wording is slightly different than the usual issue, I'm not going to vote to close this question but rather, explain what is going on.
There is only one copy of the variable i and that variable is changed as the loop runs. By the time the callbacks return, that loop is long over and i has reached its final value.
What you need to do is capture a local copy of that value. There are two ways to do it -- I'll show the easiest one to read:
function doAjax(i) {
// this 'i' is private.
var id = json[i].id;
$.ajax({
url: url,
crossDomain: true,
type: 'post',
data: {
'theid': id
},
success: function (data2) {
window.localStorage['club' + id] = data2;
}
});
}
function setValues() {
var json = jQuery.parseJSON(data);
for (var i = 0; i < json.length; i++) {
doAjax(i);
}
}
The other way to do this is to use a closure and an anonymous function:
function setValues() {
var json = jQuery.parseJSON(data);
for (var i = 0; i < json.length; i++) {
(function (i2) {
// this 'i' is private.
// Givign it the name of 'i2' just to be clear
var id = json[i2].id;
$.ajax({
url: url,
crossDomain: true,
type: 'post',
data: {
'theid': id
},
success: function (data2) {
window.localStorage['club' + id] = data2;
},
});
// this is the 'i' from the main loop
}(i));
}
}
For more info see
How do JavaScript closures work?

Issues with Javascript For and Arrays

I'm trying to dynamically hide specific photos on a page, through Javascript, by selecting their data-id attribute and hiding the photo. This is being achieved through Ajax grabbing the IDs from a TXT file, splitting them in to an Array, and then using jQuery to hide the img with that ID. Note that this function is being passed through a setInterval every 3 seconds...
function getBlockedIDs() {
var stringData = $.ajax({
url: "http://s61892.gridserver.com/zone/twitter2/blocked.txt",
async: false
}).responseText;
var blockedArray = new Array();
blockedArray = stringData.split(",");
var length = stringData.length
for (var i = 0; i < length; i++) {
$('img.tweetphoto[data-id="' + stringData[i] + '"]').hide();
}
}
My problem is, it's not working! No errors are thrown from the console. What's wrong with my code? The idea behind this is to block specific (inappropriate) photos without reloading the page.
Any help is appreciated!
Are you sure you want to use stringData inside the for loop and not blockedArray? If so change the assignment to length also.
My version would look something like :
function getBlockedIDs() {
var blockedArray = $.ajax({
url: "http://s61892.gridserver.com/zone/twitter2/blocked.txt",
async: false
}).responseText.split (/\s*,\s*/);
for (var i = blockedArray.length; i--;) {
$('img.tweetphoto[data-id="' + blockedArray[i] + '"]').hide();
}
}
I would do something like:
function getBlockedIDs() {
$.get("http://s61892.gridserver.com/zone/twitter2/blocked.txt", function(stringData) {
var blockedArray = stringData.split(/\s*,\s*/);
for (var i = 0; i < blockedArray.length; i++) {
$('img.tweetphoto[data-id="' + blockedArray[i] + '"]').hide();
}
});
}

Reducing number of calls to the methods of a JavaScript object

I was interested in a way to reduce the number of calls to the injectMethod on the below constructor function:
function InjectScriptsAndExecute(url) {
this.url = url;
this.injectMethod = function() {
var inject = $.ajax({
url: this.url,
cache: true,
dataType: 'script'
});
return inject;
}
}
var pngFix = new InjectScriptsAndExecute("/Global/ICIS/Scripts/DD_belatedPNG_0.0.8a-min.js");
var pngList = new InjectScriptsAndExecute("/Global/ICIS/Scripts/DD_PNG_listing.js");
pngFix.injectMethod();
pngList.injectMethod();
Is there a way i can pass an object to the constructor function that contains as many URL references as i like without having to declare a new variable and subsequently call the method?
You could have the constructor receive an object or array, but you're still only creating one instance.
One way around it would be to modify the constructor so that you call it as a regular function (without new), and pass it an Array of the urls. Then it will iterate over the array, making a recursive call, but with the new keyword, and overwriting each url with the new instance.
Then it would return the original Array.
function InjectScriptsAndExecute(url) {
if (Object.prototype.toString.call(url).indexOf('Array') != -1) {
for (var i = 0, len = url.length; i < len; i++) {
url[i] = new InjectScriptsAndExecute(url[i]);
}
return url;
} else {
this.url = url;
this.injectMethod = function() {
var inject = $.ajax({
url: this.url,
cache: true,
dataType: 'script'
});
return inject;
}
}
}
var arr = InjectScriptsAndExecute(["/Global/ICIS/Scripts/DD_belatedPNG_0.0.8a-min.js",
"/Global/ICIS/Scripts/DD_PNG_listing.js"
]);
var len = arr.length;
while( len-- ) {
arr[len].injectMethod();
}
For safety, you would really want to have some additional checks to see if the function is being called as the constructor or not. And you'd want to have appropriate behavior for each depending on whether it received an Array or a String.
You can -- but you're going to get into interesting territory here:
function InjectScriptsAndExecute() {
this.urls = Array.prototype.slice.call(arguments, 0);
this.injectMethod = function() {
for (var i=0; i < this.urls.length; i++) {
$.ajax({
url: this.urls[i],
cache: true,
async: false, // Otherwise you cannot depend on the parse order
dataType: 'script'
});
}
}
// You can then use it in this way:
var all_scripts =
new InjectScriptsAndExecute("/Global/ICIS/Scripts/DD_belatedPNG_0.0.8a-min.js",
"/Global/ICIS/Scripts/DD_PNG_listing.js");
all_scripts.injectMethod();
What you probably want is a dependency manager like Require.js or LAB.js if you're doing this with any frequency. Dojo and YUI also provide dependency management, if you're looking for a full framework.

Categories

Resources