I would like to know how I can use the result of an ajax request as an "object". I'll try to explain. I have an ajax request that get a number, every 2 seconds, to an xml file. Then I render it into my html.
Here is my js:
var url = window.location.pathname.split('/');
var id = url[3];
setInterval(function() {
$.ajax({
type: "GET",
url: "http://myxml",
success: parseXml
});
}, 2000);
function parseXml(xml){
$(xml).find("user").each(function() {
if($(this).attr("id") === id ) {
$(".DubScore").html($(this).attr("count"))
}
});
}
and my html:
<div class="DubScore"> </div>
It works find, I have a count displayed to my page.
What I want to do, is to take this number and be able to do whatever I wan't with it in my html. For example, name it "Score", and be able to do "Score" + 2 , and things like that.
I hope my question is clear enough. Thank you for your help.
You can parse the attribute value and store it in a global variable :
var score;
function parseXml(xml){
$(xml).find("user").each(function() {
if($(this).attr("id") === id ) {
score = parseInt($(this).attr("count"), 10);
}
});
}
Afterwards, you may do, for example,
score += 2;
$(".DubScore").html(score);
Related
I am trying to display region and city if is available and display the country text if city is not available. I tried adding if else condition and setup the variable but it returns blank, undefined or nulled. On the header I have the script below
jQuery.ajax( {
url: '//freegeoip.net/json/',
type: 'POST',
dataType: 'jsonp',
success: function(location) {
jQuery('#city').html(location.city);
jQuery('#region-name').html(location.region_name);
jQuery('#country-name').html(location.country_name);
}
} );
var mycountry = document.getElementById("country-name").value;
var mycity = document.getElementById("country-name").value;
var myregion = document.getElementById("city").value;
then on the body I have
if (mycity != "") {
document.write(mycity); document.write(myregion); }
else {
document.write(mycountry);
}
and the result I got is nulled or undefined.
reference
http://pastebin.com/xaqq16Ks
AJAX is an async operation. You can't use document.write with AJAX. Add the if (city === '') logic to success callback instead.
If you want to display them in text fields, then you should change value instead of html:
$('#city').val(location.city);
$('#region-name').val(location.region_name);
$('#country-name').val(location.country_name);
and the rest of the code will run just fine.
Otherwise if you want to display them with a span/div or any other element, use should change the second part of your code, namely, you should get the innerHTML property and not value as follows:
var mycountry = document.getElementById("country-name").innerHTML;
var mycity = document.getElementById("city").innerHTML;
var myregion = document.getElementById("region-name").innerHTML;
Use Case: I want to represent some text with ellipsis (e.g. My name is ...) in a HTML LINK/ anchor, where the text is fetched by an ajax call.
Whenever the user clicks the link, I load the text completely in a modal dialog box) by making the same ajax call used to fetch the text.
Here is the code:
"aoColumns": [
<Some code for columns>
{"mData": "id", sWidth:"180px","mRender": function ( data, type, full ) {
var obj = JSON.parse(JSON.stringify(full));
JSRoutes.com.app.controllers.File.getContent(obj["fileId"]).ajax({
data: {},
success: function(data) {
console.log("This is the data I want to represent in ellipsis: " + data);
}
});
return "<a>" + <HOW TO PUT CONTENT (data) HERE> +"</a>";
]
Problem: How to make the ajax call to fetch file content and provide the anchor element's text at the same time. Because by the time we 'return', the ajax call might not have finished.
I might not have been successful in explaining the question clearly, so comments and questions are welcome to improve the question.
Finally, I went with using the element id to modify the text later in the ajax function success callback.
As the file Ids are unique, I can provide unique HTML anchor ids.
"aoColumns": [
<Some code for columns>
{"mData": "id", sWidth:"180px","mRender": function ( data, type, full ) {
var obj = JSON.parse(JSON.stringify(full));
JSRoutes.com.app.controllers.File.getContent(obj["fileId"]).ajax({
data: {},
success: function(data) {
var linkText = "";
var n = 70;
if (data.length > n) {
linkText = data.substr(0,n) + " ...";
} else {
linkText = data;
}
$( '#file_'+obj["fileId"]).text(linkText);
}
});
return "<a> id=file_" + obj["fileId"] + ">" + "This will be loaded soon" +"</a>";
}
]
The first letter 'a' in 'ajax' stands for async, means you cannot get the result directly, but the result will be provided to your callback function later.
In your example:
JSRoutes....ajax({
success: function(data){
// async callback
}
});
This success function is which will be executed after the ajax returns.
So that you should return an empty <a> element first, and fill the content later in the callback.
example:
var a = document.createElement('a');
JSRoutes......ajax({
success: function(data){
a.textContent = data;
}
});
return a;
AJAX are asynchronous. so if you want to finish the some task first and calling the second function only after the completion of the first one than you have to write it in Javascript function instead of calling it in jQuery.
I am trying to add a delay to a repeatable query.
I found out that .delay is not the one to use here. Instead, I should go with setInterval or setTimeout. I tried both, without any luck.
Here's my code:
<?php
include("includes/dbconf.php");
$strSQL = mysql_query("SELECT workerID FROM workers ORDER BY workerID ASC");
while($row = mysql_fetch_assoc($strSQL)) {
?>
<script id="source" language="javascript" type="text/javascript">
$(setInterval(function ()
{
$.ajax({
cache: false,
url: 'ajax2.php',
data: "workerID=<?=$row['workerID'];?>",
dataType: 'json',
success: function(data)
{
var id = data[0]; //get id
var vname = data[1]; //get name
//--------------------------------------------------------------------
// 3) Update html content
//--------------------------------------------------------------------
$('#output').html("<b>id: </b>"+id+"<b> name: </b>"+vname);
}
});
}),800);
</script>
<?php
}
?>
<div id="output"></div>
The code works fine, it outputs the result as asked. It's just loads without the delay. The timout and / or interval doesn't seem to work.
Anybody knows what I am doing wrong?
I've never understood why people always add their AJAX requests in intervals rather than letting the successful AJAX calls just call themselves, all the while risking severe server load through multiple requests and not just making another call once you had a successful one come back.
In this light, I like to write solutions where the AJAX calls just call themselves on completion, something like:
// set your delay here, 2 seconds as an example...
var my_delay = 2000;
// call your ajax function when the document is ready...
$(function() {
callAjax();
});
// function that processes your ajax calls...
function callAjax() {
$.ajax({
// ajax parameters here...
// ...
success: function() {
setTimeout(callAjax, my_delay);
}
});
}
I hope this makes sense! :)
Update:
After reviewing this again, it's been brought to my attention that there was also a problem in the PHP code in the original question that I needed to clarify and address.
Although the script above will work great in creating a delay between AJAX calls, when added to the PHP code in the original post the script will just be echo'd out as many times as the number of rows the SQL query selects, creating multiple functions with the same name and possibly making all AJAX calls simultaneously...not very cool at all...
With that in mind, I propose the following additional solution - create an array with the PHP script that may be digested by the JavaScript one element at a time to achieve the desired result. First, the PHP to build the JavaScript array string...
<?php
include("includes/configuratie.php");
$strSQL = mysql_query("SELECT workerID FROM tWorkers ORDER BY workerID ASC");
// build the array for the JavaScript, needs to be a string...
$javascript_array = '[';
$delimiter = '';
while($row = mysql_fetch_assoc($strSQL))
{
$javascript_array .= $delimiter . '"'. $row['workerID'] .'"'; // with quotes
$delimiter = ',';
}
$javascript_array .= ']';
// should create an array string, something like:
// ["1","2","3"]
?>
Next, the JavaScript to digest and process the array we just created...
// set your delay here, 2 seconds as an example...
var my_delay = 2000;
// add your JavaScript array here too...
var my_row_ids = <?php echo $javascript_array; ?>;
// call your ajax function when the document is ready...
$(function() {
callAjax();
});
// function that processes your ajax calls...
function callAjax() {
// check to see if there are id's remaining...
if (my_row_ids.length > 0)
{
// get the next id, and remove it from the array...
var next_id = my_row_ids[0];
my_row_ids.shift();
$.ajax({
cache : false,
url : 'ajax2.php',
data : "workerID=" + next_id, // next ID here!
dataType : 'json',
success : function(data) {
// do necessary things here...
// call your AJAX function again, with delay...
setTimeout(callAjax, my_delay);
}
});
}
}
Note: Chris Kempen's answer (above) is better. Please use that one. He uses this technique inside the AJAX routine. See this answer for why using setTimeout is preferable over setInterval.
//Global var
is_expired = 0;
$(function (){
var timer = setInterval(doAjax, 800);
//At some point in future, you may wish to stop this repeating command, thus:
if (is_expired > 0) {
clearInterval(timer);
}
}); //END document.ready
function doAjax() {
$.ajax({
cache: false,
url: 'ajax2.php',
data: "workerID=<?=$row['workerID'];?>",
dataType: 'json',
success: function(data) {
var id = data[0]; //get id
var vname = data[1]; //get name
//--------------------------------------------------------------------
// 3) Update html content
//--------------------------------------------------------------------
$('#output').html("<b>id: </b>"+id+"<b> name: </b>"+vname);
}
}); //END ajax code block
} //END fn doAjax()
I've devised a a wrapper method which adds a custom delay on-top of the default $.ajax method. This is a way to have (on all jQuery ajax calls) a delay, throughout your entire app.
Very handy in simulating real-life random latency.
(function(){
$._ajaxDelayBk = $.ajax; // save reference to the "real" ajax method
// override the method with a wrapper
$.ajax = function(){
var def = new $.Deferred(),
delay = typeof $.ajax.delay == 'undefined' ? 500 : $.ajax.delay,
delayTimeout,
args = arguments[0];
// set simulated delay (random) duration
delayTimeout = setTimeout(function(){
$._ajaxDelayBk(args)
.always(def.resolve)
.done(def.resolve)
.fail(def.reject)
}, delay);
def.abort = function(){
clearTimeout(delayTimeout);
};
return def;
}
})();
USE EXAMPLE:
// optional: set a random delay to all `ajax` calls (between 1s-5s)
$.ajax.delay = Math.floor(Math.random() * 5000) + 1000;
var myAjax = $.ajax({url:'http://whatever.com/API/1', timeout:5000})
.done(function(){ console.log('done', arguments) })
.fail(function(){ console.log('fail', arguments) })
.always(function(){ console.log('always', arguments) })
// Can abort the ajax call
// myAjax.abort();
var takeInput=true;
$('#searchDrug').on('input',function() {
if(!takeInput){return false;}
takeInput=false;
var timer = setTimeout(function() {
$.ajax({
type: 'POST',
url: "{{route('AjaxSearchDrug')}}",
data: {
_token: '<?php echo csrf_token() ?>',
'searchkeyword': searchkeyword,
},
success: function (data) {
//do some logic then let keys be effective once more
takeInput=true;
}
});
}, 700);
please don't judge my JS skills, I'm complete beginner in it. =))
So I have a function that register user, But I want to make "create_sample_user" button to fill text fields with some data. This way people can quickly check the website, without typing names, email and so on...
But the problem is: Register button works fine when I type username and all other fields by my self. But Doesn't work(I assume it just doesn't 'see' the values of the text fields) when I fill them with "create_sample_user" button.
function create_sample_user() {
var button = $("#create-sample-user");
button.click(function() {
var ranNum = 1 + Math.floor(Math.random() * 100);
var uname = 'Sample_'+ranNum;
$("#id_username").val(uname);
$("#id_email").val(uname+'#'+uname+'.com');
$("#id_password").val(uname);
$("#id_password2").val(uname);
});
}
function register_user() {
$("#register-user").click(function() {
$.ajax({
url: "/registration/register_user/",
type: "POST",
dataType: "text",
data: {
username : $("#id_username").val(),
email : $("#id_email").val(),
password : $("#id_password").val(),
password2 : $("#id_password2").val(),
},
success: function(data) {
parsed_data = $.parseJSON(data);
if (data) {
alert("User was created");
window.location = parsed_data.link;
}
else {
alert("Error");
}
}
});
});
}
THE ANSWER:
whole thing didn't work because of one character in this line of code:
`var uname = 'Sample_'+ranNum;`
For some reason _ character was the problem, and AJAX didn't want take it.
in other words:
var uname = 'Sample'+ranNum;
This line would do the trick :=)
Okay, replace your create_sample_user() method with this:
$(document).ready(function() {
var button = $("#create-sample-user");
button.click(function() {
var ranNum = 1 + Math.floor(Math.random() * 100);
var uname = 'Sample_'+ranNum;
$("#id_username").val(uname);
$("#id_email").val(uname+'#'+uname+'.com');
$("#id_password").val(uname);
$("#id_password2").val(uname);
});
});
Also, try removing the function register_user() function wrapper.
This should do it. It should pop up the success alert box as well (I changed your AJAX URL to use the AJAX echo for jsFiddle):
http://jsfiddle.net/MQ6Cq/4/
UPDATES (since you posted your code - I will update this with bugs as I find them):
You have two $(document).ready() calls now - delete the first one (THIS WAS EDITED)
You have have to remove the lines function register_user() { and the closing brace from around the register user click handler
I made a tiny update to my earlier fiddle, just in case it helps with testing, and changed the request type to "GET". Open your browser's console (F12), right-click and turn on logging for XMLHttpRequests. Then run it and you will see that the AJAX is successfully transmitting the data. I don't know what is wrong with your other stuff but I don't have a server that I can test it on and I'm not getting enough feedback to know what's going on after you try each suggestion (or even if you're trying them). I just hope this helps you solve your problem.
Good Luck! :)
Your code should work. Here's a jsfiddle (simplified version of it)
If you look at the console, you'll see the data is well formatted.
The only thing I see in your code is that create_sample_user() is not called so the click event isn't applied to the button. But I guess you've just omitted to put it in the question
create_sample_user();
$('#register-user').click(register_user);
function create_sample_user() {
var button = $("#create-sample-user");
button.click(function() {
var ranNum = 1 + Math.floor(Math.random() * 100);
var uname = $("#id_username").val('Sample_'+ranNum);
$("#id_email").val(uname.val()+'#'+uname.val()+'.com');
$("#id_password").val(uname.val());
$("#id_password2").val(uname.val());
});
}
function register_user() {
data = {
username : $("#id_username").val(),
email : $("#id_email").val(),
password : $("#id_password").val(),
password2 : $("#id_password2").val(),
}
console.log(data);
}
$("#create-sample-user").click(create_sample_user);
$('#register-user').click(register_user);
function create_sample_user() {
var ranNum = 1 + Math.floor(Math.random() * 100);
var uname = $("#id_username").val('Sample_' + ranNum);
$("#id_email").val(uname.val() + '#' + uname.val() + '.com');
$("#id_password").val(uname.val());
$("#id_password2").val(uname.val());
}
function register_user() {
data = {
username: $("#id_username").val(),
email: $("#id_email").val(),
password: $("#id_password").val(),
password2: $("#id_password2").val(),
}
console.log(data);
}
I'm trying to load some ajax content into a table, unfortunately it's only loading the last row multiple times instead of loading each new rows.
This is the code I'm using:
function periodicRefresh()
{
$.ajax({
type: 'GET',
url: 'include/ajaxActions.php',
data: "action=displayLastEvent",
success: function(msg){
var newid = msg;
current = $("#list tr:first").get(0).id;
if(newid != current){
while (current<newid)
{
current++;
addToList(current);
}
}
}
});
}
function addToList(x)
{
$.ajax({
type: 'GET',
url: 'include/ajaxActions.php',
data: "action=displayRow&row="+x,
success: function(msg){
$("#list").prepend(msg);
$("#list tr:first").highlightFade({
speed:3000
});
lastrow = x-20;
$('#'+lastrow).remove();
}
});
}
displayLastEvent returns the id of the last row.
displayRow returns the last row
You need to push your xmlHttps into an array or abstract data type, which you can then attach events handlers. Seems jquery doesn't do that for you.
I would address this issue by encouraging you to change your approach since it looks like you're likely making more AJAX requests than necessary whenever more rows need to be added to the list (2+ instead of just 2).
I would update include/ajaxActions.php?action=displayRow to accept a CSV of ids (or whatever it is you're passing in), and returning a set of row data, instead of data for just one row.
I think that:
current = $("#list tr:first").get(0).id;
return always the same result as jQuery remember only the page when it was first loaded.
For example, if you have a single tr[id=0]:
pass 1 : current = 0; msg = 1 -> 1 tr prepended with id = 1;
pass 2 : current is always 0 (not 1); msg = 1 -> 1 tr prepended with id = 1;
...
what you should do, is make jQuery recognize your page structure after adding your messages, or store the last index in a different way: using hidden input for example:
HTML:
<input type="hidden" value="0" id="lastId"/>
script:
initialize #lastId value when the page is loaded:
$(document).ready(function(){
$("#lastId").val(0);//or by using your displayLastEvent action
});
modify periodicRefresh to read #lastId value:
function periodicRefresh()
{
$.ajax({
type: 'GET',
url: 'include/ajaxActions.php',
data: "action=displayLastEvent",
success: function(msg){
var newid = msg;
var current = $("#lastId").val();
if(current<newid) $("#lastId").val(newid);
if(newid != current){
while (current<newid)
{
current++;
addToList(current);
}
}
}
});
}