jQuery does not see my dynamically loaded checkboxes - javascript

I have written a script that will load a series of products into a div tag.
I now want to be able to filter those products using a series of checkboxes.
jquery makes a $post to an ASP page that returns an XML dataset. The first element of the data set contains a list of manufacturers in this format ara|dai|sid|alp etc. The second element contains the manufacturer names of the codes above.
I then use this script to build a list of checkboxes into a div tag.
var mc = new Array();
mc = $("manCodes",xml).text().split(",");
var manTitles = new Array();
manTitles = $("manTitles",xml).text().split(",");
for ( var i=0, len=mc.length; i<len; ++i ){
m += '<span><input type="checkbox" value="' + mc[i] + '" name="man[]" id="man_'+i+'" />' + manTitles[i] +'</span>'//mc[i];
}
manufacturers = '<div id="filter" class="man">FILTER<br />' + m + '</div>';
$(".formSelect").append(manufacturers);
This works a treat and then in the Document Ready section I have a code segment that looks for any click on a checkbox:
$(document).ready( function() {
$("input:checkbox").click(function() {
loadXML($("#sortOrder option:selected").val(),$("#limitBy option:selected").val(),$("#productGroup").val());
});
});
This is where my code falls over because any click on any checkbox is not working. Its almost like JQuery cannot see these checkboxes that it has created.
Can anybody please help how to resolve this problem please?
Cheers
Graham

You need event delegation, otherwise the event handler will not fire for dynamically inserted/removed elements. .live or .delegate are two options.
$("input:checkbox").live("click", function() {
// implementation
});
or better:
$("form").delegate("input:checkbox", "click", function() {
// implementation
});

use jQuery.live() to capture events from dynamically added elements.
Attach a handler to the event for all
elements which match the current
selector, now and in the future.
$("input:checkbox").live("click", function() {
loadXML($("#sortOrder option:selected").val(),$("#limitBy option:selected").val(),$("#productGroup").val());
});

Try:
$(document).ready( function() {
$("input:checkbox").live("click",function() {
loadXML($("#sortOrder option:selected").val(),$("#limitBy option:selected").val(),$("#productGroup").val());
});
});

Related

How do I set up an on.click for multiple generated elements?

As a student project, we are trying to build a website that gives recommendations for movies. After recommendations are generated we want the user to be able to click on any of the movie posters in order to pull up more information about that specific movie. The .on('click') currently selects all of the results which are not ideal...
As it stands this is what we have:
axios.get(omdbCall + movieTitles)
.then(function(response){
let movies = response.data.results;
for (i=0; i < movies.length; i++) {
var posterPath = movies[i].poster_path;
var movieID = movies[i].id;
var movTitle = movies[i].title;
var movImg = "https://image.tmdb.org/t/p/w92";
$('#movPoster').append('<img class="posters" src=' + movImg + posterPath + '>');
}
$(".posters").on("click", function () {
console.log("I clicked a poster!");
})
})
We also tried changing the rendered img tag to include an id based on the movie title or its imdbID. We tried using this selector for both attempts:
$("#" + movTitle)
With this change in the append function:
$('#movPoster').append('<img id=' + movTitle + ' src=' + movImg + posterPath + '>');
I expected to be able to select just one element but that ain't what's happening. I hope I explained properly and in enough detail. Any help would be greatly greatly appreciated. Thank you!
you are making .on('click') event direclty on dynamically generated html. This won't work. Because when the script was loaded initially, there is no element with class posters.
You have to use something like this
$("#not_dynamic_element").on("click", ".posters", function(){
// Code here
});
The logic is you have to select an element that is not dynamically loaded. i.e, a static element which is an ancestor of posters class.
For example say you have a div with class posters-container which is already present on page load. You are appending the img tag with class posters to this div. So you need to get click on all img tag with class posters, you could write,
$(".posters-container").on("click", ".posters", function(){
// Code here
});
Hope you understood the logic and what the issue was.
UPDATE - LOGIC ISSUE IN FIDDLE
I see what's wrong in your fiddle. I am trying to make it simple. So check this code you have written
axios.get(finalSearch)
.then(function(response){
// console.log(response);
let movies = response.data.Similar.Results;
// let posters = response.data.results.poster_path;
for (i=0; i < movies.length; i++){
// console.log(movies[i].Name);
var movArr = movies[i].Name;
var movStr = movArr.split(" ");
var movieTitles = movStr.join("+")
getMoviePosters(movieTitles);
}
})
.catch(function(err) {
console.log(err);
})
In this code you can see that you are calling the function getMoviePosters(movieTitles) inside a for loop. Your for loop contains the following line which you use to select the dynamically generated movie poster element.
$("#movPoster").on("click", function () {
console.log("I clicked a poster!");
})
So i would suggest you to call this click function after the for loop as shown below (Remove the previous code). Also add posters class to click function.
axios.get(finalSearch).then(function(response){
// console.log(response);
let movies = response.data.Similar.Results;
// let posters = response.data.results.poster_path;
for (i=0; i < movies.length; i++){
// console.log(movies[i].Name);
var movArr = movies[i].Name;
var movStr = movArr.split(" ");
var movieTitles = movStr.join("+")
getMoviePosters(movieTitles);
}
$("#movPoster").on("click", '.posters', function () {
console.log("I clicked a poster!");
})
})
reason
Maybe when the code$(".posters").on("click",...) runs while img.posters or #movPoster still not rendered in html.So the click events not triggered.
solution
You can try to move your code inner$(function() { // move your codes here });(related question!), or just add console.log($('#movPoster'), $('#movPoster .posters')) before $(".posters").on("click",...) to verify whether the target elements exist or not.
And bind the click events to #movPoster instead of img.posters。
advice
For better performance, you should refactor your code:
Bind the click events to #movPoster instead of img.posters which makes performance worser for too much events listener.
the code $('#movPoster').append(element) in the loop will cause unneccessay repaint for each loop will insert element inner #movPoster. You could rewrite it like this:
var dom = '';
for(var i=0; i<3; i++) {
dom += '<img src="">'
}
$('#movPoster').append(dom) // only insert dom 1 time, not 3 times

How do I trigger click event on dynamically created input type 'file'?

I am attempting to add an input of type 'file' to a form dynamically. Actually the end user can add as many files as they would like to a form, so an array concept is needed. I can inject dynamic elements, but I can't figure out how to dynamically invoke the click of the input element just injected. Also, need to remove the dynamic element if the user chooses cancel on the input element.
I have created a jsfiddle showing the injection but the click event never fires when the trigger is run.
How do I trigger the 'click' event after injecting this element?
jsFiddle Html
<input id='button1' type='button' value='button1'>
<div class='container'>
</div>
jsFiddle JavaScript
$(document).ready(function () {
$('#button1').on('click', function(event) {
Button1_Click(event);
});
});
function Button1_Click(event) {
var container = $('.container');
var containerChildren = $(container).children();
var containerChildrenCount = $(containerChildren).length;
var inputId = 'fileInput[' + containerChildrenCount + ']';
$('.container').append('<input id="' + inputId + '" type="file" />');
$('#' + inputId).trigger('click');
}
Try removing the [] from the inputId variable.
I got it to work in your fiddle by changing it to this
var inputId = 'fileInput-' + containerChildrenCount

Jquery mobile - Click button to add to UL

i am trying to build an application that when the user enters text into a textbox on a jquery based mobile app and clicks save it adds it to the list on the screen
so by default i won't have a list, but as the user adds an item the list should be created or if the list already exists, the new item added as a new list item.
in terms of saving it i will work on that after, for the time being i just want to dynamically append to a ul in jqm on the screen
Can someone assist with code that may help with this. it is giving me an item added saying "item undefined" however numslist is my list and txtbox is the textbox so im not sure where i am going wrong
thanks
<script>
var $txtbox = $("#txtbox").val();
var count = 0;
$("#main").live("pagecreate", function(event) {
$("#numlist").listview({create: function(event, ui) {
$("#addBtn").bind("click", function(event, ui) {
var str = "<li><a href='#'>Item " + ($txtbox) + "</a></li>";
$("#numlist").append(str);
$("#numlist").listview("refresh");
});
$("#removeBtn").bind("click", function(event, ui) {
// if (--count < 0) {
// count = 0;
// return;
// }
$("#numlist").find("li").remove();
$("#numlist").listview("refresh");
});
}});
});
</script>
Well, you can use localstorage, that way you won't need to code extra functions that save/store data.
try this:
var $lst = $('#productList');
$("#btnID").on("click",function() {
var $txtBox = $("#txtBox");
var $li = $('<li/>').html($txtBox.val());
$lst.append($li).listview('refresh');
$txtBox.val("");
});
working fiddle here: http://jsfiddle.net/REthD/21/
If I understood your question correctly, something similar to the following should work for you:
$('input[type=button]').on('click', function() {
var ul = $('#ul_id').length > 0 ? $('#ul_id') : $('<ul />', { id: 'ul_id'}).appendTo('#parent');
$('<li />').text($('#textbox').val()).appendTo(ul);
});
The first line in the event will check if the element exists, if it does, it returns that, otherwise, creates a new and appends to the specified parent element. Then, it appends a to the with the text from the textbox.
jsFiddle example

getting values from dynamic form elements with javascript

I'm creating a dynamic form with javascript which contains a drop down list and an input text as below :
$(document).ready(function() {
document.write("<FORM>");
document.write("<SELECT NAME='SelectMenu'>");
for (var i = 1; i <= 3; i++)
document.write("<OPTION>" +"one"+"</OPTION>");
document.write("<OPTION>" +"two"+"</OPTION>");
document.write("<OPTION>" +"three"+"</OPTION>");
document.write('</SELECT>');
document.write("<br>Entry <input type='text' name='myInputs[]'>");
document.write("<button onClick="ChoixDeQuestion()">Show</button>");
document.write('</FORM>');
});
The problem here is that I can't access those fields since they don't even exist in the source code of the page.
I want to get the entered text value and the selected item of the list.
So Any idea please!!
Thanks
Using document.write should be avoided. Its not a good practice.
You are using jQuery and its very easy to dynamically create elements in jQuery.
You can do something like this,
$(document).ready(function() {
var options = '';
for (var i = 1; i <= 3; i++)
options +='<option>one</option>';
options +='<option>two</option><option>three</option>';
var html = '<select>' + options + '</select><br>Entry <input type="text" name="myInputs[]" />';
var button = $('<button>Show</button>').click(function(e){
// Code to be executed when button is clicked
e.preventDefault(); // since by default button submits the form
alert('button is clicked');
});
$("<form></form>").append(html).append(button).appendTo('body');
});
jsFiddle
If you know a basic jQuery, everything is self explained, but do let me know if something bothers you :)
Instead of using the basic syntax "document.write(...)", you should use dynamic elements and creating new HTML elements.
Document.write only actually displays the text without really inserting it.
If you want to edit your HTML later on, you need the element to be created and added to the document.
Using, for example, the "CreateElement" syntax.
Here's a good tutorial to get you started on how to create a form dynamically.
Afterwards you can append elements to it, and create many more elements that way.
If you're already using jQuery, make more use of it:
$(document).ready(function() {
var form = $('<form />'),
dropdown = $('<select />', {
name: 'SelectMenu'
}),
textbox = $('<input />', {
type: 'text',
name: 'myInputs[]'
}),
button = $('<button />', {
text: 'Show'
}).on('click', ChoixDeQuestion);
for (var i = 1; i <= 3; i++) {
$('<option />', {
text: i
}).appendTo(dropdown);
}
form
.append(dropdown)
.append('<br />Entry')
.append(textbox)
.append(button)
.appendTo('body');
});
This is creating all the nodes and inserting them into the DOM in a nice way; you can also just create one big string contents with your html, and then do this:
$(contents).appendTo('body');

How to create an hyperlink whose onclick handler is an anonymous function?

I am trying to generate dynamically the onclick event handlers of the cells of a flexigrid-generated table:
// ...
preProcess: function (data) {
var rows = data.rows;
for (var i = 0; i < rows.length; ++i) {
var row = rows[i];
// If and only if this condition is true, then
// row.cell[0] must be converted into a hyperlink.
if (row.cell[1] != '0') {
// I don't want to use the href attribute, because that would
// force me to define a non-anonymous function.
row.cell[0] = '<a href="javascript:void(0)" id="E'
+ i + '">' + row.cell[0] + '</a>';
// So I'm going to try assigning the onclick attribute.
$('#E' + i).click(function () {
window.open('doc.php?q=' + this.id, 'D' + this.id,
'menubar=0,toolbar=0,directories=0,location=0,status=0,' +
'resizable=0,scrollbars=0,width=600,height=300');
});
$('#E' + i).click().id = row.cell[4];
}
}
return data;
}
// ...
However, when I click on the generated hyperlinks, they don't work. What's the problem? My use of closures? The <a> tag doesn't accept the onclick attribute?
NOTE: Since I began using jQuery, my policy is all functions shall be anonymous functions. Please don't suggest me using an ordinary function.
Sounds like what you're looking for is live():
Attach a handler to the event for all elements which match the current selector, now and in the future
In effect, it allows you to create event handlers for elements that do not exist yet.
I get the feeling you only want to make minimal changes to your current code in order to make this work. In that case, live() is your best option since your code would only change from
$('#E' + i).click(function () { ...
to
$('#E' + i).live('click', function () { ...
Create the element using jQuery (or the browser's native dom functions) and attach an event handler:
$('<a href="#" id="E' + i + '"/>').html(row.cell[0]).click(function(e) {
e.preventDefault();
// your code
});
It looks like you're creating the <a> using raw string concatenation, and then assigning it... where? If the link isn't part of the DOM, then $('linkID') won't find anything, effectively assigning your click handler to nothing. jQuery selectors only search the DOM.
Firstly, it doesn't look like you're appending your with id='#E' + i.
So, I'd guess that when you call $('#E' + i), it's returning an empty jQuery object. You can check for this by alerting $('#E' + i).length. 0 means nothing was found.
Second, you don't need to the javascript:void(0) call. Just replace it with '#' and call event.preventDefault() in your anonymous function. You'll need to pass event as a parameter to the anonymous function, as well.
You are trying to hook up the onclick event on an element that doesn't exist yet. At the time, the element only exist as text in the array, as the code hasn't been added to the DOM, the selector can't find it.
If you want to use an anonymous function for the event handler, you have to wait to hook up the event until the element has been created so that it exists as an object.
Use jQuery's live event.
For ease of seeing what's going on, I'm also adding a class to the link because I'm assuming that there's other links on the page, .
function preProcess(data) {
...
row.cell[0] = '' + row.cell[0] + '';
}
jQuery("a.clickMe").live("click", function(event) {
event.preventDefault();
window.open('doc.php?q=' + this.id, 'D' + this.id, .....
});
Disclaimer: I've never used flexigrid, but from your other comments, it appears you are able to modify the content before flexigrid puts it in the DOM.
The live event lets up hook up a single handler (anonymous or not) before the element is added to the DOM.
See: jQuery live()
.live()
Attach a handler to the event
for all elements which match the
current selector, now and in the
future
I copied your code and, after a few minor corrections, I made it work. I assumed that data was referring to a table object. Here's my code together with dummy HTML.
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js"></script>
</head>
<body>
<table id='myTable'>
<tr>
<td>x</td><td>1</td><td>a</td><td>f</td><td>p</td>
</tr>
<tr>
<td>y</td><td>2</td><td>b</td><td>g</td><td>q</td>
</tr>
</table>
<script>
function preProcess(data) {
var rows = data.rows;
for (var i = 0; i < rows.length; ++i) {
var row = rows[i];
// If and only if this condition is true, then
// row.cell[0] must be converted into a hyperlink.
if (row.cells[1] != '0') {
// I don't want to use the href attribute, because that would
// force me to define a non-anonymous function.
row.cells[0].innerHTML = '<a href="javascript:void(0)" id="E' + i + '">'
+ row.cells[0].innerHTML + '</a>';
// So I'm going to try assigning the onclick attribute.
$('#E' + i).click(function () {
window.open('doc.php?q=' + this.id, 'D' + this.id,
'menubar=0,toolbar=0,directories=0,location=0,status=0,' +
'resizable=0,scrollbars=0,width=600,height=300');
});
//$('#' + id).click().id = row.cells[4];
}
}
return data;
}
$(document).ready(function() {
preProcess(document.getElementById('myTable'));
});
</script>
</body>
</html>
My corrections were the following (I think some might be due to transcription when you were copying the code for the post):
I replaced cell with cells
I added innerHTML after the cell index
I set the link to javascript:void instead of javascript.void
I commented out the line $('#' + id).click().id = row.cells[4];, because I had no idea what it did.
With those changes it worked like a charm.
I hope this helps.

Categories

Resources