First, I think my title isn't very clear and very representative of what I want to achieve, but I couldn't make it clearer ...
Ok so I have a Leaderboard, created from this ajax call:
$.ajax({
url: '/handler',
dataType: 'json',
success: function(data) {
var tb = document.getElementById('Leaderboard');
while(tb.rows.length > 1) {
tb.deleteRow(1);
};
var keys = Object.keys(data);
for( key of keys) {
var username = data[key].username;
var score = data[key].score;
var row = $('<tr id = "row' + tb.rows.length + '"><td>' + username + '</td><td>' + score + '</td></tr>');
$('#Leaderboard').append(row);
if(tb.rows.length > 11){
tb.deleteRow(tb.rows.length -1);
}
}
},
error: function(jqXHR, textStatus, errorThrown){
alert('Error: ' + textStatus + ' - ' + errorThrown);
}
});
So as you can see in the Leaderboard, when clicking on a username, it opens a new page with the result of a GET request (/leaderboard/:username). My question is how can I skin this page, or even better load an html file in this page, but while keeping accessible the result of the GET request to use it inside?
That may not be clear, and that's maybe a reason why my title is not really fitting ... But anyway if you have some ideas i'll take them !!
Thanks
When the page loads, I am also dynamically creating a block . I am using ajax call to go and fetch data from another page and then populating it and creating my structure that is then added to a particular dom element. However, the problem is when I do this several times on the page during page loads, it takes quite some time for all Ajax call to finish. Do you know how I can speed up the ajax call?
$('.content-tile').each(function (idx, ele) {
// Step 1: Get the stuffs and add it in the right place on page load
var node_id = $(ele).find('article').attr('data-history-node-id');
$.get('/node/' + node_id , function (data) {
var $title = $(data).find('.title').text();
var $summary = $(data).find('.article__body').text();
var $ctaText = $(data).find('.article__field-read-more-text').text();
var $redirectToFile = $(data).find('.article__field-nova-redirect-to-file').find('a').attr('href');
var $redirectToLink = $(data).find('.article__field-redirect-link').find('a').attr('href');
// Either redirect to file or redirect to link in the order
var $ctaLinkHref = $redirectToFile;
if ($redirectToLink) {
$ctaLinkHref = $redirectToLink;
}
var $contentHover = "<a class='content-added contenthover hoveredLink' href= " + $ctaLinkHref + "></a>";
$(ele).find('article').after($contentHover); // Add the div that will be targeted for the hover
var $contentHoverHeader = "<h2 class='contenthover__header'>" + $title + '</h2>';
var $contentHoverContent = "<p class='contenthover__content'>" + $summary + '</p>';
var $contentHoverLink = "<a class='contenthover__link' href=" + $ctaLinkHref + '>' + $ctaText + '</a>';
$(ele).find('.contenthover').append($contentHoverHeader, $contentHoverContent, $contentHoverLink);
});
});
As Rory mentioned, instead of calling multiple times, just create the single object, post it back and return all the related data in one go.
// construct the array
var nodes = []
$('.content-tile').each(function (idx, ele) {
var node_id = $(ele).find('article').attr('data-history-node-id');
nodes.push(node_id);
}
// call ajax now
$.ajax({
url: "/node/RetrieveDataByNodes", //the new method which can accept the array and return data
data: JSON.stringify(nodes),
type: 'GET',
dataType: 'json'
}).done(function(result) {
$.each(result, function (k, v) {
//do something for each value
console.log(v);
}
});
I am using couchdb. I am new to it. I don't know what to have in dbroot value in place of "db/". I have taken this code from one of coucdb tutorial.
Thanks in advance for your help.
//Use a namespace to protect the scope of function and variable names
var poq = {
//Some variables global to the local namespace ("poq")
root: "http://localhost:5984/",
dbroot: "db/",
max_quotes: 6,
//Invoked when the HTML page is first loaded
loadPage: function()
{
var six_latest = poq.root + "poquotes/_design/document/_view/by_year?&limit="
+ poq.max_quotes + "&descending=true&callback=?";
$.getJSON(six_latest, poq.handleMainQuotes);
$('#donewquote').click(function() {
var db_link = poq.dbroot + "poquotes";
var record = {
"type": "quote",
"author": $("#author").val(),
"text": $("#text").val(),
"work": {
"title": $("#title").val(),
"link": $("#link").val(),
"year": parseInt($("#year").val())
}
};
$.ajax({
url : db_link,
data : JSON.stringify(record),
contentType : "application/json",
type : 'POST',
processData : false,
dataType : "json",
success : function(resp) {
alert("New document created: " + JSON.stringify(resp));
}
});
return false;
});
//Set up the collapsible form for adding new quotes
$('#popup').click(function(){
$("#newquote").slideToggle();
});
//Start out with the create quote form collapsed
$("#newquote").slideToggle();
},
//Invoked with the result of the AJAX call to load quote documents
handleMainQuotes: function(json)
{
//Load up to six records, as available
quote_count = Math.min(poq.max_quotes, json["total_rows"])
for (var i=0; i<quote_count; i++) {
var doc = json["rows"][i]["value"]
var year = doc["work"]["year"].toString()
var title = doc["work"]["title"].toString()
var link = doc["work"]["link"].toString()
//Create an HTML snippet from the fields of each quote document
qblock = $("<div class='span4 featured-quote'></div>")
.append("<h2>" + doc["author"] + "</h2>")
.append("<p style='font-size: 80%; height: 8em;'>" + doc["text"] + "</p>")
.append("<p>" + year + "</p>")
.append("<p><a href='" + link + "'>" + title + "</a></p>")
.append("<p><a class='btn' href='#'>View details »</a></p>")
//jQuery's eq selector to find the target div corresponding to the loop index
$('div.featured-quote:eq(' + i.toString() + ')').replaceWith(qblock);
}
},
}
Looks like dbroot here is meant to be the name of your database. If you haven't created a database yet, you can do so with:
curl -X PUT http://localhost:5984/mynewdatabase
Being new to CouchDB I recommend you start with The Definitive Guide (http://guide.couchdb.org)
I'm basically loading contents from a database over ajax into a div. Then, clicking on of these content-pieces should reload new content.
The ajax request is initialized as a method in a class which I call at the beginning:
function Request(tag1, tag2, tag3) {
this.tag1 = tag1,
this.tag2 = tag2,
this.tag3 = tag3
}
Request.prototype = {
ajaxCategoryRequest: function () {
$.ajax({
type: "GET",
url: "request2.php",
data: "tag1=" + this.tag1 + "&tag2=" + this.tag2 + "&tag3=" + this.tag3,
success: function (data) {
var jdata = $.parseJSON(data);
//Frage ausgeben
$("h1.question").html(jdata[0]);
//Tiles ausgeben
for (var i = 1; i < jdata.length; i++) {
$("#tiles").append(
'<div class="category" id="' + jdata[i].type + '" data-owntag="' + jdata[i].owntag + '" data-description="' + jdata[i].description + '"><img src="' + jdata[i].imageurl + '" alt="' + jdata[i].name + '"/><div class="ctitle">' + jdata[i].name + '</div></div>'
);
}
}
});
}
};
var searchtype = new Request("", "", "");
searchtype.ajaxCategoryRequest();
Then clicking one of the above created div's should start a new request:
$("#tiles").on('click', '.category', function () {
var tag1 = "newtag";
var tag2 = "newtag";
var tag3 = "newtag";
//remove old content
$('.category').remove();
//start new request
var nextrequest = new Request(tag1, tag2, tag3);
nextrequest.ajaxCategoryRequest();
});
});
Basically everything's working, the content is loaded, and if I click on a div, it does trigger a new request, but here comes the error, it's triggered twice. So, every new loaded element appears twice.
I searched for it, and I think it's due to the printing-loop in the ajax request, binding the click function every time to the div. I read a lot about .unbind("click") and .bind() it or similar( .off() ), but nothing worked for me. Maybe there is another solution for this problem?
it's triggered twice
Actually, not really. Put your console.log("Mouseclick"); in the first line of the click listener and you will see it only once per click.
$("#tiles").on('click','.category',function(e){
// …
//remove old elements
$('.category').fadeOut(200,function(){
console.log("Mouseclick");
$(this).remove();
//start request when animation completed
var nextrequest = new Request(tag1,tag2,tag3);
nextrequest.ajaxCategoryRequest();
});
});
The animation is your problem. The callback to fadeOut is invoked for each of the .category elements - that's why your $(this).remove() works (as this is only a single <div> element).
So you are actually starting a new request for each of the categories you have removed, which is of course not what you want. What you could do is moving the request out of the animation callback, then it will start right away. There are no race conditions, but - when the ajax is faster than 200 ms - it could happen that the new categories appear while the old ones are still fading out.
If you want to prevent such a glitch, you will need to find a way to fire the ajax after all of the animation callbacks have completed. Fortunately, there is the .promise method which does exactly that - it returns a promise which is guaranteed to resolve only once, and you can add callbacks for the end of the event queue:
$("#tiles").on('click','.category',function(e){
console.log("Mouseclick");
// …
// remove old elements
$('.category').fadeOut(200,function(){
$(this).remove();
}).promise().done(function() {
// start request once when all animations completed
var nextrequest = new Request(tag1,tag2,tag3);
nextrequest.ajaxCategoryRequest();
});
});
If you want to shorten the time until the ajax requests is finished, with promises you even can run the animation and the request in parallel very easily, adding a callback for when both tasks are finished:
function categoryRequest(data) {
return $.ajax({
type: "GET",
url: "request2.php",
data: {tag1: tag1, tag2: tag2, tag3: tag3},
dataType: "json" // invokes $.parseJSON automatically
});
}
function outputData(jdata) {
//Frage ausgeben
$("h1.question").html(jdata[0]);
//Tiles ausgeben
for (var i = 1; i < jdata.length; i++) {
$("#tiles").append(
'<div class="category" id="' + jdata[i].type + '" data-owntag="' + jdata[i].owntag + '" data-description="' + jdata[i].description + '"><img src="' + jdata[i].imageurl + '" alt="' + jdata[i].name + '"/><div class="ctitle">' + jdata[i].name + '</div></div>'
);
}
}
//Erster Aufruf
categoryRequest("", "", "").done(outputData);
// Weitere Aufrufe bei click
$("#tiles").on('click','.category',function(e){
console.log("Mouseclick");
//define next request variables (tags)
var stage = $(this).attr('id');
var owntag = $(this).data("owntag");
var tag1 = "", tag2 = "", tag3 = "";
if (stage == 'searchtype')
tag1 = owntag;
else if (stage == 'category')
tag2 = owntag;
else if (stage == 'subcategory')
tag3 = owntag;
else
console.log("No valid (stage)type defined");
var removed = $('.category').fadeOut(200,function(){
$(this).remove();
}).promise();
var request = categoryRequest(tag1,tag2,tag3);
$.when(request, removed).done(function(requestResults) {
outputData(requestResults[0]);
});
});
Use one method to trigger the function only for once.
$("#tiles").one('click','.category',function(){
$("#tiles").off('click').on('click','.category',function(){
I solutioned it like this
$('.category').fadeOut(200).promise().done(function(){
//start request when animation completed
$(".category").remove();
var nextrequest = new Request(tag1,tag2,tag3);
nextrequest.ajaxCategoryRequest();
});
I want to make a variable in a .json link
for example
http://api.wunderground.com/api/102376e7c0e1c995/geolookup/conditions/q/IA/Cedar_Rapids.json
this is a JSON that give a weather data for example I want to give to my website visitor his weather condition I want to make variable to this JSON link in country and city
for example
http://api.wunderground.com/api/102376e7c0e1c995/geolookup/conditions/q/"country variable here "/"city variable here".json
Try this:
var state = 'CA';
var city = 'San_Francisco';
var URL = 'http://api.wunderground.com/api/102376e7c0e1c995/geolookup/conditions/q/' + state + '/' + city + '.json';
$.ajax({
url: URL,
dataType: "jsonp",
success: function(parsed_json) {
var location = parsed_json['location']['city'];
var temp_f = parsed_json['current_observation']['temp_f'];
alert("Current temperature in " + location + " is: " + temp_f);
}
});
DEMO HERE