Apply a loop in JS between X and XX - javascript

So I have been trying to think of how to explain this in a way that makes sense, but I will show you below, as it makes more sense.
I have this code that works fine but I want to shorten it down into a for each loop or something.
$('.holder1').on({
click: function(){
$('.box1').css({display: 'none'});
$('.text1').css({display: 'block'});
}
});
$('.holder2').on({
click: function(){
$('.box2').css({display: 'none'});
$('.text2').css({display: 'block'});
}
});
$('.holder3').on({
click: function(){
$('.box3').css({display: 'none'});
$('.text3').css({display: 'block'});
}
});
I have this going on up to 40+, and obviously this code is horrific.

You can refactor the HTML code to use a common class and data attributes. Something like this:
<div class="holder" data-box="box1" data-text="text1"></div>
<div class="holder" data-box="box2" data-text="text2"></div>
<div class="holder" data-box="box3" data-text="text3"></div>
Then you can have a single click handler for all classes:
$('.holder').on({
click: function(){
$('.' + $(this).data('box')).css({ display: 'none' });
$('.' + $(this).data('text')).css({ display: 'block' });
}
});
This avoids the needs for ugly loops to add multiple handlers and iterative id attributes, which always turns in to a maintenance nightmare.

To solve this problem it is possible to iterate over holder elements using jQuery Attribute Starts With selector (API docs):
$.each('[class^="holder"]', function(index, item) {
$(item).on('click', function() {
$('.box' + index).css({display: 'none'});
$('.text' + index).css({display: 'block'});
});
});
I would prefer using some common class, though, as Rory McCrossan pointed out in his answer.

for (var i = 0; i< 40; i++) {
$('.holder' + i ).on({
click: function(){
$('.box' + i).css({display: 'none'});
$('.text' + i).css({display: 'block'});
}
});
}
or just add a common class and use it.

try this:
use class .box and .text instead
var holder = $(".holder1");
for (var i = 2; i<= 40; i++) {
holder.add($(".holder"+i));
}
$(holder).on(
'click', function(){
$('.box').css({display: 'none'});
$('.text').css({display: 'block'});
}
});

Assuming holders and boxes sit in their respective containers, like
<div>
<div class="holder">a</div>
<div class="holder">b</div>
<div class="holder">c</div>
<div class="holder">d</div>
</div>
<div>
<div class="box">a</div>
<div class="box">b</div>
<div class="box">c</div>
<div class="box">d</div>
</div>
you can get rid of box/text numbers altogether:
$(".holder").click(function() {
var n = $(this).index();
$(".box").eq(n).show();
});
This way it will be much easier to add new elements or change their order.

Use:
$("*[class^='holder']").on({
click: function(){
var id = $(this).attr("class").replace("holder","");
$('.box'+id).css({display: 'none'});
$('.text'+id).css({display: 'block'});
}
});

Related

jquery click to close current div using attr id

I have one problem with jquery secon click to close opened div.
I have created this DEMO from codepen.io
In this demo you can see there are two button div with blue color.So before clicked first button after click second button the first <div class="emoWrap" id="ac1"> is not closing.
I tryed the following js code:
$(document).ready(function() {
$("body").on("click", ".button", function(e) {
e.stopPropagation();
var ID = $(this).attr("id");
$("#ac" + ID).toggleClass("emoWrap-active");
/*var $current = $(this).find('.emoWrap').toggleClass("emoWrap-active");
$('.emoWrap').not($current).removeClass('emoWrap-active');*/
});
$("body").click(function(){
$(".emoWrap").removeClass("emoWrap-active");
});
});
HTML
<div class="container">
<div class="button" id="1">1</div>
<div class="emoWrap" id="ac1">
<div class="Emojis">For 1</div>
</div>
</div>
<div class="container">
<div class="button" id="2">2</div>
<div class="emoWrap" id="ac2">
<div class="Emojis">For 2</div>
</div>
</div>
Try this codepen example, I edited it so that all other emoWraps will turn off when a different one is clicked. This also means that it is exapandable, just change the IDAmount to the number of emoWraps you have.
This is the edited JavaScript code:
var IDAmount = 2;
$(document).ready(function() {
$(".button").on("click", function(e) {
e.stopPropagation();
var ID = $(this).attr("id");
$("#ac" + ID).toggleClass("emoWrap-active");
for(var i = IDAmount; i >= 1; i--){
if(i != ID){
$("#ac" + i).removeClass("emoWrap-active");
}
}
});
});
Just add a bit more logic to your first function. This isn't how I'd do it, but building on your code would be something like:
$(".button").on("click", function(e) {
e.stopPropagation();
var ID = $(this).attr("id");
if($("#ac" + ID).hasClass('emoWrap-active')) {
$(".emoWrap").removeClass("emoWrap-active");
} else {
$(".emoWrap").removeClass("emoWrap-active");
$("#ac" + ID).toggleClass("emoWrap-active");
}
});
Like so: http://codepen.io/anon/pen/wMqZqY
Sorry, didn't test. Although you do not need both clicks. You can remove from all the classes then just add the one you want:
e.stopPropagation();
var ID = $(this).attr("id");
$(".emoWrap").removeClass("emoWrap-active"); // Add this
$("#ac" + ID).addClass("emoWrap-active");

Why doesn't my <div> slide with these jquery code?

I want to reduce my <div> size when I click on a <a> . But it doesn t work.
Javascript code
(divheight is a global variable)
function jamsho(id) {
var idd=id.substr(1);
alert(document.getElementById(idd).style.height);
if(document.getElementById(idd).style.height != 30) {
$(id).stop().animate({height:30}, 700);
divheight=document.getElementById(idd).style.height;
} else if (document.getElementById(idd).style.height == "30px") {
$(id).animate({height:divheight}, 700);
}
}
And call the function :
<div class="linkbox" id="linksbox">
<a id="Titr" onClick="jamsho('#linksbox')"> پیوند ها</a>
سایت روان آنلاین
</div>
ditch the onclick, ditch the vanilla js. It's as simple as follows:
jsFiddle Example
HTML
<div class="linkbox" id="linksbox">
<a id="Titr"> پیوند ها</a>
سایت روان آنلاین
</div>
jQuery
$('#Titr').click(function(e) {
e.preventDefault();
var par = $(this).parent();
par.animate({height:par.height()==30?'':30},700);
});
And if you want something more "dynamic":
$('.linkbox').on('click', 'a:first', function(e) {
e.preventDefault();
var par = $(this).parent();
par.animate({height:par.height()==30?'':30},700);
});
Keep in mind, last solution only works for jQuery versions 1.7 and above, for older version, replace .on with .delegate
You're sure that this condition document.getElementById(idd).style.height!=30 is satisfied?
I believe that the property height comes as string with the "px" sufix. See this.
So, to work it may be if (document.getElementById(idd).style.height!="30px").
BTW, is a best pratice to use only jQuery or pure Javascript, not mix them.
You could use jQuery for all of the function, instead of part of it:
function jamsho(id)
{
var $this = $(id);
alert($this.height());
if ($this.height() != 30)
{
$this.stop().animate({height:30},700);
divheight = $this.height();
}
else if ($this.height() == 30)
{
$this.animate({height:divheight},700);
}
}
I don't think you can apply jQuery animations to non-jQuery Objects
function jamsho(id) {
alert($(id).css("height");
if($(id).css("height")!=30)
{
$(id).stop().animate({height:30},700);
divheight=$(id).css("height");
}
else if ($(id).css("height")==30)
{
$(id).animate({height:divheight},700);
}
}
Try something like this:
var $div = $('#linksbox'),
divHeight = $div.height();
$('#Titr').click(function() {
if (!$div.hasClass('expanded')) {
$div.animate({height: 40}, 700, function() {
$(this).addClass('expanded');
});
}
else {
$div.animate({height: divHeight}, 700, function() {
$(this).removeClass('expanded');
});
}
});
http://jsfiddle.net/ZqEZ5/
A few notes:
no need to use document.getElementById with jQuery
don't use inline event handlers onClick.
Hope it helps.

How to hide my dynamicly created divs?

I have created a script that creates divs based on number of li elements and that part is working fine. Now what I would like to do is to hide these div's (dynamicly created) but it is not working. Can someone tell me what I am doing wrong here? THX!!
Fiddle here
My code:
$(document).ready(function(){
$(".create").click(function(){
i='';
var count = $("li").length;
for(var i=0;i<count;i++){
$('<div class="mydiv" style="width:100px;height:100px;background-color:red;border:1px solid #000000;"></div>').appendTo('body');
}
});
$('.check').click(function(){
var getDivs= $('div').length;
alert(getDivs);
});
//Why is this not working?
$('div').click(function(){
$(this).hide();
});
});
Try to do this instead (and attach the click event when you create the div):
$('<div class="mydiv" style="width:100px;height:100px;background-color:red;border:1px solid #000000;"></div>')
.click(function(){
$(this).hide();
})
.appendTo('body');
All of this code should be in jQuery ready. The problem is your events are being bound before the elements have been created.
$(document).ready(function(){
$(".create").click(function(){
i='';
var count = $("li").length;
for(var i=0;i<count;i++){
$('<div class="mydiv" style="width:100px;height:100px;background-color:red;border:1px solid #000000;"></div>').appendTo('body');
}
$('.check').click(function(){
var getDivs= $('div').length;
alert(getDivs);
});
//Now working
$('div').click(function(){
$(this).hide();
});
});
});
Try
$(document).on('click', 'div', function () {
$(this).hide();
)};

Hide/Show different links

I have a script that works on one link on jsfiddle.
I have two links. Link one is "Link one" the other one is "Link two" you can see the code on jsfiddle = http://jsfiddle.net/lamberta/7qGEJ/4/
It works to show and hide but i cant make it show one and other. It shows everything.
If i press Link one I want to show ".open-container-One"
And if I press Link two i just want to show "open-container-Two"
Hope you understand my issue.
jsCode:
$(document).ready(function() {
var $div = $('.test');
var height = $div.height();
$div.hide().css({
height: 0
});
$('a').click(function() {
if ($div.is(':visible')) {
$div.animate({
height: 0
}, {
duration: 500,
complete: function() {
$div.hide();
}
});
} else {
$div.show().animate({
height: height
}, {
duration: 500
});
}
return false;
});
});​
Get the index from the clicked anchor, in this case that would have to be the wrapping li, and then use that index to select the right one in the collection of .test elements. No need to recreate the slideUp/Down already built into jQuery.
$(function() {
var elems = $('.test').hide();
$('a').click(function(e) {
e.preventDefault();
var selEl = elems.eq($(this).closest('li').index());
selEl.slideToggle(600);
elems.not(selEl).slideUp(600);
});
});​
FIDDLE
Although I like #adeneo's answer, I prefer this method using selectors rather than elements :
$(".test").hide();
$('.list a').each(function(i) {
$(this).on("click", function() {
$(".test").slideUp(0).eq(i).slideDown(400, function() {
$(".close a").on("click", function() {
$(".test").slideUp();
}); // on click close
}); // after slideDown (shown div)
}); // on click link
}); // each
The only condition is that there should be the same number of links (list items) as the number of div to be shown and in the same order.
See JSFIDDLE
Give class to the anchor tag,
Link 01
Link 02
give the appropriate class as id to the div tag as
<div id="link1" class="test">
...
...
</div>
<div id="link2" class="test">
...
...
</div>
Do the below change in your javascript function
$('a').click(function() {
$('div.test').hide();
var showDivClass = $(this).attr("class");
$("#" + showDivClass).show().animate({
height: height
}, {
duration: 500
});
$('div.test').not("#" + showDivClass).hide().animate({
height: 0
}, {
duration: 500
});
});
Update and test.
Please provide the id to anchor tag which will be same as the class you need to show/hide.
and replace the $div with the id tag

jquery toggle with a master switch

I am trying to use jquery toggling to show and hide features of a specific product. I have it working, however it's not perfect and wondered if anyone could help please?
Basically what I'm having problems with is that when you use the master open all and then close all of the individual items on their own, I need the master switch to revert back to show all text.
In addition I want to have a + and - icon on each of the items but can't figure out how to only replace the clicked image and not all of them in the list!
Any help would be greatly appreciated, thanks.
Script
$(document).ready(function() {
$('.toggle').hide();
$('.toggler').click(function() {
var target = this.id + '_content';
var imgtarget = this.id + '_expand';
$('#' + target).slideToggle();
$('.toggleall').text('Hide all');
$('<img src="images/collapse.gif">').prependTo('.toggleall');
});
$('.toggleall').click(function() {
if ($('.toggle').is(':visible')) {
$('.toggle').slideUp();
$('.toggleall').text('Show all');
$('<img src="images/expand.gif">').prependTo('.toggleall');
} else {
$('.toggle').slideDown();
$('.toggleall').text('Hide all');
$('<img src="images/collapse.gif">').prependTo('.toggleall');
}
});
});
Html
<div class="toggleall"><img src="images/expand.gif">Show all</div>
<br><br>
<div class="toggler" id="toggle1"><img src="images/expand.gif" class="toggle1_expand">Toggle 1</div>
<div class="toggle" id="toggle1_content">only toggle1</div>
<div class="toggler" id="toggle2"><img src="images/expand.gif" class="toggle2_expand">Toggle 2</div>
<div class="toggle" id="toggle2_content">only toggle2</div>
<div class="toggler" id="toggle3"><img src="images/expand.gif" class="toggle3_expand">Toggle 3</div>
<div class="toggle" id="toggle3_content">only toggle3</div>
Here is the jfiddle of the code (thanks François Wahl): jsfiddle.net/GUYfG
Here is the working version in a proper format :-
$(document).ready(function() {
$('.toggle').hide();
$('.toggler').click( function() {
var target = this.id + '_content';
var imgtarget = this.id + '_expand';
$('#' + target).slideToggle(function(){
if( $('.toggle').is(':visible') ) {
$('.toggleall').text('Hide all');
$('<img src="images/collapse.gif">').prependTo('.toggleall');
} else {
$('.toggleall').text('Show all');
$('<img src="images/expand.gif">').prependTo('.toggleall');
}
});
if( $('.toggle').is(':visible') ) {
$('.toggleall').text('Hide all');
}
});
$('.toggleall').click(function() {
if ($('.toggle').is(':visible')) {
$('.toggle').slideUp();
$('.toggleall').text('Show all');
$('<img src="images/expand.gif">').prependTo('.toggleall');
} else {
$('.toggle').slideDown();
$('.toggleall').text('Hide all');
$('<img src="images/collapse.gif">').prependTo('.toggleall');
}
});
});
EDIT:
Here is the fiddle
I have edited the code check now. Also check the fiddle.
To expand-collapse you can toggle a class with different background images inside a DIV, or use unordered lists (UL / LI).

Categories

Resources