So, Here is my little barter calculator.
The problem is that when I try to add it to my site it goes all nuts by hiding all the divs. (It literally applies display:none to all of them).
How can I make this work?
Additionaly, I would like to make the script calculate value after pressing Submit button, not dynamically like now. Any easy way to do it?
It goes like this(sample, for full code go to jsfiddle, link at the bottom):
<div id="Apple">
<ul>
<li><span data-val="2"></span> bananas</li>
<li><span data-val="3"></span> oranges</li>
</ul>
</div>
And this is my JS
$(document).ready(function () {
function showTab(name) {
$('div').hide();
var $div = $('#' + name).show();
var number = parseInt($('.number').val(), 0);
$('span', $div).each(function() {
$(this).text($(this).data('val') * number);
});
}
$('#dropdown').change(function () {
showTab($(this).val());
});
showTab($('#dropdown').val());
});
Fiddle - check it live
Analyse the code carefully. The showTab() function hides all divs on your site:
$('div').hide();
And then it shows the one which matches your tab:
var $div = $('#' + name).show();
You'll need to change the first selector to something a little more specific to your own markup, otherwise it will continue to hide other <div> elements. Unfortunately, it's not clear what structure you're using based on the Fiddle, so I can't help more.
I'd recommend adding a class to the numerous sections, and then updating your code. For the #Apple example:
<div id="Apple" class="tab">
In turn, you can then use the selector:
$('div.tab').hide();
It might be better to also use jQuery's not() function, to create some exclusivity as follows:
$('div.tab').not('#'+name).hide();
This will also eliminate the need to later call show().
$('div').hide(); will hide every div on the page. Be more specific:
$('div.fruit').hide();
<div id="Apple" class="fruit">
<ul>
<li><span data-val="2"></span> bananas</li>
<li><span data-val="3"></span> oranges</li>
</ul>
</div>
Demo
you have $('div').hide(); - no wonder all divs are hidden, maybe you should narrow it down with some $('#container div').hide(); ?
Try to change your selector
$('div').hide();
to
$('#Apple').hide();
Related
I have multiple containers that I need to animate.
Basically: you click on class: box-n (e.g. box-1) and you slideToggle: box-child-n (e.g. box-child-1).
Instead of a click function for every box-n to toggle box-child-n, I want a simple line of code that matches box-n with its children class.
html:
<div class="box-1">Some clickable container</div>
<div class="box-child-1">This should toggle when box-1 is clicked</div>
<div class="box-2">Some clickable container</div>
<div class="box-child-2">This should toggle when box-2 is clicked</div>
Et cetera...
current jquery:
$('.box-1').click(function() { $('.box-child-1').slideToggle() });
$('.box-2').click(function() { $('.box-child-2').slideToggle() });
Sort of desired jquery (allInt function is made up.):
var $n = allInt();
$('.box-' + n).click(function() {
$('.box-child-' + _n).slidetoggle() // local variable to inter alia .box-1
})
I can't seem to think of any solution, so I am asking for help once again.
I appreciate every suggestion you folks give me!
Here's one way to do it that allows for the elements to have other classes besides the ones that you're using to pair them up:
$('div[class*="box-"]').click(function() {
var c = this.className.match(/\bbox-\d+\b/);
if (c)
$('div.' + c[0].replace(/-/, '-child-')).slideToggle();
});
Demo: http://jsfiddle.net/6xM47/
That is, use the [name*=value] attribute contains selector to find any divs with a class attribute that has "box-" in it somewhere. Then when clicked extract the actual class and check that it matches the "box-n" pattern - this allows for multiple (unrelated) classes on the element. If it does match, find the associated "box-child-n" element and toggle it.
Having said all that, I'd suggest structuring the markup more like this:
<div data-child="box-child-1">Some clickable container</div>
<div class="box-child-1">This should toggle when box-1 is clicked</div>
...because then the JS is simple and direct:
$('div[data-child]').click(function() {
$('div.' + $(this).attr('data-child')).slideToggle();
});
Demo: http://jsfiddle.net/6xM47/1/
To just answer your question, this will do the trick :
$("div[class^='box-']").click(function(){
$(this).parent().find('.' + $(this).attr('class').replace('-','-child-') ).slideToggle();
});
jsfiddle here.
Anyway i dont think you use a good approach (you may wrap child into parent div or use ids).
I'm trying to mover a nav element up one level so I end up with something like:
<div>
<nav>
<a href='#'>hello</a>
<a href='#'>hello</a>
</nav>
</div>
to
<nav>
<a href='#'>hello</a>
<a href='#'>hello</a>
</nav>
<div>
</div>
I've been trying to use unwrap(); with no success.
$('div > nav').unwrap();
Not entirely sure why.
unwrap will unwrap your nav means it will remove the div from DOM. Try something like this.
var $div = $('div');
$div.before($div.children('nav'));
//$div.before($div.children()); //For all children use children()
if you have multiple then try this way:
$(function(){ //Make sure it is inside DOM ready
var $div = $('div:has("nav")');
$div.before(function () {
return $(this).children("nav");
});
});
You should try insertBefore() more info: http://api.jquery.com/insertBefore/
$("nav").insertBefore("div");
If you have multiples and want to make sure it is moved up one level and not to just any div and only it's parent try this:
$("div > nav").each(function (){
$(this).insertBefore($(this).parent());
});
If they aren't all inside div then just do:
$("nav").each(function (){
$(this).insertBefore($(this).parent());
});
$('nav').insertBefore($('nav').parent());
This will move the element one up.
Js fiddle http://jsfiddle.net/tsuUE/
You'll likely want to give your nav and id to select only that element.
This worked wonderfully in my case, where I had to reposition a div selected (via its class) up a level.
$(".className").each(function (){
$(this).insertBefore($(this).parent());
});
I'm sure this will be a simple question but I still struggle with DOM selectors in Jquery so here is a model of my html code:
<fieldset class="product-options" id="product-options-wrapper">
<ul class="options-list">
<li><a href>Item1.1</a></li>
<li><a href>Item1.2</a></li>
<li><a href>Item1.3</a></li>
</ul>
...other html items here
<ul class="options-list">
<li><a href>Item2.1</a></li>
<li><a href>Item2.2</a></li>
<li><a href>Item2.3</a></li>
</ul>
</fieldset>
Now how do I select all of the 'li a' items in both lists (or X number of lists) with class name .options-list and bind them with a click function.
Currently I have:
$('fieldset#product-options-wrapper ul.options-list > li a').bind('click', function(e) {
//code here
});
And it only gets the first options-list.
Thanks, greatly appreciated!
EDIT: If i click on a Item2.X list item first, then it will grab that options list. But as soon as I click on the Item1.x list items it disregards the second .options-list
If you are going to bind to each li element, you should bind it to the ul element instead (helps greatly with performance when there are a lot of events).
$('.options-list', '#product-options-wrapper').bind('click', function(e)
{
e.preventDefault();//In case you don't want to go to a different page
var clicked = e.target;//The href that was clicked
/* If you only want this to happen if the a tag was clicked, add the following line
if(clicked.tagName == 'A')*/
//Rest here
});
How about $('.options-list a').bind('click', function(e) { });?
You can use delegate in this case to make it even simpler. Try this
$('#product-options-wrapper ul.options-list').delegate('li > a', 'click', function(e) {
//code here
});
Your method seems sound to me. I created a test fiddle using your HTML (and an extra anchor to prove that it won't get the click added) and your JS (with minor modifications).
http://jsfiddle.net/chrisvenus/esZxH/1/
The selector you had did work but since you said you wanted the a to be a direct child of the li (or at least I read it that way) I slightly tweaked it in my version above. ARe you sure its not just your function is not doing quite what you want while executing or can you confirm that your click function isn't being run at all?
I am almost a noob at JavaScript and jQuery, (so I apologize if I didn't recognize a suiting answer to my question, in similar posts).
Here is the thing. I have a list with lots of stuff in each list item:
<ul id="fruit_list">
<li>
<h4> Fruit 1: remove </h4>
<p> blablabla </p>
</li>
<li>
<h4> Fruit 2: remove </h4>
<p> blablabla </p>
</li>
</ul>
add
What I want to do, is when I click on the anchor 'remove', to remove the list item containing it.
(Optionally I would like to manipulate the incremental number at Fruit 1, Fruit 2 etc, in a way that when I remove item #2, then the next one becomes the #2 etc. But anyway.)
So here is what I've written so far:
$(function(){
var i = $('#fruit_list li').size() + 1;
$('a.add').click(function() {
$('<li><h4>Fruit '+i+':<a href="#" class="remove">
remove</a></h4><p>Blabla</p></li>')
.appendTo('#fruit_list');
i++;
});
$('a.remove').click(function(){
$(this).parentNode.parentNode.remove();
/* The above obviously does not work.. */
i--;
});
});
The 'add' anchor works as expected. The 'remove' drinks a lemonade..
So, any ideas?
Thanks
EDIT: Thanks for your answers everybody!
I took many of your opinions into account (so I won't be commenting on each answer separately) and finally got it working like this:
$('a.remove').live('click', function(){
$(this).closest('li').remove();
i--;
});
Thank you for your rapid help!
The a.remove event binding needs to be a live http://api.jquery.com/live/ binding. The nodes are added to the DOM after doc ready is called.
Additionally, I think you want to use parent() instead of parentNode. Unless I'm behind on my jQuery, parentNode is just DOM manipulation and there's no standard remove(), it's removeChild(). Here you need a jQuery collection returned from parent().
Try $(this).parents("LI").remove();
The reason is that $('a.remove') is only executed once, and so only found at the moment you don't have any remove links yet. To solve this rewrite your ADD function like this:
$('a.add').click(function() {
var $li = $('<li><h4>Fruit '+i+':<a href="#" class="remove">
remove</a></h4><p>Blabla</p></li>');
$li.appendTo('#fruit_list');
$li.find('a.remove').click(function() {
$li.remove();
i--;
});
i++;
});
And just remove your old remove function.
EDIT: Oh, this will only work for items you add, if you already load some list items in the html before any Javascript is executed add this function under the $('a.add').click:
$('a.remove').click(function(){
$(this).parent().parent().remove();
i--;
});
Sorry if the title isn't clear enough, I have five <li>'s in each <li> I have <a> and a <div> and in each <div> I have a <ul>with a class of "config". Then in that I have two <li>.
I use jQuery to hide the <ul> with the class of config and then use slideToggle to show/hide them. The problem is, It shows all of them. I want to just click one link and the appropriate <div> or <ul> should appear, not all of them. How can I do this?
So far I have:
$(document).ready(function(){
$("ul.config").hide();
$("li:nth-child(1) a").click(function(){
$("li ul.config:first").slideToggle(300);
});
});
But that only shows the very first list. How can I show each one when it's clicked?
With not sure of what the HTML really is, try
$(document).ready(function(){
$("ul.config").hide();
$("li:nth-child(1) a").click(function(){
$(this).parent().find('ul.config').slideToggle(300);
});
});
put a class/id to your top-most ul (before 5 top li), e.g: id="topmenu"
$(document).ready(function(){
$("ul.config").hide();
$("#topmenu li a").click(function(){
$(this).parent().find('ul.config').slideToggle(300);
});
});