Adding jQuery event handlers to elements with wildcard IDs - javascript

I currently have the following in a document.ready block:
$("[id^=summaryDetailLink_]").each(function(index) {
var splitID = this.id.split("_");
this.click(alert('clicked: '+splitID[1])); //toggleDetail(splitID[1])
});
Ultimately I want to detect when a TD with an ID of "summaryDetail_" is clicked on and fire the toggleDetail function with the ID taken from the TD.ID attribute.
The above seems to generate the correct ID (the alert popsup) but is firing when the page loads rather than when I click on the element.
So problem number 1 - why is it firing on page load rather than creating a handler for click on each element and waiting for that click?
Problem number 2, in reading around this issue it seems it would be more sensible to create a single event handler on the table rather the TD then determine which TD element was clicked. How would I convert the code to do that?

Answer to first question:
$(function() {
$("[id^=summaryDetailLink_]").click(function() {
var splitID = $(this).id.split("_");
alert('clicked: '+splitID[1])
});
}
Answer to second question, you can do this:
$('table#yourtable').on('click', '[id^=summaryDetailLink_]', function(e) {
var splitID = $(this).id.split("_");
alert('clicked: '+splitID[1])
});

I think you're misunderstanding how the click handler works:
$(function() {
$("[id^=summaryDetailLink_]").click(function() {
var splitID = $(this).id.split("_");
alert('clicked: '+splitID[1])
});
}

Related

How do I get an event listener to work on an element that is added to my html via javascript?

I'm adding some HTML to my document via javascript. I also add a button to my HTML via this javascript function. I want this button to have an event listener, but this doesn't seem to work on the element added with javascript. Is it possible to fix this?
my js:
$('#content-overview li').on('click',function(){
// Clear previous videos
$('.content-overview-row').remove();
// Insert new video
var vimeoId = $(this).data('vimeo');
var html = '<li class="content-overview-row"><div class="content-overview-video"><iframe src="http://player.vimeo.com/video/'+vimeoId+'" width="950" height="534"></iframe><a id="close-video"></a></div></li>';
// Find end of row and insert detailed view
var nextRow = $(this).nextAll('.first-in-row:first');
if(nextRow.is('li')){
nextRow.before(html);
}
else{
//last row
if($(this).hasClass('first-in-row'))
{
//first item clicked in last row
$(this).before(html);
}
else{
$(this).prevAll('.first-in-row:first').before(html);
}
}
return false;
$('#close-video').click(function() {
console.log("works");
});
});
close-video is the close button I am talking about.
You need to bind the click event to an element which exists in the DOM when the page is loaded, and delegate the dynamically added element, like so:
$(document).on('click', '#close-video', function() {
...
});
You should change document for the element closest to your #close-video so that it doesn't have to bubble right up to the document.
Also, you're returning false; before the #close-video click handler, so that code would never be executed anyway. Move it outside of your #content-overview li click handler.

Dynamically generated html elements stop working

In the following code I have some comments in an array which are displayed in a div using jQuery. Each comment has an options button which works fine until I post a new comment. I tried using unique IDs for each element but it didn't work either.
When the page loads, the options buttons work; but when I submit a new comment, none of the buttons work. What am I doing wrong?
Here's my script:
var i = 0;
var comments_display= "";
var comments = ['Hello World!', 'Hello! This is a comment.'];
//reads the entire array, creates the content, and sends it to the div
function show_comments(){
for (i=0; i<comments.length; i++){
comments_display += "<div class='single_comment_container'>";
comments_display += "<div class='comment_comment'>" + comments[i] + "</div>";
comments_display += "<div class='options'>Options</div></div>";
}
$("#comment_container").html(comments_display);
comments_display = "";
}
//appends a new comment to the array
function new_comment(){
if ($("#comment_input").val() == null || $("#comment_input").val() == ""){
alert("Your comment must be at least 1 character long.");
}
else{
comments.push($('#comment_input').val());
show_comments();
$("#comment_input").val("");
}
}
$(document).ready(function(){
show_comments();
$("#submit_comment").click(function(){
new_comment();
});
//display a message when an element of the class 'options' is clicked
$(".options").click(function(){
alert("OPTIONS");
});
});
And here's a fiddle to see how it works. http://jsfiddle.net/fahKb/3/
Thank you for taking your time to read this question.
You need to use delegation:
$(document).on( 'click', '.options', function() {
alert("OPTIONS");
});
http://api.jquery.com/on/
Note: You might want to use a static element other than document. (Some parent div that's always on the page or something.)
Just because you are adding elements dynamically so click won't work on those, so you have to find the closest existing parent on the page, here in your case is this comment_container and use the .on() handler: http://jsfiddle.net/fahKb/4/
$('#comment_container').on('click',".options",function(){
alert("OPTIONS");
});
$(document).on( 'click', '.options', function() {
alert("OPTIONS");
});
This first response is right, the cause of this is that when elements are loaded into the DOM you assign event listeners. Essentially saying hey if this is 'clicked' then do something. The problem is that when adding a new element you have NOT also added the event listeners. By doing something like the above code, essentially what you're doing is a search for everything within document that then has the class of ".options" and finally if it is clicked then acting and executing some code.
With that said using document isn't the most optimum method but it is sometimes necessary. A better solution would be if you were to wrap all the comments in say a "div" or some other element then pass that in place of document. This will instead of searching the entire document for the '.options', it would only search your wrapper eliminating alot of unnecessary work.
$('.commentWrapper').on( 'click', '.options', function() {
alert("OPTIONS");
});

How to append the div element in jquery if don't exist

I am adding the form my current list in a div box at the bottom of the table.
I am appending the div box when someone clicks on add button.
But when i click add button multiple times , then many div boxes are appended.
Is there any way that no matter how many times I click the button, only one instance gets append to div box.
This is my code
$var = $(this).parent().parent();
$var.append($('.jq_div')[0].outerHTML);
attach your listener using .one().
$("button").one('click', function(){
// Your code
});
Read more: http://api.jquery.com/one
This is under the assumption that you're using jQuery 1.7+
One simple solution would be having a boolean flag that you can toggle once your button is clicked. Additionally, there is actually a jQuery function that provides this exact functionality.
It's called one() -
Attach a handler to an event for the elements. The handler is executed
at most once per element.
So your code would look something like this -
$("#someTrigger").one('click', function(){
$var = $(this).parent().parent();
$var.append($('.jq_div')[0].outerHTML);
});
The boolean method is also very simple -
var wasClicked = false;
$("#someTrigger").on('click', function(){
if (wasClicked == false){
// append your form
wasClicked = true;
}
});
Reference -
one()

how to remove all ClientEvents from anchors in an HTML String with jQuery

I've been struggling with what seems to be a simple problem for a few hours now. I've written a REGEX expression that works however I was hoping for a more elegant approach for dealing with the HTML. The string would be passed in to the function, rather than dealing with the content directly in the page. After looking at many examples I feel like I must be doing something wrong. I'm attempting to take a string and clean it of client Events before saving it to our Database, I thought jQuery would be perfect for this.
I Want:
Some random text click here and a link with any event type
//to become:
Some random text click here and a link with any event type
Here's my code
function RemoveEvilScripts(){
var myDiv = $('<div>').html('testing this Do it! out');
//remove all the different types of events
$(myDiv).find('a').unbind();
return $(myDiv).html();
}
My results are, the onClick remains in the anchor tag.
Here's a pure Javascript solution that removes any attribute from any DOM element (and its children) that starts with "on":
function cleanHandlers(el) {
// only do DOM elements
if (!('tagName' in el)) return;
// attributes is a live node map, so don't increment
// the counter when removing the current node
var a = el.attributes;
for (var i = 0; i < a.length; ) {
if (a[i].name.match(/^on/i)) {
el.removeAttribute(a[i].name);
} else {
++i;
}
}
// recursively test the children
var child = el.firstChild;
while (child) {
cleanHandlers(child);
child = child.nextSibling;
}
}
cleanHandlers(document.body);​
working demo at http://jsfiddle.net/alnitak/dqV5k/
unbind() doesn't work because you are using inline onclick event handler. If you were binding your click event using jquery/javascript the you can unbind the event using unbind(). To remove any inline events you can just use removeAttr('onclick')
$('a').click(function(){ //<-- bound using script
alert('clicked');
$('a').unbind(); //<-- will unbind all events that aren't inline on all anchors once one link is clicked
});
http://jsfiddle.net/LZgjF/1/
I ended up with this solution, which removes all events on any item.
function RemoveEvilScripts(){
var myDiv = $('<div>').html('testing this Do it! out');
//remove all the different types of events
$(myDiv)
.find('*')
.removeAttr('onload')
.removeAttr('onunload')
.removeAttr('onblur')
.removeAttr('onchange')
.removeAttr('onfocus')
.removeAttr('onreset')
.removeAttr('onselect')
.removeAttr('onsubmit')
.removeAttr('onabort')
.removeAttr('onkeydown')
.removeAttr('onkeypress')
.removeAttr('onkeyup')
.removeAttr('onclick')
.removeAttr('ondblclick')
.removeAttr('onmousedown')
.removeAttr('onmousemove')
.removeAttr('onmouseout')
.removeAttr('onmouseover')
.removeAttr('onmouseup');
return $(myDiv).html();
}

jquery onclick set paragraph/textbox value

I have unordered list of links and i am trying to get the clicked link text.
So when i click on some link i would like to display in paragraph or textbox at the bottom of my list text that is cliked.
So if I have something like this:
item1
item2
item3
If i click on item2 i would like to get it like: "You just clicked:item2 "
And i manage that with this:
jQuery(function () {
$('a').click(function () {
alert('Text is: ' + $(this).text());
});
});
But that is displaying an alert message. then i do this:
jQuery(function () {
$('a').click(function () {
var name = $(this).text();
$("p#selector").text(name);
$("input#textbox").val(name);
});
});
And it works it send text value of a link to paragraph but it disappear really fast, it show it about second and it's gone, is there any way to prevent this? To stop it from disappearing?
Try this:
jQuery(function () {
$('a').click(function (e) {
e.preventDefault();
var name = $(this).text();
$("#selector").text(name);
$("#textbox").val(name);
});
});
e.preventDefault() will prevent the link from doing whatever it is doing by default (which sounds like it could be refreshing the page...).
Here's a demo.
I've also amended your selectors - p#selector is inefficient, you should simply use #selector when selecting by ID, as documented in the jQuery API.
For id selectors, jQuery uses the
JavaScript function
document.getElementById(), which is
extremely efficient. When another
selector is attached to the id
selector, such as h2#pageTitle, jQuery
performs an additional check before
identifying the element as a match.
EDIT: As it's become apparent that the click handler isn't what you need here, try this solution:
Parse the URL to get the current page using a jQuery URL Parser, and then find the link that corresponds to the URL and get the text:
var url = "one.htm";
var linktext = $("a[href='" + url + "']").text();
$('#output').text(linktext);
Working demo of that bit (just do the URL parsing instead of setting the URL manually).
Try preventing the click event from propagating after you handle it by returning false from the function.
jQuery(function() {
$('a').click(function () {
var name = $(this).text();
$("p#selector").text(name);
$("input#textbox").val(name);
return false;
});
});
EDIT 1: Which is functionally identical to the answer provided by #Town, who beat me to it
EDIT 2: return false is not quite identical to .preventDefault() (which prevents the default event from occurring, but does not prevent other registered handlers from firing) or indeed .stopPropagation() (which stops event 'bubbling' and prevents handlers further up the DOM from firing). Returning false causes both but as #Town says, if the handler errors before returning, the default event will occur.
Basically... do what he said.

Categories