I'm creating a drop down menu that will be reused many times on a single page.
The following code works great when there's only one drop down menu. But when there are multiple drop downs, clicking a single .dropdown will result in all the .dd_menu's on the page being revealed.
JS:
$(document).ready(function() {
$('.dropdown').click(function(){
$('.dd_menu').toggle();
});
});
HTML:
<div class="dropdown">
<a class="mini_button" href="#">Actions</a>
<div class="dd_menu">
Link
Link
Link
</div>
</div>
Is there some what to target only the .dd_menu that is inside the particular .downdown which was clicked?
Limit the selector to the .dd_menu that is a child of the current clicked .dropdown div:
$(document).ready(function() {
$('.dropdown').click(function(){
$('.dd_menu', this).toggle(); // <========== used this as a context.
});
});
jQuery( selector [, context] ):
selector A string containing a selector expression
context A DOM Element, Document, or jQuery to use as context
docs
You can also use the find function: $(this).find('.dd_menu') but it exactly the same. the context selector is calling the find function.
You could try:
$(this).children('.dd_menu').toggle();
$(document).ready(function() {
$('.dropdown').on('click', 'a', function(){
$('.dd_menu:eq('+$(this).parent().index()+')').toggle();
});
});
Related
I have some jquery to hide content on an index page.
the commented out code in the fiddle is what i have at the moment - but it hides all content divs if any toggle link is clicked.
HTML
<div>
<h1>Dogs</h1>
<a class="toggle_group_name">∆</a>
</div>
<div class="group_name">
Dogs do this, that and something
</div>
<div>
<h1>Cats</h1>
<a class="toggle_group_name">∆</a>
</div>
<div class="group_name">
Cats do this, that and something different
</div>
jQuery
$(function() {
$('.toggle_group_name').click(function() {
$(this).parents("div").find('.group_name').toggle();
});
});
I want only the class immediately following the toggle link to be hidden/shown, but can't get it working. Have tried using parents, nextAll, and various other methods from similar examples I've found on SO, but so far nothing has worked.
The target element is not sibling or parent of the clicked element, it's next sibling of the clicked element's parent, so .parents() and .nextAll() methods are not useful in this case, you can use .closest()/parent() and .next() methods:
$(this).closest('div') // closest parent div of the clicked element
.next('.group_name') // it's next .group_name sibling
.toggle();
http://jsfiddle.net/xUgG5/
This seems to work in your fiddle:
$(function() {
$('.toggle_group_name').click(function() {
$(this).parents("div").next('.group_name').toggle();
});
});
Just use first().
http://jsfiddle.net/P6GEC/9/
$(function () {
$('.toggle_group_name').click(function () {
$('.group_name').first().toggle();
});
});
http://api.jquery.com/first/
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
});
i have to made functionality like this on click of a link it will show the product details in a popup like box
this is using a big jquery code i didn't understand
and here is my jsfiddle
i am trying to give some links same class with different #tags to show the div
and i want that when i click on link it resolves the href value of the same and show the corresponding result but it didnt works
can somebody suggest the right way
here is my JS
$(".show").click(function() {
var link = $('this').attr('href');
$(link).show();
});
and html
a
b
c
i want to show #popup on anchor click
full code on fiddle and i want this functionality
You should call $(this), not $('this')
$(this) wraps the object referred to by this inside a jQuery object,
$('this') will traverse all of your document looking for html nodes tagged this (much like $('div') will look for html nodes tagged div); since there isn't any, it will select an empty list of nodes.
Working fiddle : http://jsfiddle.net/Hg4zp/3/
( there also was a typo, calling .hide(") instead of .hide() )
Try this way:
$(".show").click(function (e) { //<-----pass the event here
e.preventDefault(); //<--------------stop the default behavior of the link
var link = $(this).attr('href'); //<-remove the quotes $(this)
$(link).show();
});
$(".close").click(function () {
$(this).closest("div.popupbox").hide(); //<----use .hide(); not .hide(");
});
You should use preventDefault() in these cases to stop the jump which take place when a link get clicked.
I am currently attempting to make a dropdown menu where selecting one of the links from the menu will change the hidden value as well as the text of the hyperlink. This is based upon Twitter's Bootstrap dropdown, and uses jQuery:
<div id="periodChooser" class="btn-group">
<input type="hidden" value="1" name="dtype" id="dtype1"></input>
<a data-toggle="dropdown" href="javascript:;">Weekend</a>
<ul class="dropdown-menu">
<li>Weekend</li>
<li>Week</li>
<li>Midweek</li>
</ul>
</div>
The script that I have attempted to write is as follows:
<script>
jQuery(function($){
$('#periodChooser').each(function() {
$('.dropdown-menu a').click(function() {
$('.btn-group').find('input[type=hidden]').val($(this)
.data('value')).change();
$('.btn-group').find('.btn:eq(0)').text($(this).text());
});
});
});
</script>
Unfortunately, whilst it doesn't return any specific error, the code does not work. Any suggestions?
Bind event out side each
<script>
$('#periodChooser .dropdown-menu a').click(function() {
$('.btn-group').find('input[type=hidden]').val($(this)
.data('value')).change();
$('.btn-group').find('.btn:eq(0)').text($(this).text());
});
</script>
I think that this can be optimized and made more re-usable.
First of all, you are using jQuery selectors like $('.btn-group') very ineffectively.
Secondly it will break, if you will use more than one "widget", because the context is whole document and it will find all elements with that class .btn-group.
Thirdly it would be more effective to use single event handler that is being binded to the parent <ul> element instead of each <a> element. It's called "event delegation". http://api.jquery.com/delegate/
<script>
$('#periodChooser').each(function() {
var $input = $('input', this),
$select = $('>a', this);
$('ul', this).on('click', 'a', function() {
var $this = $(this);
$input.val($this.data('value')).change();
$select.html($this.html());
});
});
</script>
I made this code available in JSBin: http://jsbin.com/welcome/38724/edit
What I did here?
<script>
$('#periodChooser').each(function() {
// Find and store input and "select" element only once.
var $input = $('input', this),
$select = $('>a', this); // This finds only direct child element <a>
// Find the <ul> element inside the #periodChooser
// Bind a click event that will "bubble up" from <a> elements that are children of it
$('ul', this).on('click', 'a', function() {
// Wrap a jQuery around the <a> element
var $this = $(this);
// Set the input value and execute "change" event(s)
$input.val($this.data('value')).change();
// Change the "select" title. Doesn't matter if you use html() or text() - choose yourself!
$select.html($this.html());
});
});
</script>
Now, you can use this to make multiple widgets inside single page! :)
<script>
$('.btn-group').each( /* Well, you know, the function goes here... */ );
</script>
Of course, threre are many other things that has to be done here, like opening and closing the "option list", scrolling and probably many other things...
In HTML code my page contains:
<div id="main_menu">
Link1
Link2
</div>
<div id="second_menu">
Link info
My profile
</div>
<div id="menu_oustide">Link1</div>
In jQuery if I want to check if the user clicked any link in page I use this code:
$('a').click(function() {
// do something
});
How can I start a function if the user clicked only on links in specific div? I would like to have a function that starts if a user clicked any link only in div ID named "main_menu" AND "second_menu", but not in "menu_outside".
Depending on what exactly you want to do, you can bind the event handler to those links only, using the descendant [docs] and multiple [docs] selectors:
$('#main_menu a, #second_menu a').click(function() {
// link inside #main_menu or #second_menu
});
If you don't want to perform the same action for both, you have to bind the event handler individually.
You could also check dynamically whether the link is a descendant of any of these element, with closest [docs]:
$('a').click(function() {
if($(this).closest("#main_menu").length) {
// inside #main_menu
}
if($(this).closest("#second_menu").length) {
// inside #second_menu
}
//...
});
But that introduces an additional overhead.
use this to select the div and ahref you want.
$('#second_menu a').click(function(){
// This will select the a href's only in the second menu.
// basically, in div id "#second_menu" select all "a" elements.
});