Im fetching data from a blizzard api(working fine) and i have a jquery $each loop to retrieve the data which i then append in a ul. i want to add a button within every time the loop gives out data to an object. the problem is that when i use onclick='"+myfunction(param)+"' inside the loop, it will execute the function before i have pressed the button the onclick is attached to. when i check the browser it says onclick="undefined". here is the code:
let tid;
function reply_click(clicked_id){
console.log(clicked_id);
}
$('#searchnow').bind('click',
function (){
function kaldapiclass(){
// console.log("card");
var classSelect=$('#thisclass').val();
$.getJSON('https://us.api.blizzard.com/hearthstone/cards?
locale=en_US&access_token=hidden&class='+classSelect, function(data) {
$('#kortliste').empty();
$.each( data.cards, function(i, card) {
$()
$('#kortliste').append("<li id='" + card.id + "'><img src='" + card.image + "'><p>"+
card.name +"</p><button onclick='"+reply_click(card.id)+"'>HERE</button></li>");
});
});
};
clearTimeout(tid);
tid=setTimeout(kaldapiclass, 500);
});
ty for your time
-Morten
The code you entered will actually execute the function. So, instead of:
"<button onclick='"+reply_click(card.id)+"'>HERE</button>"
you should just define the element the way you would place it in dom:
"<button onclick='reply_click("+card.id+")'>HERE</button>"
Only the card.id should be dynamic.
I would also suggest to append html only once, this way:
var toAppend = '';
$.each( data.cards, function(i, card) {
toAppend += "<li id='" + card.id + "'><img src='" + card.image + "'><p>" + card.name + "</p><button onclick='reply_click(" + card.id + ")'>HERE</button></li>";
});
$('#kortliste').html( toAppend );
Related
I'm using jQuery to get values from ajax rest call, I'm trying to concatenate these values into an 'a' tag in order to create a pagination section for my results (picture attached).
I'm sending the HTML (divHTMLPages) but the result is not well-formed and not working, I've tried with double quotes and single but still not well-formed. So, I wonder if this is a good approach to accomplish what I need to create the pagination. The 'a' tag is going to trigger the onclick event with four parameters (query for rest call, department, row limit and the start row for display)
if (_startRow == 0) {
console.log("First page");
var currentPage = 1;
// Set Next Page
var nextPage = 2;
var startRowNextPage = _startRow + _rowLimit + 1;
var query = $('#queryU').val();
// page Link
divHTMLPages = "<strong>1</strong> ";
divHTMLPages += "<a href='#' onclick='getRESTResults(" + query + "', '" + _reg + "', " + _rowLimit + ", " + _startRow + ")>" + nextPage + "</a> ";
console.log("Next page: " + nextPage);
}
Thanks in advance for any help on this.
Pagination
Rather than trying to type out how the function should be called in an HTML string, it would be much more elegant to attach an event listener to the element in question. For example, assuming the parent element you're inserting elements into is called parent, you could do something like this:
const a = document.createElement('a');
a.href = '#';
a.textContent = nextPage;
a.onclick = () => getRESTResults(query, _reg, _rowLimit, _startRow);
parent.appendChild(a);
Once an event listener is attached, like with the onclick above, make sure not to change the innerHTML of the container (like with innerHTML += <something>), because that will corrupt any existing listeners inside the container - instead, append elements explicitly with methods like createElement and appendChild, as shown above, or use insertAdjacentHTML (which does not re-parse the whole container's contents).
$(function()
{
var query=10;
var _reg="12";
var _rowLimit="test";
var _startRow="aa";
var nextPage="testhref";
//before divHTMLPages+=,must be define divHTMLPages value
var divHTMLPages = "<a href='#' onclick=getRESTResults('"+query + "','" + _reg + "','" + _rowLimit + "','" + _startRow + "')>" + nextPage + "</a>";
///or use es6 `` Template literals
var divHTMLPages1 = `` + nextPage + ``;
$("#test").append("<div>"+divHTMLPages+"</div>");
$("#test").append("<div>"+divHTMLPages1+"</div>");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test"></div>
his is : My First JSFiddle. It just appends <li></li>. It works for LocalStorage and shows the result
$(".nav").append($("<li></li>").html(inputan));
I want append like My Second JSFiddle:
var addFolder = '<li>' +
'<div class="zf-folder">' +
'<a></a>' +
'</div>' +
'</li>';
$(".nav").append($(addFolder).html(inputan));
This works for LocalStorage, but is not showing a result when the page is reloaded. I want to use use a method like that because my code looks like this :
With append method $('.nav').append(addFolder);
How can I display LocalStorage result with my second jsFiddle method?
You had addFolder inside your submitButton click handler, hence it is only available in the handler function scope.
$(".submitButton").click(function() {
var inputan = $("#input_nameFolder").val();
// move the below variable outside of this function
var addFolder = '<li>' +
'<div class="zf-folder">' +
'<a></a>' +
'</div>' +
'</li>';
...
});
Move addFolder outside of the function and it should work.
Updated your fiddle.
Edit: To get correct index
You can add a function that returns the addFolder with the current/updated index. The same function can be used for first time rendering on page load and every time on adding item from the input.
Something like:
var count = 1;
function getNewList() {
var addFolder = '<li data-index="' + (count++) + '">' +
'<div class="zf-folder">' +
'<a></a>' +
'</div>' +
'</li>';
return addFolder;
}
You can check out here:
Edited Fiddle for index
// check for the data-index on li items in the console
I'm download data from JSON file and display button with value:
function iterateOverPrzepisy(best) {
$('#listaPrzepisow').html('');
$.getJSON('przepisy.json', function(data) {
for (var x in przepisyDost) {
$('#listaPrzepisow').append(" <div data-role=\"collapsible\"><h2>" + przepisyDost[x].nazwa + "</h2>" +
"<ul data-role=\"listview\" data-theme=\"d\" data-divider-theme=\"d\">" +
"<li>" +
"<h3>Składniki: " + przepisyDost[x].skladniki + "</h3>" +
"<p class='ui-li-desc' style='white-space: pre-wrap; text-align: justify;'>" + przepisyDost[x].tresc + "</p>" +
"<button id='ulubioneBtn' value='" + przepisyDost[x].id + "'>Ulubione</button></li>" +
"</ul>" +
"</div>");
j++;
}
})
}
When I click to button #ulubioneBtn I would like to get value from this button. So I add done to getJSON
}).done(function(data){
$('button#ulubioneBtn').click(function (event) {
console.log("Ulubione: ");
event.preventDefault();
var id = $("button#ulubioneBtn").val();
console.log("Value: " + id);
//dodajemy do ulubionych
localStorage.setItem("ulubione"+id, id);
});
});
But it's not working. When I click on button Ulubione I always get in console log value = 0
The problem seems to be that you add multiple buttons with the same id. An id of a html element should be unique.
przepisyDost does not appear to be defined at
for (var x in przepisyDost) {
? Try
for (var x in data.przepisyDost) {
Duplicate id's are appended to document at
"<button id='ulubioneBtn' value='" + przepisyDost[x].id
+ "'>Ulubione</button></li>" +
within for loop. Try substituting class for id when appending html string to document
"<button class='ulubioneBtn' value='" + data.przepisyDost[x].id
+ "'>Ulubione</button></li>" +
You could use event delegation to attach click event to .ulubioneBtn elements, outside of .done()
$("#listaPrzepisow").on("click", ".ulubioneBtn", function() {
// do stuff
})
I have created a dummy JSON and executed the same JS with a single change.
In onclick handler instead of getting button I am using $(event.target).
And it is working fine.
Please find the fiddle https://jsfiddle.net/85sctcn9/
$('button#ulubioneBtn').click(function (event) {
console.log("Ulubione: ");
event.preventDefault();
var id = $(event.target).val();
console.log("Value: " + id);
//dodajemy do ulubionych
localStorage.setItem("ulubione"+id, id);
});
Seems like first object doesn't have any id value.
Please check JSON response returned from server.
Hope this helps you in solving.
I have some html in my JS and everything but the button works. The input button appears but when I click it, nothing happens.
function updateFavourite(video) {
document.getElementById("favourite").onclick = function () {
blacklist[video["id"]] = true;
myfavourite.push(video);
var html =
"<input onclick='remove(video);' value='Remove' type='button'></input>" +
"<li class=\"saved\">" +
"<img class= \"img-rounded\" src=\"{0}\"/>" +
"<p><b title=\"{2}\"><a class=\"extendedLink\" href=\"javascript:watchFavouriteVideo(\{1}\)\"><span></span>{2}</a></b><br>" +
"by {3}<br>" +
"{4} | {5} views</p>" +
"</li>";
$("#myfavourite").prepend(html.format(video["thumbnail"],
video["id"],
video["title"],
video["uploader"],
video["length"],
video["views"]));
setVideoF(video);
}
}
Method to call:
function remove (video) {
alert('Favourites removed');
}
It looses its access to video variable, remove the onclick attribute and use jQuery to bind its event, and also use JavaScript Closure to keep the video variable safe:
function updateFavourite(video) {
var clickFunc = (function (video) {
return function () {
blacklist[video["id"]] = true;
myfavourite.push(video);
var html =
"<input class='removeButton' value='Remove' type='button' />" +
"<li class=\"saved\">" +
"<img class= \"img-rounded\" src=\"{0}\"/>" +
"<p><b title=\"{2}\"><a class=\"extendedLink\" href=\"javascript:watchFavouriteVideo(\{1}\)\"><span></span>{2}</a></b><br>" +
"by {3}<br>" +
"{4} | {5} views</p>" +
"</li>";
$("#myfavourite").prepend(html.format(video["thumbnail"],
video["id"],
video["title"],
video["uploader"],
video["length"],
video["views"]));
$("#myfavourite .removeButton").click(function () {
remove(video);
});
};
})(video);
document.getElementById("favourite").onclick = clickFunc;
}
Your code is generating a dynamic html so click event is not registering properly. A little html updated required. Use the "removeVideo"class to your button and use the jquery to
register the click event for dynamic element.
$('body').on('click','.removeVideo', function(){
$(this).val("Clicked");
});
Insted of $('body') you can use the closest(but not dynamic element) parent.
I'm trying to dynamically add buttons, and add a jQuery listening even to them.
However, I'm having troubles with JavaScript's scoping (at least I think that's it is).
This is pretty much my code:
for (var item in group) {
$('div').append("<input type='button' value='" + item + "' id = 'id" + item + "'>");
$('#id' + item).click(function() {
alert("Hello from " + item);
});
}
Now the problem is that no matter which button I click, the alert inside the event callback always uses the last item.
Now I understand why this is happening (well, roughly :P), but how I can fix it?
one way of achieving this correctly is like so
for (var item in group) {
$('div').append("<input type='button' value='" + item + "' id = 'id" + item + "'>");
(function(item){
$('#id' + item).click(function() {
alert("Hello from " + item);
});
})(item);
}
here is a jsfiddle to demonstrate http://jsfiddle.net/reefbarman/bbP64/
You can use jQuery's $.each method to iterate over the group array in the same way, but this will solve the issue for you:
$.each(group,function(i,v){
$('div').append("<input type='button' value='" + v + "' id = 'id" + v + "'>");
console.log($('#id' + v))
$('#id' + v).click(function() {
alert("Hello from " + v);
});
});
http://jsfiddle.net/ebiewener/byV9X/
I would look in to using the jQuery Delegate function.
http://api.jquery.com/delegate/
That will attach an event handler to a container. All the element events in the container will trickle up to the container and if handled will trigger the event handler.
It works for me: http://jsfiddle.net/bgt89/ but i did change your handler to use closures.
var group = ['asdf', 'rere', 'eeeee']
$(document).ready(function() {
for (var item in group) {
$('div').append("<input type='button' value='" + item + "' id = 'id" + item + "'>");
$('#id' + item).click((function(item) {
return function() {
alert("Hello from " + item);
}
})(item));
}
});
Most of answers above are correct, but unnecessarily verbose. "this" is your friend.
for (item in group) {
$('div').append("<input type='button' value='" + item + "' id = 'id" + item + "'>");
$('#id' + item).click(function() {
alert("Hello from " + this.id.slice(2) );
});
}
The easy ways: pass some event data:
for (var item in group) {
$('div').append("<input type='button' value='" + item + "' id = 'id" + item + "'>");
$('#id' + item).click({item: item}, function(event) {
alert("Hello from " + event.item);
});
}
Or use event.target or this:
for (var item in group) {
$('div').append("<input type='button' value='" + item + "' id = 'id" + item + "'>");
$('#id' + item).click(function(event) {
alert("Hello from " + event.target.id); //or this.id
});
}
I think everything is OK in your code except for using the item variable in the alert() statement.
Since the alert runs long after the for loop has finished, the alert will see the last value for item, not the one you want. If you just want to access the currently clicked on items ID, then you can just get that from the this reference rather than passing it in. Try changing your code to this:
for (var item in group) {
$('div').append("<input type='button' value='" + item + "' id = 'id" + item + "'>");
$('#id' + item).click(function() {
alert("Hello from " + this.id.slice(2));
});
}
Works here in this jsFiddle: http://jsfiddle.net/jfriend00/uyK3m/
Harmen,
Why not you jquery's live function.
It allows you to bind a function to an event on a set of objects with the jquery selector just like $('#button').click() does but also allows new elements that are appended in the future to also work with the click event. This would fit your dynamically requirement.
See the example below. I use the live function to bind click event to all elements that are a class 'testButton'. Then to get the value use the attr('value') on the $(this) because this is the element clicked.
var group = ["Test 1", "Test 2", "Test 3"];
for (var item in group) {
$('div').append("<input class='testButton' type='button' value='" +item+ "'>");
}
$('.testButton').live('click', function(e) {
alert('Hello Im From ' + $(this).attr('value'));
});
Jquery Live Function : http://api.jquery.com/live/
Working Example : http://jsfiddle.net/bbP64/12/
Hope that helps.