Dynamically replacing HTML with getJSON by click of button - javascript

I have a webpage that displays a news story in the main body, and has a side navigation bars where four other stories are listed. I am trying to use json files to swap out the html text in the main body. Each story has it's own json file. Here is my current javascript code:
$(document).ready(function() {
$("#nav_list a").click(function(evt) {
buildName = "../json_files/" + $(this).attr("title") + ".json";
alert(buildName);
document.getElementById("main").innerHTML = "";
$.getJSON(buildName, function(data) {
$.each(data, function() {
$.each(this, function(key, value) {
$("#main").append(
"<h1>" + value.title + "</h2>" +
"<img src='" + value.image + "'>" +
"<h2>" + value.month + "<br>" + value.speaker + "</h2>" +
"<p>" + value.text + "</p>";
);
}); // inner each
}); // outer each
)}; // end of getJSON
}); // end click
}); // end ready
Notes:
The alert(buildName) is for my own testing.
The next line (w. the innerHTML) should clear the current body content.
** NOTE: This works if I have the $.getJSON method commented out! Otherwise both this and my alert() are entirely ignored.
Because each store has it's own json file, I questioned the necessity of the muliple $.each methods within the getJSON. It didn't make a difference (the format I have below is from my textbook and has worked on a single json file with multiple entries).
I even tried not clearing the initial innerHTML and overwriting, but I may have had some syntax wrong. Here is that attempt:
$.getJSON(buildName, function(data) {
$.each(data, function(key, value) {
$("#main").append(
("#main h1").innerHTML.replace("<h1>" + value.title + "</h2>");
("#main img").innerHTML.replace("<img src='" + value.image + "'>");
("#main h2").innerHTML.replace("<h2>" + value.month + "<br>" + value.speaker + "</h2>");
("#main p").innerHTML.replace("<p>" + value.text + "</p>");
)
}); // endeach
)}; // end of getJSON
What do you guys think? I am absolutely stumped.

Remove the semi-colon at the end inside your .append(). Otherwise, I'm not sure. I wanted to comment this instead of answering but I lack the reputation. With your second attempt, those replace calls shouldn't be made inside the .append(). Good luck!

I think that the problem might be your json path that you construct.
Try using a standard path "../file.json" or "file.json" to check if you have the result you want or if the $.getJSON() is still ignored.
About the other errors: What is your devel. environment?
I also noticed that you have a bracket mismatched in your append function at the title part. So,
"<h1>" + value.title + "</h2>" +
would have to be changed to..
"<h1>" + value.title + "</h1>" +

I have re-created a sample of your site and it all seems to run fine using your code and .json files.
I just needed to modify the code as shown below. In this case, if you have a heading it will also clear the heading in your website.
<!--json retrieve script starts here -->
<script>
$(document).ready(function(){
$(":button").click(function() {
buildName = "../json_files/" + $(this).attr("title") + ".json";
alert(buildName);
//$("#main").empty();
document.getElementById("main").innerHTML = "";
$.getJSON(buildName, function(data){
//$.each(data, function() {
// $.each(data, function(key, value){
$("#main").append(
"<h1>" + data.title + "</h2>" +
"<img src='" + data.image + "'>" +
"<h2>" + data.month + "<br>" + data.speaker + "</h2>" +
"<p>" + data.text +"</p>"
);
// });
//});
});
});
});
</script>
<!--json script end here -->
NOTE: I have swapped the link with button to wire the event for this example.
You can also use multiple file entries in a single .json file in the format shown below:
{
"story1":"/jsonfile1.json",
"story2":"/jsonfile2.json",
"story3":"/jsonfile3.json"
}
which you would then parse with an $.each(data,function(key,value) where value would be the filename to be requested via $.getJSON so you can have multiple entries handled by a single file.

There were a few syntax errors - a parenthesis and curley bracket out of order, misplaced semi-colon, things of the like. The logic was correct.
Thanks all for the replies!

Related

How can I run a function on page load and then after click?

hi this is my very first time using jquery on any project at all. I am needing a little help if someone can
on my page i have some code to load a json file this file contains menu details for the main menu such as
name / action / poster
this is my code
var Items = "";
var flixAPI = "https://example.com/api.php?action=MAIN";
$.getJSON(flixAPI, function (data) {
$.each(data, function (i, item) {
Items += "<div class='img'>";
Items += "<a target='_blank' href='" + item.ACTION + "'>";
Items += "<img src='"+ item.POSTER +"' alt='" + item.NAME + "'>";
Items += "</a>";
Items += "<div class='desc'>" + item.NAME.substr(0, 16) + "</div>";
Items += "</div>";
});
$('#content').html(Items);
});
i can get this code working when i place it into the document ready.
my issue is after the main menu is populated and added to the page i then need to stop the page redirecting when a href link is clicked and get the value of the href link to then send another get json request to load the next page
i have tried loading the main menu on the document ready and then sticking one call into a .click binding to load the next set of items based on the href link clicked but when i try do this inside or outside the document ready the .click binded function wont work
Put the code in a named function so you can call it from both places.
function getFlix(flixAPI) {
var Items = "";
$.getJSON(flixAPI, function(data) {
$.each(data, function(i, item) {
Items += "<div class='img'>";
Items += "<a class='menu-link' target='_blank' href='" + item.ACTION + "'>";
Items += "<img src='" + item.POSTER + "' alt='" + item.NAME + "'>";
Items += "</a>";
Items += "<div class='desc'>" + item.NAME.substr(0, 16) + "</div>";
Items += "</div>";
});
$('#content').html(Items);
});
}
$(document).ready(function() {
getFlix("https://example.com/api.php?action=MAIN");
$("#content").on("click", ".menu-link", function(e) {
e.preventDefault();
getFlix(this.href);
});
});
This uses event delegation because the menu links are added dynamically. See Event binding on dynamically created elements?
You would need to identify the menu items with either classes or id's.
Then you would have to define the onClick event for each one of those who you need to fetch the JSON for.
ON the onClick event, you need to use e.stoppropagation or e.preventdefault (check the usage online) and then use ajax to fetch the JSON and populate whatever you are populating.

Avoid duplicated function call in jquery?

I have build a function getuser() in which I recieve json data from php into javascript. I call this function when document gets ready. My problem is that I am also using jquery post for live updation of that record and for that reason I have to call that function getuser() again due to this it shows duplicate result. First when document gets ready socend on jquery post function.
HTML
<!--It has onclick event-->
<button type="submit" class="btn btn-primary modify" onclick="update_user()">UPDATE</button>
JQUERY
//This is function which gets json array from php
function getuser() {
$.get("getuser.php", function (data) {
var data = JSON.parse(data);
for (var i = 0, len = data.length; i < len; ++i) {
var student = data[i];
var slash = " / ";
$("#output").append("<tr><td>" + student.name + "</td><td>" + student.gender + "</td><td>" + student.age + "</td>" +
"<td>" + student.city + "</td><td><a href='#' style='text-decoration: none' class='update' id='" + student.id + "' onclick='reply_click(this.id)'>Update</a>" + slash + "<a style='text-decoration: none' href='#'>Delete</a></td></tr>");
}
});
}
//when document gets ready it will show the record
if($(document).ready()) {
// getuser();
getuser();
}
//This is jquery post. When I click button (in html section) it will get form values and sent to php page
//in return it will call getuser() function again which results of duplicate display of record
$(document).ready(function(){
$('.modify').click(function() {
var gender = '';
if($('.male').is(':checked')){
gender='Male';
}else{
gender='Female';
}
$.post("update.php",
{name: $('.name').val(),gender:gender,city:$('.city').val(),age:$('.age').val(),id:$('.id').val()},
function (data) {
//here is the function call again
getuser();
}
);
});
});
Kindy tell me that is there any way I avoid second call in post function and the record gets update without function call again.I need to avoid duplicate result. Thanks in advance!
First off, you need to read the docs on jquery document ready, and learn the difference between a function reference and actually calling a function. document.ready expects you to pass in a function definition to be called when the page is ready. It doesn't actively tell you if the page is ready, the first way you're calling it. The second way you're calling it is actually correct.
Second, replace $("#output").append with $("#output").html, which will update/replace the contents of that element every time, instead of just adding more and more.
Your if test will always return true because document.ready returns the JQuery object. So, you are always causing the call to getuser() to happen.
You can see the return value from document.ready() here:
console.log($(document).ready());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
This is an incorrect usage of document.ready(). You don't need to write a test for document.ready, just write a callback function for that event and let the browser do it correctly for you.
Read the docs on document.ready()
Solution:
This:
//when document gets ready it will show the record
if($(document).ready()) {
// getuser();
getuser();
}
Should be this:
//when document gets ready it will show the record
$( document ).ready(getuser);
Or even:
$(getuser);
As for you getting the results a second time, just overwrite the old results instead of appending them.
This: $("#output").append(...
Should be: $("#output").html(...
All of you thanks for your suggestions. I have found the solution here by just adding $("#tbody").html(''); in getuser() before loop. Here is the code which works fine for me
function getuser() {
$.get("getuser.php", function (data) {
var data = JSON.parse(data);
$("#tbody").html('');//newly added
for (var i = 0, len = data.length; i < len; ++i) {
var student = data[i];
var slash = " / ";
$("#output").append("<tr><td>" + student.name + "</td><td>" + student.gender + "</td><td>" + student.age + "</td>" +
"<td>" + student.city + "</td><td><a href='#' style='text-decoration: none' class='update' id='" + student.id + "' onclick='reply_click(this.id)'>Update</a>" + slash + "<a style='text-decoration: none' href='#'>Delete</a></td></tr>");
}
});
}
All of you thanks again!

Creating Functions in JQuery to Avoid Writing the Same Code Again

I am currently using a Twitch API that receives information about a specific channel then prepends it to the HTML document. The code that prepends the information is used over and over. I was wondering how exactly do you create a function that could avoid repetition and be called throughout the document?
The codepen can be found here: http://codepen.io/sibraza/pen/AXRRvq
Here is the JQuery Code thats gets used repeatedly:
$("#follower-Info").prepend("<div class ='row'>" + "<div class = 'col-md-4'>" + "<img src='" + logo + "'>" + "</div>" + "<div class='col-md-4'>" + name +"</div>"+ "<div class ='col-md-4'>" + status + "</div></div>")
Would something like this work:
function addThis(){
$("#follower-Info").prepend("<div class ='row'>" + "<div class = 'col-md-4'>" + "<img src='" + logo + "'>" + "</div>" + "<div class='col-md-4'>" + name +"</div>"+ "<div class ='col-md-4'>" + status + "</div></div>")
}
And then I can could call addThis() after each $.getJSON request.
It would work, but you need to pass name, logo and status as parameters to the function. You can also remove the redundant string concatenation:
function addThis(name, logo, status) {
$("#follower-Info").prepend('<div class="row"><div class="col-md-4"><img src="' + logo + '"></div><div class="col-md-4">' + name + '</div><div class="col-md-4">' + status + '</div></div>');
}
Then you can call it from within your $.getJSON handler:
addThis('Foo', 'bar.jpg', 'online');

How to pass a variable in ajax append function (into html element with razor)?

I need to pass the Id of a object into a html element (razor part), but it doesn't recognize it. Look like the Id is not in its scope, or something. Is there a way to pass the value into the razor part of my html element in the append function?
$.ajax({
data: data,
url: url + "?searchTerm=" + data
}).success(function (response) {
console.log(response);
var table = $('#companyTable');
var tBody = table.children('tbody');
tBody.html("");
var textbox = document.getElementById("searchBar");
textbox.value = "";
tBody.append(
"<tr><td>" +response.CompanyName + " </td><td>" +
response.CompanyIdNumber + "</td><td>" +
response.CompanyTaxNumber + "</td><td>" +
"<p><button onclick=\"location.href='#Url.Action("Edit", "Company", new { #id = response.CompanyId })'\"> Edit</button></p>" +
"</td></tr>"
);
table.removeClass("hidden");
var originalTable = $('#originalTable');
originalTable.remove();
}).error(function (response) {
console.log(response);
});
}
Thank you.
I do those things this way:
+ "<p><button onclick=\"location.href='#(Url.Action("Edit", "Company"))?id=" + response.CompanyId + "'\">Edit</button>"
You are totally missing the concept of server-side rendering and browser execution. Consider this example, your server renders your js code, and just leaves all work to browser, then browser stars to execute Ajax request somehow(button click), when Ajax completed - you have a response value, but this value exists only inside browser context, so it doesn't make sense to pass value into razor, as it already done its work while rendering your file
Now, what to do? The simplest solution would be to hardcore Url of company edit by yourself, as razor simply doesn't know anything what's happening client-side, example:
location.href="/company/1/edit" //where 1 is id from Ajax request
The easiest complete solution is
public ActionResult WhateverMethod()
{
// ....
var urlHelper = new UrlHelper(this.ControllerContext.RequestContext);
response.Url = Url.Action("Edit", "Company", new { #id = response.CompanyId });
// ....
}
And
tBody.append(
"<tr><td>" +response.CompanyName + " </td><td>"
+ response.CompanyIdNumber + "</td><td>"
+ response.CompanyTaxNumber + "</td><td>"
+ "<p><button onclick=\"location.href='" + response.Url + "'\"> Edit</button></p>"
+ "</td></tr>");
Calling a Razor methods in JavaScript is going to cause you nothing but grief.
response.CompanyId is considered as string , so try by concatenating it as below
var a="location.href='#Url.Action("Edit", "Company", new{#id='"+response.CompanyId+"'})'"
response.CompanyId ( "<tr><td>" +response.CompanyName + " </td><td>" +
response.CompanyIdNumber + "</td><td>" +
response.CompanyTaxNumber + "</td><td>" +
"<p><button onclick=\""+a +"\"> Edit</button></p>" + "</td></tr>")

How to add my photostream?

I want to add my photostream to my website I have tried multiple bits of code
https://gist.github.com/willdurand/5705453 (cant find the set id)
and
jQuery.getJSON("http://api.flickr.com/services/feeds/groups_pool.gne?id=675729#N22&lang=en-us&format=json&jsoncallback=?", function(data){
jQuery.each(data.items, function(i,item){
jQuery("<img/>").attr("src", item.media.m).appendTo("#images")
.wrap("<a href='" + item.link + "'></a>");
});
});
suppose I need to find id to add the public feed to my photostream?
edit this seems to work but throws a 403.
<script>
jQuery(function(){
var apikey = 'xxxxxxx';
var userid = 'xxxxxx';
jQuery.getJSON('http://api.flickr.com/services/rest/?&method=flickr.people.getPublicPhotos&api_key='+apikey+'&user_id='+userid+'&format=json&jsoncallback=?',
function(data){
jQuery.each(data.photos.photo, function(i,item){
var purl = 'http://farm' + item.farm + '.static.flickr.com/' + item.server + '/' + item.id + '_' + item.secret + '_m.jpg';
var pid = item.id;
var container = '<div class="image-container" style="background: url(' + purl+ ');"></div>';
jQuery(container).appendTo('#images');
});
});
});
</script>
this works just have to set the images to public.
I have taken the exact code you have posted below and applied it to a JSFiddle.
jQuery.getJSON("http://api.flickr.com/services/feeds/groups_pool.gne?id=675729#N22&lang=en-us&format=json&jsoncallback=?", function(data){
jQuery.each(data.items, function(i,item){
jQuery("<img/>").attr("src", item.media.m).appendTo("#images")
.wrap("<a href='" + item.link + "'></a>");
});
});
http://jsfiddle.net/mYnQy/
The images are returned correctly and the links are working too, I would imagine that you should check that you have a div with an ID of "images" located on your page and that you have no other javascript that is causing an error on your page.
Check this by using developer tools in your browser of choice and taking a look at the Console.

Categories