jQuery and Ajax script - javascript

So i have a jQuery script that i should explain it line by line, i already do that and i want to make sure that is correct, so this is my script :
//Here we use the jQuery selector ($) to select the servers_id which is located into
//the delivers_id and we attaches a function to run when a change event occurs
$("#delivers #servers").change(function(){
//Here we look if the servers_id value was changed and the value is different of 0
if($(this).val() != '0') {
//Here we create a new variable sid and we stored the servers_id value in it
var sid = $("#delivers #servers").val();
//Here we use the Ajax $.get to get the sid value and send it by Ajax request then
//we set the data into the o_vmats_id html and empty the vmtas_id
$.get("/deliverability/get_vmtas/" + sid,
function(data) { $('#o_vmtas').html(data); $('#vmtas').html(''); });
}
//Here the else statement, we select the vmtas_id and set the html content like in the code (value=0)
//and empty the o_vmtas_id html content
else { $('#vmtas').html('<option value="0">All Classes</option>');
$('#o_vmtas').html(''); }
});
so please if someone has any remark i will be very appreciative

You're looking for the #servers element twice, no need for that. You can and should cache items that are going to be looked up more than once, so store that element in a var at the very beginning.
Other than that... there's not much to it, other than you wouldn't actually need much jQuery to do this :)

Related

Ajax call in "for" loops skips odd/even iterations

If I am here asking it is because we are stuck on something that we do not know how to solve. I must admit, we already searched in StackOverflow and search engines about a solution.. but we didn't manage to implement it / solve the problem.
I am trying to create a JavaScript function that:
detects in my html page all the occurrences of an html tag: <alias>
replaces its content with the result of an Ajax call (sending the
content of the tag to the Ajax.php page) + localStorage management
at the end unwraps it from <alias> tag and leaves the content returned from ajax call
the only problem is that in both cases it skips some iterations.
We have made some researches and it seems that the "problem" is that Ajax is asynchronous, so it does not wait for the response before going on with the process. We even saw that "async: false" is not a good solution.
I leave the part of my script that is interested with some brief descriptions
// includes an icon in the page to display the correct change
function multilingual(msg,i) {
// code
}
// function to make an ajax call or a "cache call" if value is in localStorage for a variable
function sendRequest(o) {
console.log(o.variab+': running sendRequest function');
// check if value for that variable is stored and if stored for more than 1 hour
if(window.localStorage && window.localStorage.getItem(o.variab) && window.localStorage.getItem(o.variab+'_exp') > +new Date - 60*60*1000) {
console.log(o.variab+': value from localStorage');
// replace <alias> content with cached value
var cached = window.localStorage.getItem(o.variab);
elements[o.counter].innerHTML = cached;
// including icon for multilingual post
console.log(o.variab+': calling multilingual function');
multilingual(window.localStorage.getItem(o.variab),o.counter);
} else {
console.log(o.variab+': starting ajax call');
// not stored yet or older than a month
console.log('variable='+o.variab+'&api_key='+o.api_key+'&lang='+o.language);
$.ajax({
type: 'POST',
url: my_ajax_url,
data: 'variable='+o.variab+'&api_key='+o.api_key+'&lang='+o.language,
success: function(msg){
// ajax call, storing new value and expiration + replace <alias> inner html with new value
window.localStorage.setItem(o.variab, msg);
var content = window.localStorage.getItem(o.variab);
window.localStorage.setItem(o.variab+'_exp', +new Date);
console.log(o.variab+': replacement from ajax call');
elements[o.counter].innerHTML = content;
// including icon for multilingual post
console.log(o.variab+': calling multilingual function');
multilingual(msg,o.counter);
},
error: function(msg){
console.warn('an error occured during ajax call');
}
});
}
};
// loop for each <alias> element found
//initial settings
var elements = document.body.getElementsByTagName('alias'),
elem_n = elements.length,
counter = 0;
var i = 0;
for(; i < elem_n;i++) {
var flag = 0;
console.info('var i='+i+' - Now working on '+elements[i].innerHTML);
sendRequest({
variab : elements[i].innerHTML,
api_key : settings.api_key,
language : default_lang,
counter : i
});
$(elements[i]).contents().unwrap().parent();
console.log(elements[i].innerHTML+': wrap removed');
}
I hope that some of you may provide me some valid solutions and/or examples, because we are stuck on this problem :(
From our test, when the value is from cache, the 1st/3rd/5th ... values are replaced correctly
when the value is from ajax the 2nd/4th .. values are replaced
Thanks in advance for your help :)
Your elements array is a live NodeList. When you unwrap things in those <alias> tags, the element disappears from the list. So, you're looking at element 0, and you do the ajax call, and then you get rid of the <alias> tag around the contents. At that instant, element[0] becomes what used to be element[1]. However, your loop increments i, so you skip the new element[0].
There's no reason to use .getElementsByTagName() anyway; you're using jQuery, so use it consistently:
var elements = $("alias");
That'll give you a jQuery object that will (mostly) work like an array, so the rest of your code won't have to change much, if at all.
To solve issues like this in the past, I've done something like the code below, you actually send the target along with the function running the AJAX call, and don't use any global variables because those may change as the for loop runs. Try passing in everything you'll use in the parameters of the function, including the target like I've done:
function loadContent(target, info) {
//ajax call
//on success replace target with new data;
}
$('alias').each(function(){
loadContent($(this), info)
});

How can I load data from API to page on onload event?

Ajax call using JQuery Ajax call using JQuery
You can store the values in localStorage to retain them and append it to textbox as needed:
$(document).on('ready' ,function(){
var value=localStorage.getItem('symbols'); //get value from localStorage
if(value!="" && typeof value != undefined) //check if it has value or not
$("#inputSymbol").val(value) //set input text's value
$("form").submit(function(){
var valueEnteredByUser = $("#inputSymbol").val();
var valueToBeStored=localStorage.getItem('symbols') + ' ' + valueEnteredByUser;
//here I am storing values with space separate and you have to take care how you want to store it actually
localStorage.setItem('symbols',valueToBeStored); //Store it in same localStorage.
//var valueEnteredByUser = "GE";
if (valueEnteredByUser == null || valueEnteredByUser == ""){
alert("Please enter a valid symbol");
}
new Request.symbolExecution(valueEnteredByUser, function(data) {
$("#dataContainer").remove();
this.success(data);
});
return false;
});
});
Now at any point of time if you want to remove value just do as below:
localStorage.setItem('symbols','') //store empty value
I would make the AJAX call right away inside your $(document).ready() block and push it onto a table that has the style="visibility:hidden;" that way the API call can begin before rendering takes place. Next I would set the hidden table to show during the $(window).load() function (which occurs after 'ready').
It may looks something like this:
$(document).on('ready', function(){
//AJAX API Here
// On success push data to table (hidden style)
});
$(window).load(function(){
//$(.hiddenTable).show();
});
This should provide a good user experience since the data will begin retreival from the API before the page is even rendered.
Why not make the first call through php and then the rest of the keys through js, as you said you want the data that is available through "GE" key as the default, you could get that data by using CURL or get_file_contents().

Jquery delay to stop code like an alert box does

If I use an alert to stop the code running the ddl ‘Suburb1' is populated with the correct value if I use ‘delay’ the value is not set. I need some way of stopping the code running after ‘change’ so that $('#Suburb1').val(SuburbVC); is not fired straight away when the ddl Suburb1 is getting populated from the DB.
if ($(this).attr("checked") == true) {
var PostCode = $('#PostCode').val();
var SuburbVC = $('#SuburbVC').val();
$('#PostCode1').val(PostCode);
// Another function is called which populates Dropdown list from DB
// If I use delay Suburb1 is not populated
$('#PostCode1').change().delay(5000);
//If I use an alert Suburb1 is populated
// alert('delay');
$('#Suburb1').val(SuburbVC);
} else {
$('#PostCode1').val("");
}
Thanks
You are tackling this problem the wrong way; You should add a callback function to execute the rest of the code, after you populate the values from the DB.
How do you populate the values from the DB? AJAX? If so, add a function call with the code you want to execute after the data is ready, to the success handler.

Variable not updating in script string, yet it updates

Very confused here.
I have a search box which reads a list of school names from my database. When I select a school, the id (from the db) gets put in a hidden textbox.
I also have a search box which reads a list of courses from my database. However, I made the query so that it only reads the courses from the selected school.
It does that, in theory.
I was planning to pass the school id, which I grab from the hidden box, to the search script which in turn passes it to my database query. However, the variable I put my school id in doesn't seem to be updating.. yet it does. Let me explain.
I come on the page. The school for my test account has id 1. The id number in my hidden box is indeed 1. I search for a school which I know has some courses assigned to it: the id number in the box changes to 3.
I have a JS variable called school_id which I declared outside of my $(document).ready. I assume that means it's global (that's what I got taught even though SO told me once it isn't really the correct way to do this. Still have to look into that). I wrote a function which updates this variable when the school search box loses focus:
$("#school").blur(function() {
school_id = $("#school_id").val();
});
A quick javascript:alert(school_id); in my browser bar also shows the updated variable: it is now 3 instead of 1.
Onto the search script part of my page (excerpt of the script):
script:"/profiel/search_richting?json=true&limit=6&id=" + school_id + "&"
As you can see, I pass the school_id variable to the script here. However, what seems to be happening is that it always passes '1', the default variable when the page loads. It simply ignores the updated variable. Does this string get parsed when the page loads? In other words, as soon as the page loads, does it actually say &id=1? That's the only idea I can come up with why it would always pass '1'.
Is there a way to make this variable update in my script string? Or what would be the best way to solve this? I'm probably missing out on something very simple here again, as usual. Thanks a lot.
EDIT
Updated per request. I added a function getTheString as was suggest and I use the value of this function to get the URL. Still doesn't work though, it still seems to be concatenating before I get a chance to update the var. HOWEVER, with this code, my ajax log says id:[object HTMLInputElement], instead of id:1. Not sure what that means.
<script type="text/javascript">
var school_id;
$(document).ready(function() {
$("#school").blur(function() {
school_id = $("#school_id").val();
});
// zoekfunctie
var scholen = {
script:"/profiel/search_school?json=true&limit=6&",
varname:"input",
json:true,
shownoresults:false,
maxresults:6,
callback: function (obj) { document.getElementById('school_id').value = obj.id; }
};
var as_json = new bsn.AutoSuggest('school', scholen);
var richtingen = {
script: getTheString(),
varname:"input",
json:true,
shownoresults:true,
maxresults:6
};
var as_json2 = new bsn.AutoSuggest('studierichting', richtingen);
});
function getTheString() {
return "/profiel/search_richting?json=true&limit=6&id=" + school_id + "&";
}
</script>
This is because the URL is static, it is not updated as the ID changes.
You should update the URL as part of the code you wrote to get the ID:
$("#school").blur(function() {
school_id = $("#school_id").val();
// update URL here ...
});
Aren't you concatenating script:"/profiel/search_richting?json=true&limit=6&id=" + school_id + "&" before the event is fired and the var updated?
Okay. So the problem was my third party plug-in instead of the code I wrote. I fixed this by editing the code of the autoSuggest plugin so it now includes my id field in the AJAX request.
var url = this.oP.script+this.oP.varname+"="+encodeURIComponent(this.sInp)+"&id="+ $("#school_id").val();
Thanks to everyone who tried to help me out!

My AJAX is only firing once,

I ahave some ajax that is fired when a checkbox is clicked, it essentially sends a query string to a PHP script and then returns the relevant HTML, however, if I select a select it works fine if I then slect another checkbox as well as the previous I get no activity what so ever, not even any errors in firebug, it is very curious, does anyone have any ideas?
//Location AJAX
//var dataObject = new Object();
var selected = new Array();
//alert(selected);
$('#areas input.radio').change(function(){ // will trigger when the checked status changes
var checked = $(this).attr("checked"); // will return "checked" or false I think.
// Do whatever request you like with the checked status
if(checked == true) {
//selected.join('&');
selected = $('input:checked').map(function() {
return $(this).attr('name')+"="+$(this).val();
}).get();
getQuery = selected.join('&')+"&location_submit=Next";
alert(getQuery);
$.ajax({
type:"POST",
url:"/search/location",
data: getQuery,
success:function(data){
//alert(getQuery);
//console.log(data);
$('body.secEmp').html(data);
}
});
} else {
//do something to remove the content here
alert($(this).attr('name'));
}
});
I see you are using the variable checked = $(this).attr("checked"); I think this might be a problem because checked is a standard JS attribute native to JS. You can compare checked normally on an element and see if it is true or false. I would start by changing the name of your variable and move on from there.
The other thing that could be happening is you might be losing your listener which might be caused by your variable selected. You do not need to declare selected outside your listener. Just declare it inside when you set it.
And if THAT doesn't help, providing some markup would help debug this issue because it seems like there is a lot going on here.
Good luck.
I turned out that because my ajax loads in a new page on success the actions were not being put on the elements as they were only being loaded once on DOM ready, I moved the all the script into a function and call that on DOM Ready now and it works great.

Categories