dynamic selectors added when a function is performed - javascript

I am echoing some php lines with some class id and need to be able to use them with jquery .click as the selector. Is there a way to do this?? The property is not loaded with everthing else, it is added later on by php.
play.js-
$(".link").click( function(){
/* var l = ""
$.post('input_commands/move_to.php',{l:l}, function(data) {
text=data;
elem = $("#placeholder");
//delay=100;
addTextByDelay(text,elem,delay);
}); */
alert("omg whyyyyy");
});
get_locations.php -
if($array_loc['loc_north']>0){echo "<a class='link' id='location_north'>Go north to ".$array_loc_north['loc_name']."</a> <br>";}

You need to use a delegated event because your elements are added to the DOM dynamically (or after the event handler is created).
$(document).on('click', '.link', function(){
console.log("clicked");
});
In the above, the event is delegated to the document and so all clicks will be checked against the .link selector, even if the target is an element that didn't exist when the event was delegated.

in order to bind an event to a dynamic element (one that was added after first DOM load),
replace:
$(".link").click( function(){
with:
$(document).on('click', '.link', function(){
hope that helps.

If it's added dynamically using ajax you might want to call that selector and append the .click() on the callback.
$.ajax({
url: '...',
success: function(response) {
// do stuff with response (assume that .link will be appended)
$(".link").click( function(){
//stuff when click link
}
}
});
Otherwise, you can output the links with the onclick attribute and define a custom function:
if($array_loc['loc_north']>0){echo "<a class='link' id='location_north' onclick='customFunction(this)'>Go north to ".$array_loc_north['loc_name']."</a> <br>";}
and in the JS:
function customFunction(element) {
//do stuff here after the link was clicked
//element variable passed as parameter contains the link element clicked
}
PS: If there are multiple elements it's not ok to specify constant value for "id" attribute because it should be unique.

Related

Jquery change class on click not working

I have those codes that i use on click to change classes
$(document).ready(function(){
$("div.add").click(function(e){
$.ajax({url: "?action=add&postid=" + $(this).parents('div.box').first().attr("id")})
$(this).removeClass('add').addClass('remove');
});
});
$(document).ready(function(){
$("div.remove").click(function(e){
$.ajax({url: "?action=remove&postid=" + $(this).parents('div.box').first().attr("id")})
$(this).removeClass('remove').addClass('add');
});
});
When i click first time the div class changes from <div class="add"> to <div class="remove"> and the ajax url works, but when i click again from the changed class nothing happens. ( it doesn't change back to add class )
If the element that you want to listen for events to do not exist yet when you attach the event handlers, it is better to attach the event handlers using the .on method. In your case, you can do it like this:
$(document).on('click', '.add', function() { ... });
$(document).on('click', '.remove', function() { ... });
This is called event delegation, which (in my own understanding) attaches event handlers to an element up above in the DOM tree which is sure to exist once the page loads. Events will bubble up the DOM tree (unless prevented), executing all the event handlers in the elements that they pass by.
Probably that's because on document ready event there is no div element with class of remove, so your $("div.remove") returns an empty collection. One option for solving the issue is using the event delegation technique:
$(document).on('click', 'div.remove', function() {
// ...
});
But in this case I suggest using the hasClass and toggleClass methods for toggling and checking the class names:
$(document).ready(function() {
$("div.add").click(function(e) {
var add = $(this).toggleClass('add remove').hasClass('add'),
id = $(this).closest('div.box').attr("id"),
action = add ? 'add' : 'remove',
url = '...';
$.ajax({
url: url
})
});
});

'.on' click not running function?

I have a function that when it runs new markup is generated on the fly...
$('.search input[type="image"]').on('click', function(){
// Open directions in a map
if($('#TXT_SAddr').val() === ''){
return false;
$('.directions .search').css('background' , '#ff0000');
} else {
var from = $('#TXT_SAddr').val();
var to = $('.postal-code').html();
var directions = 'http://maps.google.com/maps?saddr=' + from + '&daddr=' + to + '&output=embed';
var modal = '<div class="apply-modal modal"><a class="close-apply-now" style="margin-bottom: 20px;"><img src="http://site.co.uk/images/closeModal.png" alt="Close" style="border-width:0px;"></a><div class="holder"><iframe src="'+directions+'" style="border:none; width:100%; height:500px;" border="0"></iframe></div></div>';
$('body').prepend('<div class="modalOverlay"/>' + modal);
$('.modal').animate({
'opacity': 1,
'top': '100px'
}, 700, 'easeOutBack');
}
return false;
});
If you can see, the above generates a div with an anchor under the class name of 'close-apply-now'.
I now want to bind a function to this and I've tried using...
$('a.close-apply-now').on('click', function(){
alert('asdasd');
});
with no luck, can anybody see where I may be going wrong? Not even my alert is working.
Since the close-apply-now div is added dynamically, you need to use event delegation to register the event handler like:
// New way (jQuery 1.7+) - .on(events, selector, handler)
$('body').on('click', 'a.close-apply-now', function(event) {
event.preventDefault();
alert('asdasd');
});
This will attach your click event to any anchors with class close-apply-now within the body element.
The syntax for event delegation is slightly different.
The event need to be bind to an element which is already existing in the dom while the target element selector needs to be passed as the second argument
$(document).on('click', 'a.close-apply-now', function(){
alert('asdasd');
});
The close-apply-now div is added dynamically. You have to add the selector parameter, otherwise the event is directly bound (doesn't work for dynamically loaded content) instead of delegated. See http://api.jquery.com/on/#direct-and-delegated-events
Change your code to
$(document.body).on('click', '.update' ,function(){
The jQuery set receives the event then delegates it to elements matching the selector given as argument. This means that contrary to when using live, the jQuery set elements must exist when you execute the code.
Use jQuery's live() method. Description: Attach an event handler for all elements which match the current selector, now and in the future.
$("a.close-apply-now").live("click", function(){
alert('asdasd');
});
Try Both in Jsfiddle

Update div id in jquery so script can only run once

I currently have a script that I am using in my website. The goal of the script is when the user clicks the link, the javascript function will fire. This function is based off of the div id. At the end of the function I use jquery to change said div id. However, when the user clicks the link again the function still fires, even though the id has changed. What am I doing wrong? How can I get the script to only execute the first time the link is clicked?
$("#down").click(function(){
var id = $("#down").attr("class");
$.ajax({
type: "POST",
url: "vote.php",
data: "side=down&id=" + id,
success: function(){ alert("lul worked"); }
});
$('.' + id + '#down').attr('id', 'down_stay');
});
Now that you all have answered, what is the better choice, using "one" or using "unbind"?
Don't use click, use on. Or in your case, one:
$('#down').one('click', function() {
// function only fires once and then is unbound.
});
Use $("#down").one("click", function(){}); instead to make it fire only once.
Use unbind() instead.
replace
$('.' + id + '#down').attr('id', 'down_stay');
with
$( this ).unbind( 'click' );
Try using one
$("#down").one('click', function(){
The DOM events are attached to the elements and not to the attributes.
So even if you change the attributes of the element it does not mean it is a different element.
The event will only be removed if that particular element will be removed from the DOM..

Trapping all `a` clicks including ones added dynamcally

I know you can bind to click events with jQuery like so:
$('a').click(function(){});
But what about html elements that are added dynamically? Lets say I have a div with the following contents:
<div>
<a href='location.html'>location</a>
</div>
Now I call:
$('a').click(
function(){
console.log("going to " + $(this).attr('href'));
return true;
});
And that will work fine. But if somewhere along the line I call
$('div').("<a href='location2.html'>location2</a>");
without explicitly binding that event handler to that event then the event handler will pick up on it.
Is it possible to rebind when ever a new a element is added. Or even better, when ever the location.href property is changing so I can add a get parameter to it every time.
For example if I was binding to a click event on an a element the event handler would be:
function(){
var newid = parseInt(Obj.Request('pageid'), 10) + 1;
location.href = $(this).attr('href') + '?pageid=' + newid.toString();
return false;
}
Assuming the Obj.Request is a function that returns a get parameter. (I already have this in place).
Use it in this manner:
$(document).on( 'click', 'a', function() {
console.log("going to " + $(this).attr('href'));
return true;
});
Working on your fiddle link.
You want to use the function .on.
$('a').on('click', function() {
//works on non dynamic elements present at page load
});
$('#some_non_dynamic_parent_ID').on('click', 'a', function() {
//works on dynamic elements added later
});
You want to use .on(), but as a delegation method.
Bind it to the closest static parent - for this example I'll just use body.
$('body').on('click', 'a', function(e){
e.preventDefault();
});
This will wait until the event bubbles up to the body element and check what the original target of the event was - if it was an a element, it'll fire the handler.
You can use .on() or live() functions if you use jquery upper then 1.7 version. About the difference of these functions you can read in this article

jquery or js code to obtain exact node data for currently selected form item/text/image in a web page

I want to obtain the exact details for the item on a web page that has been clicked on, using jquery.
That item can be a form item (like a checkbox, text box, text area etc) or section of text (in a paragraph or div or other) or list or image ...
What I figured out is the following--
$(function(){
$('*')
.bind('click', function(event) {
//now obtain details of item that has been clicked on...
});
});
Now, I want the exact details- viz the div id/form id/paragraph #, ie all details for that particular item. How do i get this data? I understand that this data is available in the DOM but I just dont know how to get it in this particular case...
Probably the best way to do to use the target property of the event. By default, this returns a non-jQuery object, which isn't particularly useful, however wrapping it in $() solves this issue:
$(function() {
$(document).bind('click', function(event) {
var element = $(event.target);
alert(element.height()); // Get height
alert(element.attr('id')); // Get ID attribute
// ...
});
});
If you want to fix your current method, inside your click() handler, you can access the properties of that element using .attr(), and friends:
$(function() {
$('*').bind('click', function(event) {
alert($(this).height()); // Get height
alert($(this).attr('id')); // Get ID attribute
// ...
});
});
$(this) in the scope of the function references the element that was clicked. There is a list of functions that will return attributes here and here in the jQuery docs. $.attr('id') will return the element's ID, among other things, and $.data() will return data-* attributes.
To get attributes of parent elements, simply use $(this).parent(). For example, to get the ID of the form that contains the clicked element, use $(this).closest('form').attr('id');. Everything is relative to the clicked element ($(this)), so you can just use the DOM traversal functions.
However, using $('*').bind() is incredibly inefficient; you're binding an event handler to every element on the page, when really you should delegate events with .on() (jQuery 1.7+):
$(function() {
$('body').on('click', '*', function(event) {
alert($(this).height()); // Get height
alert($(this).attr('id')); // Get ID attribute
// ...
});
});
This approach only binds one event to <body> instead of an event to every element on the page.
Use the target of click event on page
$(document).click(function(event){
/* store native dom node*/
var tgt=event.target;
/* store jQuery object of dom node*/
var $tgt=$(tgt);
/* example element details*/
var details={ id : tgt.id, height: $tgt.height(), tag : tgt.tagName}
console.log( details)
})
Look at the event.target, and then you can use jQuery's .parents() method to look at every ancestor:
$(document).on('click', function(event) {
var $t = $(event.target); // the element that was actually clicked
var $p = $t.parents(); // the target's parents
var $form = $p.filter('form').first(); // the enclosing form, if it exists
});

Categories