Getting a new JSON object when clicking a button (jQuery) - javascript

I'm brand new to webdev, I'm trying to build a web app that gets a new quote whenever the button #getQuote is clicked.
This is my my js code:
$(document).ready(function() {
// function get_new will get a new JSON object
function get_new() {
$.getJSON("https://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1&callback=", function(a) {
var quote = a[0].content.slice(3, -6);
var author = '- ' + a[0].title;
var my_quote = $('<i class="fa fa-quote-left"></i> ' + quote + ' <i class="fa fa-quote-right"></i>');
$('.quoteBody').html(my_quote);
$('.quoteAuthor').html(author);
// tweet the quote
$("#tweet").click(function() {
$(this).attr('href', 'https://twitter.com/intent/tweet?text=' + '"' + quote + '" - ' + author).attr("target", "_blank");
});
});
}
// calling function to appear as default
get_new();
// when clicked, get new quote
$('#getQuote').click(function() {
get_new();
});
});
Any help would be appreciated guys.
Here's the codepen for anyone interested:
https://codepen.io/tadm123/pen/YNvdyr

As others have pointed, it's just a cache issue on codepen.
Add this line to your code to set cache false:
$.ajaxSetup({ cache: false });
Be careful using this in a live environment, you dont want to affect all your ajax requests with cache:false. So I'd recommend you using a normal jQuery ajax call and set the property cache to false specifically to this function only:
$.ajax({
cache: false,
url: "/path/to/file.json",
dataType: "json",
success: function(data) {
...
}
});

Your code is 100% right. It just so happens that the browser is caching the result of the url you're accessing. I noticed that Codepen was caching the result and my browser was caching it too when I tested it with files on my computer. So after it hits that URL the first time, it thinks something along the lines of "Oh, I've already gone to this URL and I already know what the result is. So to save time, I'll just give it the same data as before."
To combat this (this might be considered hacky?), add the current time to the end of the URL (because the time will always be different) like so:
function get_new(){
var currentDate = new Date().getTime(); // create new date
$.getJSON("http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&date=" + currentDate, function(a) { // add it to end of URL
var quote = a[0].content.slice(3,-6);
var author = '- ' + a[0].title;
var my_quote = $('<i class="fa fa-quote-left"></i> ' + quote + ' <i class="fa fa-quote-right"></i>');
$('.quoteBody').html(my_quote);
$('.quoteAuthor').html(author);
// tweet the quote
$("#tweet").click(function(){
$(this).attr('href', 'https://twitter.com/intent/tweet?text='+ '"'+ quote + '" - ' + author).attr("target","_blank");
});
});
}
Also sometimes the result will come slowly, but I think that's because of the speed of the server your requesting the quotes from. Another challenge can be to have a loader show while it's getting a quote from the server.

Put cache false in your URL. This is because you are getting same data again and again
https://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1&cache=false&callback

Close... to get it to work with the console closed, the $.ajaxSetup({ cache: false }); didn't work. However, randomizing the URL did:
$.getJSON("https://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1&callback=&cache="+Math.random(), function(a) {

Related

Pinterest images returning broken after ajax call

So I'm trying to make a mini app where I can access a bunch of drawing references I pinned on my pinterest board. I managed to get ajax call to work and SOME of the images are appending but then some do not.
I originally used the url property but then everything broke so I switched to link where I managed to get some images but some were still broken. Afterward I added an if statement to weed out images that didn't have a link url.
This worked as I can see the urls popping up in the console, they just don't render images.
Does anyone have any ideas?
//on document start up
$(document).ready(function(){
//declare the global variables:
var queryURL, results, resultURL, imageHolder, image;
//create the url where we will get the images from pintrest
queryURL = "https://api.pinterest.com/v1/boards/gasulliv/concept-art-inspiration/pins/?access_token=AXHj1v5z8_oy5kcy6NtLlZaoY_XAFQ-h5sli9PNErKPqdSA7cQAAAAA&fields=id%2Clink%2Cnote%2Curl";
//empty the div
$("#images").empty();
//performing ajax call
$.ajax({
url: queryURL,
method: "GET"
}).done(function(response) {
console.log(response.data);
//creating a variable for the repsonse data
results = response.data;
//loop through the data
//this is the shorthand for a forloop
for (var i in results){
resultURL = results[i].link;
console.log(results[i].url);
if (results[i].link !== ""){
//put results in a variable and then with each loop append them to the div
imageHolder = $("<div class='imageHolder'>");
image = $("<img>").attr("src", resultURL);
imageHolder.append(image);
$('#images').prepend(imageHolder);
}
}
});
});
Figured it out.
Just a head's up if you do ever run into this problem with pinterest's api, you'll need to make sure your queryURL includes the original be sure to return it like this:
resultURL = results[i].image.original.url;
this should return the original image's url
Don't make your access token accessible to everyone !
then for readability, you can make a code like this :
var tpl = [
"<div class='results'>",
"<div class='card'>",
"<div class='card-result'>",
"<p class='pBlack20'>" + data.response.docs[i].lead_paragraph + "</p>",
"<p class='pBlack14'>" + data.response.docs[i].pub_date + "</p>",
"<a class='FontRed link' target='_blank' href='" + data.response.docs[i].web_url + "'>For more detail</a>",
"<hr>",
"</div>",
"</div>",
"</div>"
]
$('.results-content').append(tpl.join(''));

AJAX : What to do when the POST succeeds?

I've been doing a lot of searching the last few days on AJAX.
I see why I postponed learning that particular area of JavaScript, it seems a little complex.
I notice that most questions and answers are formulated around how to SEND data via POST, but I can't find any detailed examples of what to DO with the data once the POST has completed.
I want to use JavaScript rather than php to process the data server side, and I haven't found any useful Q/A. tutorials or discussion on the topic, excluding PHP. I figure I have to ask the specific question myself.
To help visualize my question I'll give the specific example that stimulates my question.
I have a file containing a list of tasks pending, and a list of tasks completed.
The functionality in this list is that when a user clicks on the task, it is inserted into a database, where it is associated with the user.
Multiple users see this page and anyone logged in can "log" a task completed by clicking on the list item. The list item also opens another page containing more details on the item and cascades to some other functions while logging the completion and user data to the database.
<h3>To Do!</h3>
<ol class="pending>
<li><a class="pending_task" href="localhost://nextstep.html">Task Three</a></li>
<li><a class="pending_task" href="localhost://nextstep.html">Task Five</a></li>
<li><a class="pending_task" href="localhost://nextstep.html">Task Six</a></li>
</ol>
On the same page is the "Completed" task list which is populated when the pending is clicked:
<h3>Completed!</h3>
<ol class="completed">
<li><a class="completed_task" href="localhost://nextstep.html">Task One</a></li>
<li><a class="completed_task" href="localhost://nextstep.html">Task Two</a></li>
<li><a class="completed_task" href="localhost://nextstep.html">Task Four</a></li>
</ol>
The code which manages that:
$(document).ready(function(){
$('.pending').on('click', function(){
evt.preventDefault();
$(this).toggleClass("pending").parent().appendTo("ol.completed");
});
});
My goal is to have the static html updated server side, when a task has been completed, so that when the page reloads or is accessed by another user, the new configuration of "Pending" vs "Completed", is current. As a friend explained, I can't just write the updated file to server from the client side, so I realized AJAX was the best solution. Send the updated information to the server and have a script on the server side rewrite the source file when a task has been clicked as complete. I have done the $_POST[key] functionality with PHP, but I have been more impressed with JavaScript so I want to learn how to do this purely in JavaScript.
Based on my new understanding, I changed the code a bit:
$(document).ready(function(){
$('.pending').on('click', function(){
evt.preventDefault();
$(this).toggleClass("pending").parent().appendTo("ol.completed");
var newData = $("ul.pending") + $("ul.completed");
console.log(newData);
var xhr = $.ajax({ //jshint ignore: line
method:'POST',
data: newData,
url:"update.js",
success: function(){
console.log("completed POST");
},
dataType: 'html',
}); //xhr
});
});
So I get this far and I'm confused by how to properly activate the receiving script so that the file is rewritten and also perhaps reload the file so that the persistence of the change is maintained.
I'm looking to understand the details of handling the POST data, without using PHP or a DATABASE. I just want to rewrite the HTML with the updated changes to the <ol> items.
If this is not the proper forum for that or there are resources that would help enlighten me, I would appreciate advice on how to find the best resources.
Thank You.
UPDATE:
I am using node.js on the server side. The HTML is being presented via an app.js so the idea of doing server side operations is deeply connected to using node.js
Update 2:
I'm a little lost in the process of the POST/response dynamic.
The script initiating the POST will get a response, of that I am clear.
So if I want the POSTEd html to be manipulated on the server side, then the response will come from the node.js indicating that the file has been rewritten, as requested by the POST? So the response can/will be a result of something I code on the server side.
My question remains though: How do I manipulate the POST data on the server side?
In PHP it is $_POST[key]. What is it in JavaScript?
And since I am sending HTML as the POST data, how should I handle it? Will it be a hash {key, value} or is it in some other form? I can't find these details in my google searching. I'm not sure how to phrase the question to get the answer I need.
And further, what triggers the node script to execute on the server side once it has been addressed y the POST call? Or am I overthinking that part?
You seem to misunderstand the server/client model. You cannot use html/javascript to change things in your server, for that you will have to use your PHP server.
You can have a javascript server with Node.js https://nodejs.org , but that will probably replace your current PHP server. You can have multiple server in different languages, but that will make your project a bit harder to maintain.
Now about the AJAX request, it's like any other http request. You will send a header with your meta data and you will receive the answer from the server. If you want the server to do something (like write to a file or DB) every time it receives an specific request, you will need to code that by yourself.
UPDATE
You edited your question, now I know you're using nodejs. Here are a few extra info that might help
1 - Take a look at this question (it's really basic stuff and might help a lot)
Basic Ajax send/receive with node.js
2 - Change this line:
var newData = $("ul.pending") + $("ul.completed");
to this:
var newData = $("ul.pending").html() + $("ul.completed").html();
3 - This question will show you how to handle POST in node How do you extract POST data in Node.js?
This was the final code I developed after coming to an understanding of AJAX:
http.createServer(function(req, res){
if ((req.method === 'POST') && (req.url === '/result')){
var body = '';
res.statusCode = 200;
res.end("Message Received!");
req.on('data', function(data){
body += data;
});
req.on('end', function () {
var suffix = getDateTime();
var output = "Links" + "_" + suffix + ".html";
// Copy the original First
fs.writeFileSync(output, fs.readFileSync("./Links.html"));
// Overwrite the original file with the updated list configuration
fs.writeFileSync("./Links.html", body, 'utf-8');
});
} else if (req.method === 'GET') { // Reorganized 2017 01 05 # 2237
// Serve the static html
var filename = req.url || "Links.html";
var ext = path.extname(filename);
var localPath = __dirname;
var validExtensions = {
".html": "text/html",
".css": "text/css",
".js": "application/javascript",
".txt": "text/plain",
".jpg": "image/jpeg",
".gif": "image/gif",
".png": "image/png",
".woff": "application/font-woff",
".woff2": "application/font-woff2",
".ico": "image/x-icon",
"" : "text/html"
};
var validMimeType = true;
var mimeType = validExtensions[ext];
if (checkMimeType){
validMimeType = validExtensions[ext] !== undefined;
}
if (validMimeType){
localPath += filename;
fs.exists(localPath, function(exists){
if (exists){
getFile(localPath, res, mimeType);
} else {
console.log("File not found: " + localPath);
res.writeHead(404);
res.end();
}
});
} else {
console.log("Invalid file extension detected: " + ext + "(" + filename + ")");
}
}
}).listen(port, serverURL);
function getFile(localPath, res, mimeType){
fs.readFile(localPath, function(err, contents){
if (!err) {
res.setHeader("Content-Length", contents.length);
if (mimeType !== undefined){
res.setHeader("Content-Type", mimeType);
}
res.statusCode = 200;
res.end(contents);
} else {
res.writeHead(500);
res.end();
}
});
}
The other relevant code:
/* jslint node: true, browser: true */ /* globals $:false */
"use strict";
var ajax_url ="/result";
$(document).ready(function(){
$('.source_link').on('click', function(){
//evt.preventDefault();
$(this).toggleClass("source_link downloaded").parent().appendTo("ol.downloaded");
var front = "<!doctype html><html>";
var head1 = "<head><link rel=\"stylesheet\" href=\"link.css\">";
var head2 = "<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js\"></script>";
var head3 = "<script src=\"links.js\"></script>";
var head4 = "<script src=\"nameanchor.js\"></script>";
var head5 = "</head><body>";
var bottom = "</body></html>";
var newData = front + head1 + head2 + head3 + head4 + head5 + "<ol class=\"pending\">" + $('ol.pending').html() +
"</ol>" + "<ol class=\"downloaded\">" + $('ol.downloaded').html() + "</ol>" + bottom;
$.ajax({
method:'POST',
data: newData,
url: ajax_url,
success: function(result, status, jqxhr){
console.log("Response: " + jqxhr.responseText);
console.log("POST status: " + status);
},
dataType: 'html',
});
});
});

problems displaying page, deleting contents and repopulating - could this be multiple binding?

I have a mobile app.
It consists of 2 screens. The first is for capturing user
credentials and the 2nd is for displaying data.
The idea is to collect the credentials on screen 1.
Then make an ajax call with the credentials to get data and present it on
screen 2 as a series of links.
Then allow the user to touch a link on screen 2. This will return the link data to the javascript and pass it to the ajax call and get more data - THEN delete all the data on screen 2 and repopulate it with the new data.
First thing I want to find out: is showing a page with mobile.changePage(), populating it, deleting the contents and then repopulating it (without another call to mobile.changePage()) a reasonable thing to do?
I'm having a problem and I think its related to how I'm using onclick in the <a>
Each time I display the most recently received data, I want to display it in an <a>. I write each onclick to call the getData routine passing it information to determine the next ajax AND whatever is being displayed in the <a>. The only way I could figure out to access that was in onclick.
Is there a better way?
I'm able to display the results of the first ajax call just fine. But things get weird with the 2nd, 3rd etc.
Sometimes I'll touch a link and I'll progress thru the screens as I expect.
Sometimes I'll touch an <a> on the 1st result screen, the 2nd result screen will display and then (without me selecting data from the 2nd screen) the 3rd screen will display.
I've looked at the logs and the getData() routine is being executed.
What could be causing this? Am I somehow not destroying all the <a> properly? Am I using onclick in a fashion its not designed for? Should I be using buttons styled to look like links instead of <a>
Here's my code:
"use strict";
var app = {
onDeviceReady: function() {
$('#startButton').click(function(){
app.getDeptsForUser();
});
},
getDeptsForUser: function(){
var parms = new Object();
parms.userName = assignedUser;
app.getData(JSON.stringify(parms),"ENDPOINT1", "Departments");
$.mobile.changePage("#index", { transition: 'slide' });
},
getData: function(paramStr, endpoint, displayHeader){
var paramStrObj = JSON.parse(paramStr);
var serverName = server + ":" + port;
var encoded = Base64().encode(paramStrObj.userName + ':' + pass);
var authType = 'Basic ' + encoded;
var option = endpoint+"?action=start&params=" + paramStr;
var URL = serverName + "/rest/bpm/wle/v1/service/"+option;
$.ajax({
url: URL,
type: "POST",
crossDomain: true,
jsonp: "callback",
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", authType);
},
success: function (result) {
console.log("MobileMockUp getData() ajax success result="+JSON.stringify(result));
if (endpoint === "ENDPOINT1"){
app.displayData(paramStr, endpoint,"Departments", result.data.data.depts.items);
}
else if (endpoint === "ENDPOINT2"){
app.displayData(paramStr, endpoint,displayHeader, result.data.data.checklists.items);
}
else if (endpoint === "ENDPOINT3"){
app.displayData(paramStr, endpoint,displayHeader, result.data.data.checks.items);
}
},
error: function(jqXHR, textStatus, errorThrown) {
alert('Unable to retrieve '+displayHeader);
},
});
},
displayData: function(currParms,currEndPt, headerText, list){
var nextEndpt;
var nextHeaderText;
var currParmsObj = JSON.parse(currParms);
if (currEndPt === "MD#getDeptsForUser"){
nextEndpt = "MD#getCheckLists";
nextHeaderText = "Check Lists";
}
else if (currEndPt === "MD#getCheckLists"){
nextEndpt = "MD#getChecks";
}
var htmlListString="";
var parmObj;
var newLink;
$('#headerText').text(headerText);
for (var i = 0; i < list.length; i++){
parmObj = new Object();
if (currEndPt === "ENDPOINT1"){
parmObj.userName=currParmsObj.userName;
parmObj.dept=list[i];
}
else if (currEndPt === "ENDPOINT2"){
parmObj.userName=currParmsObj.userName;
parmObj.dept=currParmsObj.dept;
parmObj.checklist=list[i];
}
else if (currEndPt === "ENDPOINT3"){
nextHeaderText = list[i];
}
var str = JSON.stringify(parmObj);
str = str.toString().replace(/"/g, '\\"');
newLink = "<a style='background:#ffffff;padding-top:5%;border-top: thin solid black; display:block;font-size:12px;font-weight:normal;color:#000000;text-decoration: none;' href='#' onclick='app.getData(\""+str+"\",\""+nextEndpt+"\",\""+nextHeaderText+"\")'><pre>" + list[i] + " </pre></a><br>";
htmlListString=htmlListString+newLink;
}
$('#taskListUL').empty();
$('#taskListUL').append(htmlListString);
}
};
Could this be multiple binding?
i figured out it was multiple bindings

Rewrite URL hash to get variable

I am working on a site that has dynamic content.
When you click an article, it changes to address using the push state.
Example:
http://www.some-site.com/news/ - Before clicking a news item
http://www.some-site.com/news/dynamic-url/ - after clicking news item
But as pushstate does not work in IE or older browsers, I've rewritten it to use jQuery.address so it changes the hash in the url instead only for IE.
The problem now, is say someone sends a link to the site to a friend that they copied from Chrome and their friend uses IE, it will start appending the new has to that url.
Example:
http://www.some-site.com/news/dynamic-url/ - URL sent to friend
http://www.some-site.com/news/dynamic-url/#!/dynamic-url - URL after friend visits the site
So, I'm stuck on how to rewrite/redirect them. As, the hash never gets sent to Apache.
I've seen on twitter, they do exactly what I want, but I am unable to figure out how.
https://twitter.com/#!/google gets redirected to https://twitter.com/google and it works in IE.
Any help is much appreciated and if you don't understand please ask me to elaborate.
As suggested by David Thomas, here is the function.
var permalink = function(title, id, permalink){
var current = siteUrl + type + (order ? '/orderBy/' + order : '');
var newUrl = current + '/' + permalink + '/';
if(jQuery.browser.msie){
newUrl = '/' + permalink + '/';
jQuery.address.value(newUrl);
}
else{
stateNum++;
window.history.pushState({state: stateNum}, title, newUrl);
}
jQuery('title').html('SITE - ' + title);
}
What you need to do is either use a plugin (like jquery history) or make an event yourself to check the hash changes. Then, you read the hash (you strip the "!") and then handle the hash how ever you need. You might want to do ajax with it (such as load the domain / hash) and put the content somewhere on the page.
Is that clear?
After thinking it through for a while, I could only find one solution.
I'll post it here in case anyone is in a similar situation.
My solution, was a little hacky. If the browser is IE and has a fragment of url after a certain point, I count that as the name of news item. Once I have the name, I redirect them to the suitable url.
var permalink = function(title, id, permalink){
var current = siteUrl + type + (order ? '/orderBy/' + order : '');
var newUrl = '/' + permalink + '/';
if(jQuery.browser.msie){
jQuery.address.value(newUrl);
}
else{
current = siteUrl + type + (order ? '/orderBy/' + order : '');
newUrl = current + '/' + permalink + '/';
stateNum++;
window.history.pushState({state: stateNum}, title, newUrl);
}
jQuery('title').html('SITE - ' + title);
}
jQuery(document).ready(function(){
jQuery.address.crawlable(true);
if(jQuery.browser.msie){
if(jQuery.address.value() == '/'){
var currentPermalink = window.location.toString();
currentPermalink = currentPermalink.split(type);
if(currentPermalink[1] !== '/'){
window.location = siteUrl + type + '/#!' + currentPermalink[1];
jQuery.address.value(newUrl);
}
}
}
});

jquery, json and xml

I have a database at zoho creator. They feed me a json of the database content. I have trouble to parse and display that data with jquery or php or in html
Question : So how do I capture json data, and save (convert) it to file as XML. With the xml file I can parse it with jquery xpath easily... the "file" will be a local database, as a backup (if saved)
anybod have clue on that ?
as request.. here is the link for the query -link-
getting a way to display data from var i need is the minimum i must have !
like prod_categorie or prod_nom
note :
i can get help with any tutorial on
how to get xml data from zoho
any json to xml converter (jquery)
out there ?????
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
</head>
<body>
<div id="Liste_output"></div>
<script type="text/javascript">
jQuery.ajax({
url: "http://creatorexport.zoho.com/marcandremenard/application-lemieux/json/Liste_produits_View1/7GWhjVxYeNDePjPZnExCKy58Aqr21JX2hJEE6fAfgfkapEQnRjRd5RUy8wdjKuhmFEhJR9QRsBCUBjACAdSgmJNQSvxMt6geaMNC/",
dataType: "json",
success: function(data) {
var Liste_div = jQuery("#Liste_output");
var Liste_data = data["Liste_des_produits1"];
for (var i=0; i<Liste_data.length; ++i) {
var prod_i = Liste_data[i];
Liste_div.append('<div>' +
'<div>Nom: <span>' + prod_i["prod_nom"] + '</span></div>' +
'<img src="/images/prod/'+ prod_i["prod_photo"] +'"/>' +
'<div>Description: <span>' + prod_i["prod_desc"] + '</span></div>' +
'<div>Ingredient: <span>' + prod_i["prod_ingredient"] + '</span></div>' +
'<div>Odeur: <div class="odeur_cls"></div></div>' +
'<div>Certification: <div class="cert_cls"></div></div>' +
'</div>');
var odeur_data = prod_i["prod_odeur"];
for (var j=0; j<odeur_data.length; ++j) {
jQuery('#Liste_output odeur_cls').eq(j).append('<span>' +
odeur_data[j] + '</span>' + (j<odeur_data.length-1 ? ', ' : ''));
}
var cert_data = prod_i["prod_certification"];
for (var k=0; k<cert_data.length; ++k) {
jQuery('#Liste_output cert_cls').eq(k).append('<div>' + cert_data[k] + '</div>');
}
}
}
});
</script>
</body>
</html>
This will not work from a local file. The HTML must be served from the same domain as the database query, that is, it must be served from http://creatorexport.zoho.com (you can put it in the app subfolder)
– OR –
You must read the zoho docs and find out how to do a "callback" (sometimes called "JSONP"). Usually this is done by adding something like ?callback=data to the end of the URL.
Firstly, Javascript has no file-output capability. The best it can do is send data back to a server for processing there -- so the "capture json data, and save it to file as XML" idea is out.
What problems in particular are you having with using JSON? As it gets converted to a native Javascript object, I find it quite easy to work with myself. Though, I can see that if you wanted to use XPath to query it, JSON is no help. You should still be able to get to whatever data you need, but it might be a bit more verbose.
In your example JSON:
{"Liste_des_produits1":[{"Added_Time":"28-Sep-2009 16:35:03",
"prod_ingredient":"sgsdgds","prod_danger":["sans danger pour xyz"],"prod_odeur"..
You could access the prod_danger property like this:
$.getJSON(url, function(data) {
var danger = data.List_des_produits1[0].prod_danger;
});
If you are having trouble getting the right path to a property, Firebug is a great help with this. Just call this:
$.getJSON(url, function(data) {
console.log(data);
});
...and then you can browse through its properties in a tree-structure.
There are jQuery pluggins for such convertion, for example json2xml.

Categories