jQuery delegateing inside div > divs > a also :( - javascript

html:
<div id="a">
<a id="a0" href="#"></a>
<div id="b"><a id="b0" href="#"></a><div>
<div>
jQuery:
$('#a').delegate('a', 'click', function(){ //do stuff });
delegates #b0 as well. Is there any clever selector way of ways to ignore #b ?
NB /// links inside divs are added and detached dynamically ///
ty

if you know it's only direct descendants try
$('#a').delegate('#a>a', 'click', function(){ alert('a') });
if you know you want to ignore children of b try
$('#a').delegate('a:not(#b>a)', 'click', function(){ alert('a') });
EDIT: a fiddle

This is working as expected. Your delegate() call will set event handler for all children under #a that match selector a.
If you are trying to set handler for a specific element then do that
$('#a0').click(function(){ ... });
Also your html is pretty broken. Make sure closing tags actually closing.

The first field in the delegate method is the selector. As of now, you are selecting all the anchors. Use id instead.

jQuery1.7 or above
$('#a').on('click', '#a0', function(event) {
alert(event.target.id);
});

Related

Trigger Event on Ajax generated Element

I can't use any Event (eg. onlick) on any ajax generated element. I read about jQuery's ".on" function, but I need to use something like <div id="myId_1234" onlick="doStuff()">.
The Id of the Element is random, so I can't use
`$('.some-parent-class').on('click', '.element', function() {// DO STUFF!});`
I hope someone can help me! Thanks.
You could attach the event handler to your element in the AJAX response before adding it to the DOM by using
$(responseHtml).find('some selector').on('click', handler);
There is most likely one or more attribute selectors that will work for you.
Ex: id begins with selector
$(responseHtml).find('div[id^=myId]').on('click', handler);
If you cannot differentiate which element in the response you need with a css selector you will have to modify the server script generating the HTML with a unique id or class that matches a pattern you can look for.
EDIT
You CAN use a css class to identify each element. use:
$('.myCloseButtonClass').on('click', function(){ $(this).parent.hide(); });
The key here is the this object. It will reference the specific element that was clicked thereby allowing you to close only the chat window that contains the clicked close button.
JSFiddle using AJAX echo
$('.some-parent-class').on('click', 'this put your id input', function() {// DO STUFF!});
proib with this......
You could do something like:
<div class="myBoxes">
<div id="oneBox" onclick="myFunc(this.parentNode);">
<p>Some content..</p>
</div>
</div>
function myFunc(){
// Code goes here
alert('function fired!');
}
I am simulating the Ajax Generated part by dynamically generating a clickable DIV element.
HTML:
<div id="container">
</div>
JS:
$("#container").append(
$('<div>').attr('id', 'randomId').html('New element')
);
$("#randomId").click( function(){
alert('Clicked!!!');
});
EDIT: Same example using class instead of Id:
$("#container").append(
$('<div>').attr('id', 'randomId').addClass('parent-class').html('New element')
);
$(".parent-class").click( function(){
var clickedElementId = $(this).attr("id");
alert('Element with ID ' + elementId + ' Clicked!!!');
});
Working fiddle

Get custom css property with a function

This is my code :
<html>
<body>
<button class="myclass" data-card-id="1">Save</button>
</body>
</html>
My question is how whould look like a function that when user click on any of "myclass" buttons submit a variable with data-card-id of the specific card in a php file.
Thank you ! :)
this is using Jquery:
$(".myclass").click(function(){
$(this).attr( "data-card-id" );
});
JSFIDDLE - http://jsfiddle.net/q5j8z/11/
see browser console for data display
// change the selector "ul li a" to your button
$('ul li a').click(function (e) {
e.preventDefault();
var value = $(this).data('value');
$('.button').data('value', value);
console.log($('.button').data('value'));
});
$('.button').click(function (e) {
e.preventDefault();
console.log($(this).data('value'));
});
This can be accomplished through an additional selection feature. I believe "data-card-id" is an attribute of your html tag, so you have two choices.
Bind the click to the element using the selector or delegate it to the body of the document, I think you'll see how either way works here.
Option 1. The advantage here is that when click events bubble up to the body this will check and execut appropriately, even if other buttons are added to the page after this code is executed. This is jquery's click delegation feature
$('body').on('click', 'button[data-card-id="1"]', function(){
//perform your action
});
Option 2. This binds the click event to the object itself. This can be more straight forward and has its advantage in simplicity.
$('button[data-card-id="1"]').click(function(){
// perform some action
});
And of course you have a plethora of other approoaches......
or
$('button').each(function(){
if($(this).attr("data-card-id") == '1'){
$(this).click(function(){
//some action
});
}
});
There are other approaches, too. Let me know if none of these seem to work.
JS FIDDLE DEMO
The most simpler would be to use this code -- >
just change this card-id to this cardid
HTML
<button class="myclass" data-cardid="1">Save</button>
<button class="myclass" data-cardid="2">Save</button>
JS
$(document).ready(function(){
$(".myclass").on('click',function(){
var cid = $(this).data("cardid");
alert(cid);
});
});

How to select all the elements in the DOM except one element?

I have an jQuery events) that are triggering on every DOM element on the page.
That's fine for now, but I need a way to exclude a div (with child divs as well) from DOM selection in order to prevent triggering event on them.
I've tried jQuery's unbind(), not() and off() directly on $('#myDiv'), but the events are still triggering.
The code that triggers the event(s):
$("*").each(function () {
// here are events bound to every DOM in the page
$(this).mouseover(mouseover).mouseout(mouseout).click(click);
});
I've also tried with
$("*:not(#myDiv)").each(function () {
// events
$(this).mouseover(mouseover).mouseout(mouseout).click(click);
});
and still wasn't able to remove events from #myDiv.
The HTML:
<div id="myDiv">
<div class="data">
<!-- -->
</div>
<div class="debug">
<!-- -->
</div>
<div class="form">
<!-- -->
</div>
</div>
What is the best way to make full DOM selection but excluding #myDiv, so I would be able to use bind() or on() for binding events?
NOTE: I don't want to remove #myDiv from the DOM tree, but rather exclude it from selection.
You may try this
$(function(){
$('body > *').not('#myDiv')
.on('mouseover', function(){ //... })
.on('click', function(){ //... });
});
An Example.
Try .not()
$("*").not("#myDiv").each(function () {
$(this).mouseover(mouseover).mouseout(mouseout).click(click);
});
Try the following:
$("*:not(#myDiv):not(#myDiv *)")
.mouseover(mouseover)
.mouseout(mouseout)
.click(click)
This will exclude not only #myDiv, but any child elements of #myDiv (which you seem to be going for).
If you want to exclude the children as well, you'll need to do so explicitly:
$("*:not(#myDiv):not(#myDiv *)")

jQuery Nested Plugins Selector Issue

I'd like the ability to nest one plugin within another. However my selectors are too aggressive and keep retrieving the elements for the nested plugin aswell.
For example given the following HTML:
<div class="my-plugin">
...
<div class="my-plugin">
...
<button class="select">Select</button>
</div>
</div>
With the following code to create the plugin:
$(function() {
$('.my-plugin').myPlugin();
});
When I say the following (within my plugin):
// element is the element the plugin is attached to
$('.select', element);
This will retrieve the select element from the nested plugin within the outer plugin but I'd like it not to. Also I'd like to do the same when attaching click events. For example the following code should only attach the click event in the nested plugin and not within the outer plugin.
element.on('click', '.select', function(e) {
...
});
I hope I've explained that clearly. I'd appreciate if someone could show me how my selector can be improved to handle this. Thanks
The problem is, selectors work against the context they're given. If you tell jQuery to search a div, it will search everything in that div for what it's looking for. It's just how jQuery works.
If you want to exclude the inner plug-in, give it an id and exclude it using .not(). Or you could give it a class or data-* attribute as well. We just need something to tag it as "do not include".
So, do this:
$('.select', element).not('#mySecondPlugin');
or:
$('.select', element).not('.mySecondPlugin');
or:
$('.select', element).not('[mySecondPlugin="true"]');
This selector will select everything within your outer element EXCEPT the inner one and its contents.
And finally:
$('.select', element).not('[mySecondPlugin="true"]').on('click', function(e) {
...
});
You can use jQuery .closest() to find the first occurrence of a selector from an element. So you could target the nested div with #('.select').closest('.my-plugin').
Using jQuery .filter():
var myPlugin = this;//or whatever is representing your plugin jQuery object.
var selectsYouWant = $('.my-plugin .select').filter(function(index){
if(this.closest('.my-plugin') === myPlugin) {
return true;
} else {
return false;
}
});
You need to understand events. When you click on the element, event bubbles up the DOM tree. You need to stop propagation, so that it would not reach outer plugin handler. Depending on the logic you may also need to prevent default action:
element.on('click', '.select', function(e) {
e.stopPropagation();
e.preventDefault();
// ...
});
Also, not sure what is the logic inside plugin, but you can filter out inside items:
var button = $('.my-plugin').find('.select').not('.my-plugin .my-plugin *');
button.css('color', 'red');
See: FIDDLE
This is the approach I recommend.
At initialization:
$(element).addClass('my-plugin');
var $selects = $(element).find('select')
.not( $(element).find('.my-plugin select') );
You would have to make sure that the element and $selects variables are accessible to all functions in the plugin.
On the note about on(), here's what I would suggest:
element.on('click', '.select', function(){
// see if the closest .my-plugin is the matching element, and not
// a child plugin
if ( ! $(this).closest('.my-plugin').is( element ) )
return;
...
});
Try to start outside of your first plugin:
for example:
<div class="plugin-wrapper">
<div class="my-plugin">
...
<button class="select">Select</button> //We want this one
<div class="my-plugin">
...
<button class="select">Select</button> //Without this one
</div>
</div>
</div>
You would then be able to use something like $('.plugin-wrapper > .my-plugin > .select') which would get ONLY the first .select without the second. Which I believe is what you are trying to accomplish
For the onclick
$('.plugin-wrapper > .my-plugin > .select').on('click', function () {
//Your code here
});

Identical JQuery function is working for one link, not another

I have the function:
<script type="text/javascript">
$(function() {
$('#subbutton').click(function() {
$('#subbutton').hide();
});
});
</script>
It simply makes this button hide when clicked:
<a id="subbutton" class="button" href="javascript:TINY.box.show({url: 'follow',width:600,height:170,openjs:'initPopupLogin',opacity:30})"><span>Button</span></a>
Now, if i try to use the identical function, but with a link later on the page, it doesnt work (i have erased the original button at this point) Here is the code:
<div id="subbutton">
<span>Button</span>
</div>
I have tried putting the id in the anchor and in the span, nothing seems to be working for this link. Any idea why this isn't working? (I have deleted the original button so that this second button is a unique id on the page)
Try using .on instead to attach your event handler. I am suspecting the button is not in the dom at the time you attach the event handler.
$(document).on('click', '#subbutton', function() {
$(this).hide();
});
EDIT now that i understand the problem. You are better off giving the buttons a class and using a class selector.
.hide doesn't remove the element from the page so your selector will still be matching on the first element. You need to use .remove to remove the first element from the DOM so the second selector can work.
Also, little jQuery optimization. The nested call to $('#subbutton') is not needed. At best, it is harder to maintain, at worst, it could cause performance issues if you put this in a large loop. This is better.
$(function() {
$('#subbutton').click(function() {
$(this).remove();
});
});
You are missing a " after this:
<a id="subbutton" class="button
and Id has to be unique. Then it should work.
Don't reuse ids, they must be unique. pass the id to the function
Change your javascript to:
$(function() {
$('#subbutton').live("click",function() {
$(this).hide();
});
});​
http://jsfiddle.net/W2agx/
also don't reuse id's. use a class for multiple DOM elements that you want to be able to select together.

Categories

Resources