This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 8 years ago.
I have filter for producttypes which is getting created as per enteries in database via ajax:
HTML Part:
<ul id="foodtype"></ul>
Ajax Code to show filter:
function showtypes(){
$.ajax({
type: "POST",
url: "ajax/incl/showtype",
data:'',
dataType : 'json',
cache: false,
success: function(records1){
$('#foodtype').html(makefoodType(records1));
}
});
}
function makefoodType(data1){
var tbl_body = "";
$.each(data1, function() {
var tbl_row = "",
currRecord = this;
$.each(this, function(k1 , v1) {
tbl_row += "<li><input type=checkbox id="+v1+" name="+v1+" />
<span style=font-size:14px>"+v1+"</span></li>";
})
tbl_body += tbl_row;
})
return tbl_body;
}
The categories are getting displayed properly but when i select checkbox then following code needs to be executed
function getFilterOptions(){
var opts = [d,de];
$checkboxes.each(function(){
if(this.checked){
opts.push(this.id);
}
return opts;
}
var $checkboxes = $("input:checkbox");
$checkboxes.on("change", function(){
var opts = getFilterOptions();
updateProducts(opts);
});
I want the ID of checkbox to be pushed to page having php code. But nothing is happening on checking checkbox.
Note: When i view source code then <ul id="foodtype"></ul> code remains inact.. No <li> elements are displayed :(
You need to use something called event delegation. Listen on the click events on the container where checkboxes are. So after you add them dynamically, the click event will get bubbled to the container.
That's because var $checkboxes = $("input:checkbox"); is getting executed before ajax is complete and hence no elements.
Change to
$(document).on("change", "input:checkbox", function() {
var opts = getFilterOptions();
updateProducts(opts);
});
and it should work.
Related
This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 2 years ago.
When I reload the page, I call ajax to get the data and display it on the screen.
<div class="empList"><ul></ul></div>
<script>
$(document).ready(function() {
$.ajax({
url: 'process.php',
method: 'post',
dataType: "json",
data: {
action: "employeelist"
},
success: function(data) {
var trHTML = '';
$.each(data, function(i, item) {
trHTML += '<li><div class="employeeShareWrap">Share</div></li>';
});
$('.empList ul').append(trHTML);
}
})
});
//clicking on the share button
$(".employeeShareWrap>a").click(function(e) {
e.preventDefault();
console.log('hi');
alert("hello");
});
// this is the second way i tried
/*
$(".employeeShareWrap>a").click(function(){
var otherInput=$(this).data("id");
alert(otherInput);
alert("hello");
});*/
<script>
As of now, I am displaying the share button for testing purposes. Now My issue is when I am clicking on the share button then I am not getting any alert. There is no error in the console.
And if I added directly in the HTML then it's working.
<li><div class="employeeShareWrap">Share</div></li>
<script type="text/javascript">
$(".employeeShareWrap>a").click(function(e){
e.preventDefault();
console.log('hi');
alert("hellow");
});
</script>
Is there any issue with my script or I am displaying it in a wrong way?
This is because the anchor tag hasn't been created yet, by the time you try to attach your listener to it. Consider using the on method instead:
$(document).on('click', '.employeeShareWrap > a', function(e){
e.preventDefault();
console.log('hi');
alert("hellow");
});
I've been wrestling with a simple JQuery event handler for hours.
My event handler fires exactly once, when the page loads, and never again no matter the event or the interaction with the select box.
When deferred, the alert (when I have one) shows the first select option. When not, the alert is blank.
All I want is for the select box to load from AJAX and for a user choice to trigger another AJAX call.
HTML:
<select id="connection" name="Connection"></select>
<div id="testme" style="background: #CCC; width:100%; height:50px;position:relative;color:red">testing</div>
Javascript:
$(document).ready(function () {
// Event handler. Tried as a separate function and as a parameter to $.on(...)
function connectionSelected() {
var str = $('#connection option:selected').text();
alert(str);
$("#testme").text(str);
}
var $connectionSelect = $('#connection');
//$connectionSelect.selectmenu(); // Tried enabling/disabling
// Tried this and all JS code inside and outside of $(document).ready(...)
$.when(
$.ajax({
dataType: "JSON",
url: '#Url.Content("~/API/ConnectionHint")', // The AJAX call (using ASP Razor) works fine
success: function(data) {
// This function is always called and works
var items = [];
$.each(data, function(key, val) {
items.push("<option value='" + key + "'>" + val + "</option>");
});
$connectionSelect.append(items.join(""));
// Tried setting up the event handler here
},
error: function() {
$connectionSelect.html('<option id="-1">none available</option>');
}
})
).then(function() {
//$("#connection option").blur(connectionSelected()).change();
$("#connection").on("change", connectionSelected());
});
});
Tried dozens of variations of the event handler, several events, inside and outside of a deferred.done and deferred.then, etc.. E.g.:
$connectionSelect.selectmenu({
change: function (event, data) {
$('#connection').change(function () {
var str = "";
$('#connection').each(function () {
str += $(this).text() + "<br>";
});
$("#testme").text(str);
});
}
});
I usually write back-end code and am familiar only with portions of JQuery, and this is driving me crazy. I've looked more than 30 related question on SO and elsewhere, e.g.
Jquery event fires once
Jquery .change() function not working with dynamically populated SELECT list
http://jqueryui.com/selectmenu/#product-selection
Any ideas are appreciated.
Instead of
$("#connection").on("change", connectionSelected());
try
$("#connection").on("change", connectionSelected);
Note that in the second one I'm passing your function handler by reference, instead of invoking it.
I have the following javascript when my script is loaded:
var current_selected_note = $('#new_note');
current_selected_note.addClass('hover active');
$('#note-item-lists').on('click', '.list-group-item', function () {
//removes the hover color from the previous selected
current_selected_note.removeClass('hover active');
// sets the currently selected equal to the selected note
current_selected_note = $(this);
// adds the hover active to the currently selected
current_selected_note.addClass('hover active');
//adds the title of the currently selected to the title input field
$('#txt_new_note_title').val($(this).find('Strong').text());
selected_note_id = $(this).get(0).id;
getNote(selected_note_id);
load_comments(selected_note_id);
});
$( "#note-item-lists").find('li').first().trigger( "click" );
Now AFTER this is loaded i click one of my buttons which has the following javascript:
$('#note-item-lists').on('click','.close',function(){
var r = confirm('Are you sure you wish to delete "'+$(this).next('div').find('.new_note_title').text()+'" ?')
if(r == true){
deleteNote($(this));
$( "#note-item-lists").find('li').first().click();
}
})
function deleteNote(button){
var id = button.closest('li').get(0).id;
$.ajax({
type: 'POST',
url: '/solo/ajax_delete',
dataType: 'json',
data: {
id: id
},
success: function (data) {
}
});
button.closest('li').remove();
}
When this happens (i debug it) and the event function is called first 1 time (adding the class correctly) but is then happens immediatly again.
Anyone tried this before?
Try this, It will call one time.
$('#note-item-lists .close').on('click',function(){
alert("Hello");
});
Try using .off()
$('#note-item-lists').on('click', '.list-group-item', function () {
$(this).off(); //add this here
This is homework, just declaring it now.
I have to load a 'quiz' via XML (completed successfully), and generate td cells (done) to display said questions (not done, test data instead).
Here is my source code for the javascript
var selected;
var $cell;
var $cell2;
$(document).ready(function() {
$("#getTitle").click(function() {
selected = $("#quizname>option:selected").text();
$("#quiztitle").html(selected+" Quiz");
$("#quiz2").html(selected+" Quiz");
murl = "quizdata.xml";
$.ajax({type:"GET",
url:murl,
success:loaddata,
cache:false,
dataType:"xml",
data:selected,
error:ajaxerror
});
});
});
var $xml;
function loaddata(respobj,status,xhr) {
//to do:
//dynamic td creation for each xml question
$("#questions").empty();
$xml = $(respobj).find("quiz:contains("+selected+")");
for (var i=0;i<$xml.attr("qnum");i++) {
$('<tr>').attr("id","questions"+(i+1)).appendTo("#questions");
$("<td>").attr("id","question"+(i+1)).appendTo("#questions"+(i+1));
$("#question"+(i+1)).html((i+1)+". "+$xml.find("question[num='"+(i+1)+"']").text());
$("#question"+(i+1)).addClass("th.thirty");
$("<td>").attr("id","blank_question"+(i+1)).appendTo("#questions"+(i+1));
$("#blank_question"+(i+1)).addClass("question");
$("#blank_question"+(i+1)).html("Put Answer Here");
$("<td>").attr("id","answer"+(i+1)).appendTo("#questions"+(i+1));
$("#answer"+(i+1)).addClass("question");
$("#answer"+(i+1)).html((i+1)+". "+$xml.find("answer[num='"+(i+1)+"']").text());
$("#answer"+(i+1)).click(selectCell);
}
}
function selectCell() {
$cell = $(this);
$cell.css("background-color","red");
for (i=0;i<$xml.attr("qnum");i++) {
$("#blank_question"+(i+1)).click(function() {
$cell2 = $(this);
$cell.css("background-color","lightgray");
temp_text = $cell.text();
temp_id = $cell.attr("id");
$cell.attr("id",$cell2.attr("id"));
$cell.text($cell2.attr('id'));
$cell2.attr("id",temp_id);
$cell2.text(temp_id);
$("#answer"+(i+1)).unbind("click");
$("#answer"+(i+1)).bind("click", function() {
selectCell();
});
});
}
}
function swapCell() {
$cell.css("background-color","lightgray");
alert($(this).attr("id"));
}
function ajaxerror(xhr,status,error) {
$("td#desc").attr("class","");
$("td#desc").html("xhr="+xhr);
$("td#desc").append("<br /><br />status="+status)
$("td#desc").append("<br /><br />error="+error);
}
My issue is (try it here: HomeWork Link) that the first time you click the first cell, swap it with the second, it works. However, it only works every OTHER click and swap, which makes me think that there are some binding issues or focus issues because I need it to swap seamlessly. Is there an obvious error in the code or am I missing a specific focus/bind event?
Thanks!
Edit: the values being displayed AFTER swapping are the cells ID attribute
After googling "jquery recursive .click binding" I found that instead of .click() I changed it to .live() and that works perfectly.
I am using jquery to add mulitple new "addTask" form elements to a "ul" on the page every time a link is clicked.
$('span a').click(function(e){
e.preventDefault();
$('<li>\
<ul>\
<li class="sTitle"><input type="text" class="taskName"></li>\
<li><input type="button" value="saveTask" class="saveTask button"></li>\
</ul>\
</l1>')
.appendTo('#toDoList');
saveTask();
});
These new nested ul elements all have an button with the same class "saveTask". I then have a function that allows you to save a task by clicking on an button with the class "saveTask".
// Save New Task Item
function saveTask() {
$('.saveTask').click(function() {
$this = $(this);
var thisParent = $this.parent().parent()
// Get the value
var task = thisParent.find('input.taskName').val();
// Ajax Call
var data = {
sTitle: task,
iTaskListID: 29
};
$.post('http://localhost:8501/toDoLists/index.cfm/Tasks/save',
data, function(data) {
var newTask = '<a>' + task + '</a>'
thisParent.find('li.sTitle').html(newTask);
});
return false;
});
}
This essentially allows the user to enter some text into a form input, hit save, and then the task gets saved into the database using ajax, and displayed on the page using jQuery.
This works fine when there is only one element on the page with the class "saveTask", but if I have more than 1 form element with the class "saveTask" it stops functioning correctly, as the variable "var task" shows as "undefined" rather than the actual value of the form input.
Don't rely on the .parent() method. Use .closest('form') instead. So the following line:
var thisParent = $this.parent().parent()
should look something like this instead:
var thisParent = $this.closest('form');
EDIT:
Based on the updated information you provided, it looks like when you're trying to register the click event handler it's failing out for some reason. Try this javascript instead as it will make use of the live event so that all the newly added items on the page will automatically have the click event autowired to them.:
$(function(){
$('span a').click(function(e){
e.preventDefault();
$('<li>\
<ul>\
<li class="sTitle"><input type="text" class="taskName"></li>\
<li><input type="button" value="saveTask" class="saveTask button"></li>\
</ul>\
</l1>')
.appendTo('#toDoList');
});
$('.saveTask').live('click', function() {
$this = $(this);
var thisParent = $this.closest('ul');
// Get the value
var task = thisParent.find('input.taskName').val();
// Ajax Call
var data = {
sTitle: task,
iTaskListID: 29
};
$.post('http://localhost:8501/toDoLists/index.cfm/Tasks/save',
data, function(data) {
var newTask = '<a>' + task + '</a>'
thisParent.find('li.sTitle').html(newTask);
});
return false;
});
});
First turn the save task into a function:
(function($){
$.fn.saveTask= function(options){
return this.each(function(){
$this = $(this);
$this.click(function(){
var thisParent = $this.parent().parent()
//get the value
var task = thisParent.find('input.taskName').val();
// Ajax Call
var data = {
sTitle: task,
iTaskListID: 29
};
$.post('http://localhost:8501/toDoLists/index.cfm/Tasks/save', data, function(data){
var newTask = '<a>' + task + '</a>'
thisParent.find('li.sTitle').html(newTask);
});
});
});
return false;
})(jQuery)
When the app starts change the saveTask selector to this:
function saveTask(){
$('.saveTask').saveTask();
}
Then on your add function:
function addTask(){
$newTask = $("<div>Some Task stuff</div>");
$newTask.saveTask();
}
This code is written very quickly and untested but essentially create a jQuery extension that handles for data submission then when ever a task is created apply the save task extension to it.
I think you're looking for the live event.
Also, your code is a little awkward, since the click event is only added when the saveTask() function is called. In fact, the saveTask() function, doesn't actually save anything, it just adds the click event to the elements with the .saveTask class.
What is your HTML structure?
It looks like your code can't find the input.taskName element.
Try setting thisParent to something like $this.closest('form'). (Depending on your HTML)
You could try wrapping your click function in an each()
ie
function saveTask(){
$('.saveTask').each (function () {
$this = $(this);
$this.click(function() {
var thisParent = $this.parent().parent()
//get the value
var task = thisParent.find('input.taskName').val();
// Ajax Call
var data = {
sTitle: task,
iTaskListID: 29
};
$.post('http://localhost:8501/toDoLists/index.cfm/Tasks/save', data, function(data){
var newTask = '<a>' + task + '</a>'
thisParent.find('li.sTitle').html(newTask);
});
return false;
});
})
}
I find this helps sometimes when you have issues with multiple elements having the same class