I am trying build a web page that will construct elements from JSON file and attach click function to those elements.
$(document).ready(function(){
$.ajax({
url: 'database.php',
type: "POST",
dataType: 'json',
success: function (datas) {
(datas);
for (var x = 0; x < datas.data.length; x++) {
var id = datas.data[x].ID;
var ip = datas.data[x].IP;
var ips='<div class="ip"><span id="ids">'+id+'</span><span id="number">'+ip+'</span></div>';
$('#left').append(ips);
}
}
});
$('.ip').click(function () {
alert($(this).children('#ids').text());
});
});
the code above builds the elements successfully but the click function is not working.
You can use the on function instead, it is used to apply event handlers to elements that are not yet created.
Where you have your current click setup, try something like this instead:
$(document).on('click', '.ip', function(){
alert($(this).children('#ids').text());
});
As #Pete has suggested, it is not a good idea to assign the same id attributes within a loop, they should be unique to the document. Consider finding them via class names instead, so you could alert something like:
alert($(this).children('.MyIdsSpan').text());
Related
I am very new in javascript/jQuery so please bear with me if my question will be too easy for you and too difficult for me.
This is from a function, I just don't post the complete codes since it will be too long.
And I have another function which also have an ajax and I want to pass get the ID of the <a> tag:
function someName() {
jQuery.ajax({
type: 'POST',
url: 'thisisprivate.aspx',
data: {
action: 'MyAction',
word: 'Wednesday',
count: '4',
page: '1'
},
success: function(data) {
var json = jQuery.parseJSON(data);
var htmlInfo = '';
for (i = 0; i < json.length; i++) {
var htmlCode = '';
htmlInfo = htmlInfo + htmlCode;
}
jQuery('#WMVideoxx').html(htmlInfo);
}
});
}
and
function VideoDiv() {
jQuery.ajax({
type: 'POST',
url: 'thisisprivate.aspx',
data: {
action: 'actionNameHere',
idorname: id //I Want to pass the ID here
});
}
What you are doing is:
jQuery('a').click(function() {
VideoDiv(jQuery(this).attr('id'));
});
This will not work because of the nature of <a> tag being dynamically generated and the event doesn't get registered. Consider delegating the event (see Understanding Event Delegation for more information):
jQuery(document).on("click", 'a', function() {
VideoDiv(jQuery(this).attr('id'));
});
The above code works, but will delegate for all the <a> inside the document. Instead, add a class or something that uniquely identifies that. And call it this way:
jQuery(document).on("click", 'a.class', function() {
VideoDiv(jQuery(this).attr('id'));
});
Another thing about the above delegation of code is, it is better to use a closest static parent instead of document. Since I don't know the HTML structure, I have used document. :)
Also, as Ismael Miguel says, it is better to get the id using this.id:
jQuery(".static-parent").on("click", '.class', function () {
VideoDiv(this.id);
});
The above would be the best code.
Also, it has been pointed out again, for better performance, you may replace the code with:
setTimeout(
(function () {
VideoDiv(this.id);
}).bind(this), 10
);
This will let jQuery handle the next even handler, and will execute this code on the next 10ms (when available).
use onclick="function();" with your anchor and pass arguments that you want in your function
Your htmlcode should be like this
Your VideoDiv function
function VideoDiv(id)
{
//your ajax goes here
}
Try this : you can put onclick call to a tag while creating it and pass this object which is nothing but the a tag element, see below code
var htmlCode = '';
Now make following changes in your javascript function
function VideoDiv(anchor)
{
jQuery.ajax({
type: 'POST',
url: 'thisisprivate.aspx',
data: {
action: 'actionNameHere',
idorname: anchor.id //pass id here from anchor object
}
});
}
NOTE: your data attribute in above ajax call is incomplete, please correct it.
I'm using below code. This is bootstrap 3 delete conformation message.
$(document).ready(function(){
$('a.btnDelete').on('click', function (e) {
e.preventDefault();
var id = $(this).closest('div').data('id');
$('#myModal').data('id', id).modal('show');
});
$('#btnDelteYes').click(function () {
var id = $('#myModal').data('id');
var dataString = 'id='+ id ;
$('[data-id=' + id + ']').parent().remove();
$('#myModal').modal('hide');
//ajax
$.ajax({
type: "POST",
url: "delete.php",
data: dataString,
cache: false,
success: function(html)
{
//$(".fav-count").html(html);
$("#output").html(html);
}
});
//ajax ends
});
});
This is the trigger element that I'm using
<div data-id="MYID"><a class="btnDelete" href="#">Delete</a></div>
And I'm using the same HTML element dynamically to trigger delete and it doesn't work.
Can someone point me the correct way to do it?
You have to use event delegation
$(document).on("click" , '#btnDelteYes' ,function () {
Pretty much: bind the click higher up to something that exists when the script is run, and when that something is clicked, tell it to pass the click event to the #btnDelteYes element instead
I cant understand what exactly you are doing on your code due to missing information, but the answer is: you should use event delegation on the dynamically inserted content
you can try
$('[data-id=MYID]').on('click','.btnDelteYes',function({
e.preventDefault();
var id = $(this).closest('div').data('id');
$('#myModal').data('id', id).modal('show');
});
here <div data-id="MYID"> should be a hard coded html content and The idea is to delegate the events to that wrapper, instead of binding handlers directly on the dynamic elements.
So I'm just getting started with event delegation and I'm still fairly confused by it but here goes:
I have a button which adds a rating in ajax, once clicked again I'd like it to remove the rating, here's the code with annotations (and some parts removed to make it look more clear).
$(document).on("click", '.add_rating', function() {
l.start();
var input = $(this).prev().children('.my_rating');
var score = input.val();
var what_do = input.attr('action_type');
var cur_average = $('.current_average').val();
var data = {};
data.score = score;
data.media_id = <?php echo $title_data->media_id; ?>;
data.what_do = what_do;
$.ajax({
dataType: "json",
type: 'post',
url: 'jquery/actions/add_remove_rating',
data: data,
success: function(data) {
if (data.comm === 'success') {
//do some other stuff there, irrelevant
$('.ladda-button').removeClass('btn-primary');
$('.ladda-button').removeClass('btn-sm');
$('.ladda-button').addClass('btn-danger btn-xs');
$('.ladda-label').html('Remove');
$('.ladda-button').addClass('remove_rating'); <-- add the remove rating class I want to call if the button is clicked again
input.attr('action_type', 'remove_rating');
l.stop();
}
}
});
$('.remove_rating').on('click', function() { <-- this doesn't work, why?
alert('remove was clicked');
});
});
I can't seem to trigger this:
$('.remove_rating').on('click', function() { <-- this doesn't work, why?
alert('remove was clicked');
});
Any help appreciated!
Edit: on a side note, I don't actually need this to work as php figures out if we're removing or adding a score based on the action_type attribute. I just wanted to find out why it's not triggering.
change your code to:
$(document).on("click", '.add_rating', function() {
l.start();
var input = $(this).prev().children('.my_rating');
var score = input.val();
var what_do = input.attr('action_type');
var cur_average = $('.current_average').val();
var data = {};
data.score = score;
data.media_id = <?php echo $title_data->media_id; ?>;
data.what_do = what_do;
$.ajax({
dataType: "json",
type: 'post',
url: 'jquery/actions/add_remove_rating',
data: data,
success: function(data) {
if (data.comm === 'success') {
//do some other stuff there, irrelevant
$('.ladda-button').removeClass('btn-primary');
$('.ladda-button').removeClass('btn-sm');
$('.ladda-button').addClass('btn-danger btn-xs');
$('.ladda-label').html('Remove');
$('.ladda-button').addClass('remove_rating'); <-- add the remove rating class I want to call if the button is clicked again
input.attr('action_type', 'remove_rating');
l.stop();
$('.remove_rating').on('click', function() { <-- this doesn't work, why?
alert('remove was clicked');
});
}
}
});
});
EXPLANATION:
first have a look here: Understanding Event Delegation.
event delegation is used when you need to create event handlers for elements that do not exist yet. you add a .remove_rating class to elements dynamically, however you are trying to attach a handler to elements with the above mentioned class before you even attach it.
you are attaching the class when the asynchronous ajax call returns, in the success function, however your event handler block is being processed right after you send the ajax, and not after the ajax returns (ajax is async rememeber?). therefore, you need to wait until the ajax returns and the elements are created, and only then attach the handler to them.
alternatively, using event delegation, you can attach the handler to the document, like you did in the following line:
$(document).on("click", '.add_rating', function() {
it means, that you attach the handler to the document, and whenever any element ON the document is clicked, if that element has the class '.add_rating' then execute the handler.
therefore, you may attach another handler to the document to monitor for clicks on elements with the .remove_rating class as follows:
$(document).on("click", '.remove_rating', function() {
this is called event delegation, because you delegate the event to a parent element.
Because class was added after click event initialised. You need to use live event handlers, like this:
$( document ).on('click', '.remove_rating', function() {
In this case .remove_rating click handler will work on dynamically created elements and on class name changes.
I got a problem with my Json in Javascript.
So I run json and I get a list of all youtube id's, now I show all those youtube videos and I place a button next to it. Now if I click that button it must give me a console log of the youtube id of that video but it always gives me the last youtube video id. Can anyobdy help me witht his code cause Im stuck.
Here is my code:
function generateLast5()
{
$("#musicList").html("");
console.log("what uuup");
$.ajax({
url: ".............",
dataType: "jsonp",
success: function(json){
console.log(json.played_tracks);
for(i in json.played_tracks)
{
console.log(i);
oSingle = json.played_tracks[i];
console.log(oSingle.youtube_ids.default);
phli = $("<li/>")
.appendTo("#musicList");
$("<iframe/>")
.attr("src", "http://www.youtube.com/embed/" + oSingle.youtube_ids.default)
.appendTo(phli);
$("<button/>")
.attr("id","btnAddToPlaylist")
.text("Add To Playlist")
.click(function() {
console.log(oSingle.youtube_ids.default);
})
.appendTo(phli);
}
}
});
}
There's a number of issues with your code.
First, you are creating multiple buttons that have the same id. ids should be unique (and in your case they are not needed).
Second, it is not recommended to use a for...in loop to iterate through arrays. Instead, use a for loop and the array length.
Third, you are assigning values to global variables. I would recommend local variables (e.g. var oSingle) to avoid conflicts.
Now to your issue: you always get the last id because that's what you are calling with oSingle.youtube_ids.default (cf. above comment on local variables). Instead, you could attach the id to each button:
$("<button/>")
.data("youtubeId",oSingle.youtube_ids.default)
.text("Add To Playlist")
.click(function() {
console.log($(this).data(youtubeId));
})
You should split your code up for better readability
AJAX Function
function generateLast5() {
$("#musicList").html("");
console.log("what uuup");
$.ajax({
url: ".............",
dataType: "jsonp",
success: function (json) {
load(json); // call load function here
}
});
}
Loop with proper Array for loop and set id as data attribute
function load(json) {
console.log(json.played_tracks);
for ( var i = 0; i < json.played_tracks.length; i++) { // use array loop
console.log(i);
oSingle = json.played_tracks[i];
console.log(oSingle.youtube_ids.default);
phli = $("<li/>")
.appendTo("#musicList");
$("<iframe/>")
.attr("src", "http://www.youtube.com/embed/" + oSingle.youtube_ids.default)
.appendTo(phli);
$("<button/>")
.data("id", oSingle.youtube_ids.default) // set id as data attribute
.addClass('btn') // set class here for delegation reasons instead of id, Id should be unique
.text("Add To Playlist")
.appendTo(phli);
}
}
Separate click event
$('button').on('click', '.btn', function(){
console.log($(this).data('id'));
});
I have some jquery that looks like this,
$('.career_select .selectitems').click(function(){
var selectedCareer = $(this).attr('title');
$.ajax({
type: 'POST',
url: '/roadmap/step_two',
data: 'career_choice='+selectedCareer+"&ajax=true&submit_career=Next",
success: function(html){
$('.hfeed').append(html);
$('#grade_choice').SelectCustomizer();
}
});
});
My problem is that if the user keeps clicking then the .hfeed keeps getting data appended to it. How can I limit it so that it can only be clicked once?
Use the one function:
Attach a handler to an event for the elements. The handler is executed at most once per element
If you wanted the element to only be clicked once and then be re-enabled once the request finishes, you could:
A) Keep a state variable that updates if a request is currently in progress and exits at the top of the event if it is.
B) Use one, put your code inside a function, and rebind upon completion of request.
The second option would look like this:
function myClickEvent() {
var selectedCareer = $(this).attr('title');
var that = this;
$.ajax({
type: 'POST',
url: '/roadmap/step_two',
data: 'career_choice='+selectedCareer+"&ajax=true&submit_career=Next",
success: function(html){
$('.hfeed').append(html);
$('#grade_choice').SelectCustomizer();
},
complete: function() {
$(that).one('click', myClickEvent);
}
});
}
$('.career_select .selectitems').one('click', myClickEvent);
You can either use a global variable like
var added = false;
$('.career_select .selectitems').click(function(){
if(!added) {
// previous code here
added = true;
}
});
or use .one("click", function () { ... }) instead of the previous click function to execute the handler at most once per element. See http://api.jquery.com/one/ for more details.