jQuery getting .preventDefault() to work on generated elements - javascript

I'm having a bit of a problem with getting the .preventDefault to work on some elements I am generating via JQuery.
I am getting a JSON file using the following code and putting the data into individual p elements:
$.getJSON(searchURL, function(data) {
$.each(data, function(key, value) {
if (typeof value === 'object') {
for (var i = 0; i < data.count; i++) {
var fullPlayerURL = "<p class='entry'>" + "<a href=" + playerURL + data.data[i].id + ">"
+ "Nickname - " + data.data[i].nickname + "</a>" + "</p>"
$('#results').append(fullPlayerURL);
}
}
});
}); //end getJSON
Then I'm using the following code to stop the link from redirecting when clicked (links to another JSON file):
$('.entry').click(function(event) {
event.preventDefault();
var linkClicked = $(this).attr("href");
console.log(linkClicked);
});
I don't know if it matters but #results is just an empty div.
Here's all the code if this isn't enough info (sorry it's such a mess).

You'll need delegated event handlers for dynamic elements
$('#results').on('click', '.entry', function(event){
event.preventDefault();
var linkClicked = $('a', this).attr("href");
console.log(linkClicked);
});

Sorry, I'm not allowed to comment on adeneo's answer.
For me var linkClicked = $('a', this).attr("href"); gives undefined.
I had to make var linkClicked = $(this).attr("href"); out of it.
Edit: Know it, I wanted to address the anchor.
$('#results').on('click', 'a', function(event) {
event.preventDefault();
var linkClicked = $(this).attr("href");
console.log(linkClicked);
});

Related

jquery cannot get div to show using this selector

I am querying the Twitch API for a list of users in my database, to see if they are online.
I am essentially listing them all, with "display: none" and then unhiding if online:
$('.online_list').each(function (index) {
var tnick = $(this).data('tnick');
$.getJSON("https://api.twitch.tv/kraken/streams?client_id={:twitch_key}&channel="+tnick+"", function(a) {
if (a["streams"].length > 0)
{
alert(tnick);
$(this).show();
console.log(index + ": " + $( this ).text());
}
});
});
In my testing, the alert(tnick) works perfectly, so I know it's running. The problem is $(this).show(); just isn't working.
Here's example HTML:
<div class="online_list" data-tnick="test" style="display: none;">test:Twitch <span>(Online)</span></div>
<div class="online_list" data-tnick="test2" style="display: none;">test2:Twitch <span>(Online)</span></div>
this is the current scope object!
to fix your code you can do the following:
$('.online_list').each(function (index) {
var $that = $(this); // create a temp var that
var tnick = $that.data('tnick');
$.getJSON("https://api.twitch.tv/kraken/streams?client_id={:twitch_key}&channel="+tnick+"", function(a) {
if (a && a["streams"] && a["streams"].length > 0) {
alert(tnick);
$that.show(); // use that instead of this
console.log(index + ": " + $that.text());
}
});
});
Check out this resource for more information on scope & this: http://javascriptplayground.com/blog/2012/04/javascript-variable-scope-this/
EDIT:
Also, like #djxak suggests, you can use the element parameter of the callback, that is more simple and clean in my opinion.
The #djxak suggests:
$('.online_list').each(function (index, element) {
//... (scope1 code)
$.getJSON("", function(a) {
//... (scope2 code)
$(element).show();
});
});
My approach:
$('.online_list').each(function (index) {
//... (scope1 code)
var $current = $(this);
$.getJSON("", function(a) {
//... (scope2 code)
$current.show();
});
});
Info about each function and element parameter in jQuery docs: https://api.jquery.com/each/#each-function

Adding event handler to non-existent class?

I've seen questions that relate to non-existent elements, but not non-existent classes. Here's what I want to do. When a button of class "see_answer" is clicked, I want to remove the class and replace it with "see_question". However, my click function for a button, once its class is "see_question", is not running. I have tried $(document).on("click", ".see_question", function(event ) and I have tried $(".see_question").on("click", function(event) {etc.... Thanks for the help! My code is below:
$(document).ready(function() {
// initialize variables
var lang = "javascript";
var qno = 1;
var prevText; // holds question/answer
var language = lang + ".html";
// set up tabs, and keep track of which one is clicked
$("#myTabs").tabs({
activate: function (event, ui) {
var active = $("#myTabs").tabs("option", "active");
lang = $("#myTabs ul > li a").eq(active).attr("href");
lang = lang.replace("#", "");
}
});
/* REMINDERS
actual qa part: blah_language
*/
// set up question
$.ajax({
url: language,
dataType: "html",
success: function(data) {
$("#blah_"+lang)
.text($(data).find("#1").text());
},
error: function(r) {
alert("whoops, error in initialization");
}
});
$(".next_question").on("click", function(event) {
event.preventDefault();
var id = $(this).attr("id").replace("next_question_", "");
var language = id + ".html";
var doc = "#blah_" + id;
$.ajax({
url: language,
dataType: "html",
success: function(data) {
var num = "#" + qno;
$(doc)
.text($(data).find(num).text());
qno = qno + 1;
},
error: function(r) {
alert("whoops");
}
});
prevText = "";
});
// SHOW ANSWER
$(".see_answer").on("click", function(event) {
event.preventDefault();
var id = $(this).attr("id").replace("see_answer_", "");
var prev = "#blah_" + id;
var answers = id + "_answers.html";
// Save the question
prevText = $(prev).text();
var obj = $(this);
$.ajax({
url: answers,
dataType: "html",
success: function(data) {
var num = "#" + 3;
$(prev)
.text($(data).find(num).text());
},
error: function(r) {
alert("whoops");
}
});
obj.val("See Question");
obj.removeClass("see_answer");
obj.addClass("see_question");
event.stopPropagation();
});
$(document).on("click",".see_question", function(event) {
event.preventDefault();
obj = $(this);
event.preventDefault();
var id = $(this).attr("id").replace("see_answer_", "");
var prev = "#blah_" + id;
$(prev).text(prevText);
obj.val("See Answer");
obj.removeClass("see_question");
obj.addClass("see_answer");
});
})
Click handling for .see_question elements is delegated to document. For .see_answer elements, a click handler is attached directly. Therefore, swapping the class names will have an undesirable effect.
when see_answer is in force, a click will trigger the "see_answer" handler.
when see_question is in force, a click will trigger the "see_question" handler AND the "see_answer" handler, which is still attached.
There's a number of ways to do this properly. From where you currently are, the simplest solution is to delegate click handling of .see_question and .see_answer elements to document.
$(document).on("click", ".see_answer", function(event) {
...
});
$(document).on("click", ".see_question", function(event) {
...
});
Combine the 2 handlers and figure out which version it is by hasClass() before you change the classes around
$(document).on("click", ".see_question, .see-answer", function(event ){
var $btn =$(this), isAnswer = $btn.hasClass('see_answer');
// we know which one it is so can switch classes now
$btn.toggleClass('see_answer see_question');
if(isAnswer){
/* run code for answer version */
}else{
/* run code for question version */
}
});

Jquery Json not working properly

I have the following which works fine:
$('<li><a id=' + loc.locId + ' href="/DataEntry" rel="external">' + loc.locName + '</a></li>').appendTo("#btnList");
$("#btnList a").click(function () {
alert(siteName);
localStorage["dataEId"] = $(this).attr("id");
localStorage["dataESiteName"] = siteName;
localStorage["dataESysName"] = sysName;
localStorage["dataELocName"] = $(this).text();
}
When I have the following, I can't even get to the click to display an alert message:
$.getJSON('/Home/GetLocType', { "locId": loc.locId }, function (result) {
var str = JSON.stringify(result);
if (str == '1') {
$('<li><a id=' + loc.locId + ' href="/DataEntry" rel="external">' + loc.locName + '</a></li>').appendTo("#btnList");
} else {
$('<li><a id=' + loc.locId + ' href="/DataEntry/PotableForm" rel="external">' + loc.locName + '</a></li>').appendTo("#btnList");
}
$("#btnList").listview('refresh');
});
$("#btnList a").click(function () {
alert(siteName);
localStorage["dataEId"] = $(this).attr("id");
localStorage["dataESiteName"] = siteName;
localStorage["dataESysName"] = sysName;
localStorage["dataELocName"] = $(this).text();
}
Note sure what the difference is. I need to use Json as based on value, I need to go to a either of the 2 hyperlinks.
Use event delegation since anchor is created dynamically in your ajax call or bind the event (only for the added element) inside the ajax success callback. on syntax will work if your jquery version >= 1.7 for earlier versions take a look at live
$("#btnList").on('click', 'a', function () {
alert(siteName);
localStorage["dataEId"] = $(this).attr("id");
localStorage["dataESiteName"] = siteName;
localStorage["dataESysName"] = sysName;
localStorage["dataELocName"] = $(this).text();
}
Your first syntax works because it binds the click event to the anchor that exists underneath btnList, but it doesn't bind event to the ones added during the ajax calls in a later point in time.

use JSON variable in jQuery to display more JSON variables

This is somewhat pseudo code so EDIT away. I want to make it when the user clicks on a thumb inside #placeholder DIV thumb2 is then displayed inside #imageLoad DIV. NOTE: Thumb and thumb2 are JSON items. A lot of people are saying that this can't be done with getJSON because it's an asynchronous request. If that is the case, then how can I change my script to support the request? If I am going the wrong way, please provide alternate solutions.
$.getJSON('jsonFile.json', function (data) {
var image1 = "<ul>";
for (var i in data.items) {
image1 += "<li><img src=images/items/" + data.items[i].thumb + ".jpg></li>";
}
image1 += "</ul>";
document.getElementById("placeholder").innerHTML = output;
var image2 = "<img src=images/items/" + data.items[i].thumb2 + ".jpg>";
$('li').click(function () {
document.getElementById("imageLoad").innerHTML = output;
});
});
Here is the external JSON file below (jsonFile.json):
{"items":[
{
"id":"1",
"thumb":"01_sm",
"thumb2":"01_md"
},
{
"id":"2",
"thumb":"02_sm",
"thumb2":"02_md"
}
]}
You can try something like the following:
$.getJSON('jsonFile.json', function(data)
{
$("#placeholder").html("");
var ul = $('<ul></ul>');
$('#placeholder').append(ul);
var load = $("#imageLoad");
for(var i in data.items)
{
var li = $('<li></li>');
ul.append(li);
var img = $('<img>');
img.attr("src", "images/items/" + data.items[i].thumb + ".jpg");
img.click((function(x)
{
return function()
{
load.html("<img src=images/items/" + data.items[x].thumb2 + ".jpg>");
}
})(i));
li.append(img);
}
});
Main difference is that click-handler is assigned inside the loop, so every handler receives a closure with appropriate reference to thumb2.
I think this could do the trick:
var $placeholder = $('#placeholder'),
$imageLoad = $('#imageLoad');
$.getJSON('jsonFile.json', function(data) {
var html = '<ul>';
$.each(data.items, function(i,item){
html += '<li><img src=images/items/' + item.thumb + '.jpg></li>';
});
html += '</ul>';
$placeholder.html(html);
});
$placeholder.on('click','li',function(){
$imageLoad.html($(this).html());
});
I can't understand the use of output since you are not declaring it in anyway. The eventhandler for the click event will trigger on all current and future li elements of the $placeholder which contains the DOM object with an id of placeholder.

get id of child element when parent is clicked

Hello I have seen similar posts but none answer what I want to accomplish
I made a sample here
http://jsfiddle.net/edgardo400/R6rVJ/
What i basically want is when a click happens in the parent you get the id of the child
and store it in a variable so i can pass the variable currentID to the code below otherwise I will have to replicate this code 9 times for each id from box1 to box9
jQuery(currentID).delegate("a", "hover", function(event){
var $img = jQuery(this).parent("li").find('img');
var image = jQuery(this).attr('data-img');
jQuery('.defaultimg').stop(true, true).fadeOut();
if( event.type === 'mouseenter' ) {
if($img.length){
$img.show();
}else{
jQuery(this).parent("li").append('<img id="theImg" src="' + image + '" />');
}
}else{
if($img){
$img.hide();
}
jQuery('.defaultimg').stop(true, true).fadeIn();
}
});
});
$('#boxes').on('click', function(e) {
var currentID = e.target.id;
console.log(currentID);
......rest of code
In javascript it would be:
var a = document.getElementById('#boxes');
a.onclick = function(e){
console.log(e.target.id);
}
If you only wish to make your code working and displaying on your console the box name, you should probably set
jQuery('#boxes').bind('click', function(event) {
var currentID = jQuery(event.srcElement).attr('id');
/* rest of your code */
});
You might want to do something easier
jQuery('#boxes').children().bind('click', function() {
jQuery(this).delegate...
});
Although I'm not sure why you are doing this ...
fixed http://jsfiddle.net/nxTDA/

Categories

Resources