Assign id to div dynamically created from a JSON file - javascript

I want to assign dynamic id attributes to the div(s) which are being appended through JavaScript. For example:
function x() {
for (current_list = 0; current_list < data.length; current_list++) {
$("#current").append(
"<div class="card">" +
"" + data[current_list].name + "" +
"</div>");
}
}
Two cards will be appended, so I want to assign them an id which can increase if there are more numbers of arrays present in the JSON.

you probably looking for this.
function x() {
var container=$("#current");
for(var i=1;i<10;i++)
{
var id="card"+i;
var divHtml="<div class='"+id+"'>" +
""+data[current_list].name+"" +
"</div>"
container.append(divHtml);
}
}

As Rory said, here a solution using DOM traversal.
You would have to call this after appending your "cards".
$(".card").each(function(value, index){
$(value).attr("id", "card" + index);
});

if you call x() function one time you can use
function x() {
for (current_list = 0; current_list < data.length; current_list++) {
$("#current").append('<div id="card-'+current_list+'" class="card">' + data[current_list].name + '</div>');
}
}
and if you call it many time you can use this function after every call
$(".card").each(function(value, index){
$(value).attr("id", "card-" + index);
});

Related

Issue when trying to use jQuery's window.open function in combination with a for-loop to iterate through an array

Let's say I have an array of links like this:
var playlist = [
"",
"https://www.youtube.com",
"https://www.google.com",
"https://www.facebook.com",
"https://www.instagram.com"
];
And a bunch of boxes generated in the following way:
for(var i = 1; i < 5; i++) {
$(".container").append("<div class='luke luke-" + i + "'>" + "<h3 class='nummer'>Luke " + i + "</h3> " + "</div>");
}
I then want to iterate through this array to open a specific link when a box is clicked.
for(var i = 1; i < 5; i++) {
$(".luke-" + i).click(function(){
window.open(playlist[i], "_blank");
})
}
That doesn't seem to work at all, however the example below does exactly what I want.
$(".luke-1").click(function(){
window.open(playlist[1], "_blank");
})
$(".luke-2").click(function(){
window.open(playlist[2], "_blank");
})
$(".luke-3").click(function(){
window.open(playlist[3], "_blank");
})
$(".luke-4").click(function(){
window.open(playlist[4], "_blank");
})
$(".luke-5").click(function(){
window.open(playlist[5], "_blank");
})
So this works, but it's a pain in the ass to setup as I want to have 25 boxes in total and this solution offers little to no flexibility if I want to increase or decrease that amount at a later time. What am I doing wrong with the for-loop that's causing issues here?
If I use
console.log(playlist[i]);
inside of the for-loop, it simply returns "undefined" regardless of what box I click in case that helps.
You can do this much easier and simpler using a data attribute.
HTML
<div class="container"></div>
Javascript/jQuery
var playlist = [
"",
"https://www.youtube.com",
"https://www.google.com",
"https://www.facebook.com",
"https://www.instagram.com"
];
for(var i = 1; i < 5; i++) {
$(".container").append("<div class='luke' data-url='" + playlist[i] + "'>" + "<h3 class='nummer'>Luke " + i + "</h3> " + "</div>");
}
$('.luke').click(function() {
window.open($(this).data('url'));
});
Demo Here
You are not doing right.
EXAMPLE FIDDLE
var playlist = [
"https://www.youtube.com",
"https://www.google.com",
"https://www.facebook.com",
"https://www.instagram.com"
];
var container = $("#container");
for(var i = 1; i < 5; i++) {
container.append('<div class="luke" db-id="'+ i + '"><h3 class="nummer">Luke ' + i + '</h3></div>');
}
$(".luke").click(function(i){
window.open(playlist[$(this).attr('db-id')], "_blank");
});
for(var i = 1; i < 5; i++) {
$(".luke-" + i).click(function(i){
window.open(playlist[i], "_blank");
})
}
The click event will launch your function only inside the scope of the loop. This means that once the loop have finished, ( and counting from 0 to 5 is insanely fast for your computer ) there's no more function attached to your click event. In other terms, as long as i < 5, your click function will work as you expect, but after that, the click event will no longer call the function you created.
One solution could to be attach a function to the onclick attribute in the HTML like this :
for(var i = 1; i < 5; i++) {
$('<div/>', {
'class': 'luke luke-' + i,
'click': yourFunction(i)
}).appendTo(${'.container'});
$('<h3/>', {
'class':'nummer',
'html': 'Luke' + i
}).appendTo(${'.luke-'+i})
}
and then write a function like this :
function yourFunction(index){
window.open(playlist[index], "_blank");
}
Simple way by using Hyperlink
hyperlinks
Demo Here

JavaScript Callbacks for multiple functions

I'm currently trying to take results I have from an api controller, and have that json data added to a table in my razor view. I had some issues with the array I was using to fill the table not being filled with data before the table was created. I've tried to absolve that problem with callbacks, but I'm still inexperienced, and having trouble understanding from tutorials.
Here are the javascript function I have (and in order they must go 1. the $.getJson 2. the fillArray function 3. the AddToTable function) :
$(document).ready(function ()
{
$.getJSON('api/GetRestaurants/detroit').done(fillArray(data))
});
function fillArray(data, callback)
{
var restaurant =
{
Name: "",
PhoneNumber: "",
PlaceID: "",
Rating: 0,
Website: ""
};
var dataArray = new Array();
for (var k = 0; k < data.length; k++) {
restaurant.Name = data[k].Name;
restaurant.PhoneNumber = data[k].PhoneNumber;
restaurant.PlaceID = data[k].PlaceID;
restaurant.Rating = data[k].Rating;
dataArray.push(restaurant);
}
callback(AddToTable(dataArray));
}
function AddToTable(dataArray) {
document.getElementById("tbl").innerHTML =
'<tr>' +
'<th>Restaurant Name</th>' +
'<th>Restaurant PlaceID</th>'
for (var i = 0; i < dataArray.length; i++) {
+'<tr>'
+ '<td>' + dataArray[i].Name + '</td>'
+ '<td>' + dataArray[i].PlaceID + '</td>'
+ '</tr>';
}
}
The data is there, and the api controller call is successful, I just need to data to fill the array before the table uses that array.
I appreciate any help and/or comments, thanks guys :].
When you do the following:
$.getJSON('api/GetRestaurants/detroit').done(fillArray(data))
You are calling the fillArray() function and passing its result to the .done() function. Instead, you should be passing the fillArray function to the .done() function.
$.getJSON('api/GetRestaurants/detroit').done(fillArray)
I prefer to use an anonymous function when setting a callback. Then the named functions can have the signatures that make sense for them. The anonymous callback function, of course, has the signature required for it. The named functions are then called inside the anonymous callback function.
$(document).ready(function() {
$.getJSON('api/GetRestaurants/detroit').done(function(data) {
var restaurants = createRestaurantArray(data);
addRestaurantsToTable(restaurants);
});
});
function createRestaurantArray(apiData) {
var restaurants = []; // Preferred syntax over "new Array()"
for (var i = 0; i < apiData.length; i++) {
restaurants.push({
Name: apiData[i].Name,
PhoneNumber: apiData[i].PhoneNumber,
PlaceID: apiData[i].PlaceID,
Rating: apiData[i].Rating,
Website: ""
});
return restaurants;
}
function addRestaurantsToTable(restaurants) {
var html = '<tr>'
+ '<th>Restaurant Name</th>'
+ '<th>Restaurant PlaceID</th>'
+ '</tr>';
for (var i = 0; i < restaurants.length; i++) {
html += '<tr>'
+ '<td>' + restaurants[i].Name + '</td>'
+ '<td>' + restaurants[i].PlaceID + '</td>'
+ '</tr>';
}
$('#tbl').html(html);
}
Also, your fillArray() function was creating a single restaraunt object and pushing that same object to the array for each iteration of the for-loop. That means the resulting array would contain the same object over and over, and that object would have the property values set by the last iteration of the loop.
All the commands in your fillArray function appear to be synchronous (i.e. the code does not move on until they are completed) so as long as this is called before your function to add the data you should be okay.

Trouble passing entire two dimensional array as parameters in JavaScript/jQuery

I am trying to generate divs around each of the elements of a two dimensional array using the methods below. So far the code only outputs the last 3 elements in the array (the 3 elements of third nested array). I am passing the array elements as parameters using .apply. How could I modify this to output each element of the array catArray in order? And why would it only pass the last 3 as it is? Any advice would be appreciated, I am trying to understand this better. I have spent hours on this, hopefully someone can help.
Here is a codepen:
http://codepen.io/anon/pen/kzEdK
function cats(catName, catFur, catEyes) {
$("#row").html('<div>' + catName + '</div>' + '<div>' + catFur + '</div>' + '<div>' + catEyes + '</div>');
}
var catArray = [
["fluffy", "soft", "green"],
["mittens", "coarse", "fire"],
["wiskers", "none", "grey"]
];
function catGenerator() {
for (var i = 0; i < catArray.length; i++) {
var blah = catArray[i];
cats.apply(this, blah);
}
}
catGenerator();
You probably want something like:
function cats(catName, catFur, catEyes) {
// note the difference (append() instead of html())
$("#row").append('<div>' + catName + '</div>' + '<div>' + catFur + '</div>' + '<div>' + catEyes + '</div>');
}
function catGenerator() {
$("#row").html(""); // in case you wish to call catGenerator() multiple times, clear the row before appending to it
for (var i = 0; i < catArray.length; i++) {
var blah = catArray[i];
cats.apply(this, blah);
}
}
It shows only the last 3 elements because $("#row").html("...") overwrites the contents of #row three times and the value set in the last iteration remains visible. I fixed that by replacing html() with append(), which does what you want.
The problem is that you have $("#row").html() which will replace the markup within the div tag after each iteration. Consider using $("#row").append()
function cats(catName, catFur, catEyes) {
$("#row").append('<div>' + catName + '</div>' + '<div>' + catFur + '</div>' + '<div>' + catEyes + '</div>');
}
var catArray = [
["fluffy", "soft", "green"],
["mittens", "coarse", "fire"],
["wiskers", "none", "grey"]
];
function catGenerator() {
for (var i = 0; i < catArray.length; i++) {
var blah = catArray[i];
cats.apply(this, blah);
}
}
catGenerator();

For loop won't pass i variable to Jquery function inside the loop

I've a for-loop and it won't pass it's i variable or any kind of a variable into Jquery function coded to run with every loop.
for (var i = 0; i < result.length; i++) {
$('#frame-' + i + '').fadeOut(function () {
ALERT(i);
document.getElementById('frame-' + i + '').getElementsByTagName('img')[0].src = 'img/' + result.cat[i].id + '.png';
});
$('#frame-' + i + '').fadeIn();
}
I found that I can use .on or .bind functions but I've no idea how it should be done with fadeOut().
fadeOut.on() won't work.
Any suggestions to get this working?
The problem is by the time your fadeOut completes, the for loop has already completed and as such, the value of i that the fade code is reading, will always be the same (the last value).
Create a closure to pass the value of i. This gives you a local copy of i which won't be overwritten by the for loop. Also change ALERT() to alert() (Javascript is case sensitive).
for (var i = 0; i < result.length; i++) {
(function(i){
$('#frame-' + i).fadeOut(function () {
alert(i);
document.getElementById('frame-' + i + '').getElementsByTagName('img')[0].src = 'img/' + result.cat[i].id + '.png';
}).fadeIn();
})(i);
}
Closure again!!!
$.each(result, function (i, res) {
$('#frame-' + i + '').fadeOut(function () {
alert(i);
$(this).find('img').get(0).attr('src', 'img/' + res.cat.id + '.png');
}).fadeIn();
})

jQuery JSON database variable applied in Javascript

This could be an easy task but I am just learning the relationship between jQuery, JSON, and Javascript. I used jQuery to to pull from my database and create a variable called res[i].showlink which is a url. Here is part of my code for the call.
$.get("http://databasecall=json", {}, function (res) {
$.mobile.hidePageLoadingMsg();
if (res.length) {
var s = "";
for (var i = 0; i < res.length; i++) {
s += "<li><a name=" + res[i].id + " href='" + "javascript:openGoogle()" + "'>" + res[i].showlink + "</a></li>";
}
$("#showList").html(s);
$("#showList").listview("refresh")
}, "json");
The problem is that I would like reuse the res[i].showlink database variable in a javascript function (openGoogle) outside of the code above. When I go to reuse the database variable res[i].showlink, it no longer contains my data from the database. How can I reuse the variable outside of the jQuery/JSON code above? I really appreciate any suggestions. Thank you!
You are storing that value as the contents of the anchor tag, you can access it from there too.
change
javascript:openGoogle()
to
javascript:openGoogle.apply(this)
and then inside of openGoogle, you can access the value with $(this).text()
Edit
Another option is to pass the value directly as a parameter.
change
javascript:openGoogle()
to
javascript:openGoogle(" + res[i].showlink + )
and then modify
function openGoogle() {
to
function openGoogle(showlink) {
and access the value with
alert(showlink);
You need to store a reference to res outside of the get call--otherwise, it's scoped and, as you noticed, you can't access it from outside the call. Try something like this:
var globalRes = null;
$.get("http://databasecall=json", {}, function(res) {
globalRes = res;
$.mobile.hidePageLoadingMsg();
if (res.length) {
var s = "";
for (var i = 0; i < res.length; i++) {
s += "<li><a name=" + res[i].id + " href='" + "javascript:openGoogle()" + "'>" + res[i].showlink + "</a></li>";
}
$("#showList").html(s);
$("#showList").listview("refresh")
}, "json");​
After the call, globalRes will contain the value of res, but will be global, meaning you can access it from outside the get call.
save the value in the global variable:
$.get("http://databasecall=json", {}, function (res) {
window.myResult = res;
....
}
and use it afterwards
You need to store it in a variable that has scope outside of the ajax return call.
So for example you could have:
var resData;
at the top of an included javascript file
then replace your code with
$.get("http://databasecall=json", {}, function(res) {
$.mobile.hidePageLoadingMsg();
if(res.length){
resData = res;
var s = "";
for(var i=0; i<res.length; i++) {
s+= "<li><a name=" + res[i].id + " href='" + "javascript:openGoogle()" + "'>" + res[i].showlink + "</a></li>";
}

Categories