How to get index without counting the hidden elements? - javascript

I'm trying to get the index of clicked element. This works fine so far.
Problem is that you can hide elements. If an element is hidden I don't want it to be "counted" in the index.
If you have a look at the fiddle and all boxes are orange the index is how it should be. If you click on Click me to hide some divs -- they don't get removed, in reality they get a display:none; here they just get another color to give you an idea -- they also get the class hidden so now I don't want the index to index them. But if I click on Div 2 I would like the index to show 1
I've tried with $('div').not('hidden') fiddle here -> http://jsfiddle.net/rva54sy3/2/
<script>
(function($){
var indexBoxes = function(e) {
$element = $(this);
var index = $element.not('.hidden').index();
$( "h3.txt" ).text( "That was div index #" + index );
}
$(document).on( 'click', '.getIndex', indexBoxes);
})(jQuery);
$('.hide-some-divs').on('click',function(){
$('.hide').addClass('hidden').closest('.wrap').addClass('hidden');
});
</script>
<h3 class="txt">Click a div!</h3>
<div class="wrap clearfix">
<div class="getIndex">Div 0</div>
<div class="getIndex hide">Div 1</div>
<div class="getIndex">Div 2</div>
<div class="getIndex hide">Div 3</div>
<div class="getIndex">Div 4</div>
<div class="getIndex hide">Div 5</div>
</div>
<div class="hide-some-divs">Click me to hide some divs</div>
and if you like some styling:
<style>
.getIndex {
width:100px;
height:100px;
margin:5px;
background-color:orange;
float:left;
}
.wrap.hidden > div.hide {
background-color:#fafafa;
}
.hide-some-divs {
background-color:#afafff;
padding:10px;cursor:pointer;
margin:20px auto;
width:250px;
text-transform:uppercase;
text-align:center;
}
.clearfix:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
.clearfix { display: inline-block; }
</style>
Thanks for advices

You can get the index like this way
(function($) {
var indexBoxes = function(e) {
var index = $(".getIndex").not('.hidden').index(this);
$("h3.txt").text("That was div index #" + index);
}
$(document).on('click', '.getIndex', indexBoxes);
})(jQuery);
This will the index of given element corresponding to your selected list(not related to the immediate parent). Here the selected element list is .getIndex class divs which doesnt have the class name .hidden
Fiddle

You can use $.inArray() to get the index of clicked element from visible elements.
(function($){
var indexBoxes = function(e) {
$element = $(this);
var index = ($.inArray((this),$(".getIndex").not(".hidden")));
$( "h3.txt" ).text( "That was div index #" + index );
}
$(document).on( 'click', '.getIndex', indexBoxes);
})(jQuery);
Here's a link to fiddle!

In case you would actually hide them, you could use:
var index = $(".getIndex:visible").index(this);
The selector only counts elements with a class .getIndex that are also visible (aka not display: none)
However, that won't work with your example, because you use a background color to "fake" hiding them.

Related

Swapping text equal in different divs and classes

I have several boxes of cards on one page, these boxes can come dynamically in different, not upper right corner has a text for the click to open the accordion type content, for each class I have to do an action as below, I think of something Regardless of the number of classes.
*new
I do not know how to explain it, I'll try a summary:
Change the text of only one div when clicking, because when I click on the item in the box it changes all the other texts of the
Other boxes.
$('.change-1').click(function () {
var $mudartxt = $('.mudartexto');
if ($mudartxt.text() == 'expandir')
$mudartxt.text('ocultar');
else {
$mudartxt.text('expandir');
}
});
You need to find the current clicked item.
For that you can use the event object
$('.change-1').click(function (e) {
// Get current target as jquery object
var $target = $(e.currentTarget);
// Find mudartexto in current target.
var $mudartxt = $target.find('.mudartexto');
if ($mudartxt.text() == 'expandir')
$mudartxt.text('ocultar');
else {
$mudartxt.text('expandir');
}
});
.change-1 {
display:inline-block;
width:200px;
height:50px;
text-align: center;
background-color:#dfdfdf;
clear: both;
float: left;
margin-top:10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="change-1">
<div class="mudartexto">expandir</div>
</div>
<div class="change-1">
<div class="mudartexto">expandir</div>
</div>
<div class="change-1">
<div class="mudartexto">expandir</div>
</div>
<div class="change-1">
<div class="mudartexto">expandir</div>
</div>
If you are asking how to change text of an element, inside a clicked box, this should do it.
$('.change-1').click(function () {
var $mudartxt = $(this).find('.mudartexto');
if ($mudartxt.text() == 'expandir')
$mudartxt.text('ocultar');
else {
$mudartxt.text('expandir');
}
});

Replace DIV with JQuery passing parameters

I'm having a problem here to create a generic function on JQuery for my "boxes".
I have a visible box with contents, but I will have some other boxes(all DIVs) with another contents and forms. It can be just a DIV ou a full scructured content.
For exemple, a structure like this:
| DIV CONTAINER
|---- DIV CONTACT FORM
|---- ---- DIV RESET PASSWORD
|---- DIV RESET PASSWORD
|---- DIV SIGN UP FORM
|---- DIV RULES
|---- TERMS
Right now I'm doing the box exchanging manually like this code:
$( "#contact-form-link" ).on( "click", function()
{
$( "#contact-form-link" ).fadeOut( "normal", function()
{
$( "#reset-password-form" ).fadeIn( "normal" );
});
});
$( "#reset-password-form" ).on( "click", function()
{
$( "#reset-password-form" ).fadeOut( "normal", function()
{
$( "#contact-form-link" ).fadeIn( "normal" );
});
});
It's unecessary so much code!
I would like to create a function with parameters, so, I can call it from a LINK inside any part of the current box.
A function like:
function exchangeBoxes(box_fadeout,box_fadein)
{
$("box_fadeout").on("click", function()
{
$("box_fadeout").fadeOut( "normal", function()
{
$("box_fadein").fadeIn( "normal" );
});
});
};
So this way, I can call this function from a link passing which DIV will fadeOut and which will fadeIn.
I'm in #contact-form and want to change to #reset-password-form?
Click Here
I need to be able to call the function from any link, anywhere on the page, WITHOUT setting a ID or CLASS for the link, only for the DIVS.
I'm using one function inside another so the IN page only loads when the OUT page is done.
ONLY ONE div can be displayed at time. When one fades out, the other one called will fadeIN. Always callig by the ID, never by CLASS.
Any help to create this generic function is welcome!
Thanks!
You can attach the event to parent div, check id of element at click event, pass the element as either first or second parameter to exchangeBoxes depending on the id of the element.
function exchangeBoxes(a, b) {
$(a).fadeOut( "normal", function() {
$(b).fadeIn( "normal" );
});
}
var elems = ["contact-form-link", "reset-password-form"];
$("#container").on("click", "[id]", function(e) {
if (this.id === elems[0]) {
exchangeBoxes("#" + elems[0], "#" + elems[1])
}
if (this.id === elems[1]) {
exchangeBoxes("#" + elems[1], "#" + elems[0])
}
});
or use multiple selectors when assigning click event
var elems = ["contact-form-link", "reset-password-form"];
$("#contact-form-link, #reset-password-form")
.on("click", function(e) {
exchangeBoxes(this, "#"
+ elems.filter(function(id) {return id !== e.target.id})[0])
});
You could attach a class e.g. exchange to your link and use a data attributes to store the ID of the elements you want to fade in and out.
<a class="exchange" href="#" data-out="#contact-form" data-in="#reset-password-form">Click Here</a>
<a class="exchange" href="#" data-out="#reset-password-form" data-in="#contact-form">Click Here</a>
Then attach an event handler
$(".exchange").on("click", function () {
var data = this.dataset;
$(data.out).fadeOut("normal", function () {
$(data.in).fadeIn("normal");
});
});
If you strictly only focusing on those two DIVs, you could also use fadeToggle() without having to use data attributes
$(".exchange").on("click", function () {
$('#contact-form').fadeToggle("normal", function () {
if ($(this).is(':visible')) {
$("#reset-password-form").fadeOut("normal");
} else {
$("#reset-password-form").fadeIn("normal");
}
});
});
In addition to the answer above, you can also acheive this without using inline onclick. I prefer to keep the javascript separate.
Give each link a data-link with the box they link to. e.g.
Go to box 2
Then in js you can pick this up and do the required fade in/out as per the example:
p.s. sorry for the css I'm really bored with nothing better to do.
$(".box a").click(function() {
linkTo = $(this).data("link");
$(this).parent().fadeOut("normal", function() {
$(linkTo).fadeIn();
});
});
body {
background: #333;
color: #ccc;
font-family:sans-serif;
}
.box {
margin: 0 auto;
width: 300px;
border: 1px solid #ccc;
text-align: center;
display:none;
}
.box a {
text-decoration: none;
color: #ccc;
border:1px solid #ccc;
padding: 10px;
margin: 0 0 10px 0;
display: inline-block;
}
.box a:hover {
background: #333;
color: #ccc;
}
#box1 {
background: #CD5C5C;
display:block;
}
#box2 {
background: #6B8E23;
}
#box3 {
background: #6A5ACD;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div class="container">
<div class="box" id="box1">
<h3 class="title"> I am Box 1 </h3>
Go to box 2
<br>
Go to box 3
</div>
<div class="box" id="box2">
<h3 class="title"> I am Box 2 </h3>
Go to box 1
<br>
Go to box 3
</div>
<div class="box" id="box3">
<h3 class="title"> I am Box 3 </h3>
Go to box 1
<br>
Go to box 2
</div>
</div>
Well, thank you all!
I put all responses together and came up with this:
<div id="contact">
<h3>CONTACT</h3>
<p>My form</p>
Reset Password
About
</div>
<div id="reset" style="display:none">
<h3>RESET</h3>
<p>Reset password form</p>
Back to contact
</div>
<div id="about" style="display:none">
<h3>ABOUT</h3>
<p>Some info.</p>
Back to contact</li>
</div>
And the JQuery very clean:
function exchangeBoxes(a, b)
{
var a = "#" + a;
var b = "#" + b;
$(a).fadeOut( "normal", function()
{
$(b).fadeIn( "normal" );
});
}
Thank you very much, guys!

Prevent children divs from moving while div toggle

I'm new and have I think very simple problem to solve.
I have 4 buttons to show/hide each panel. What should I do to prevent child divs from moving to te left while hiding some div?
I prefer them to stay at the initial position.
This is my code:
HTML:
<button class="panel-button" data-panel="panel1">1</button>
<button class="panel-button" data-panel="panel2">2</button>
<button class="panel-button" data-panel="panel3">3</button>
<button class="panel-button" data-panel="panel4">4</button>
<div class="wrapper">
<div id="panel1">1</div>
<div id="panel2">2</div>
<div id="panel3">3</div>
<div id="panel4">4</div>
</div>
JS:
$(function() {
$('.panel-button').on('click',function(){
var panelId = $(this).data('panel');// attr('data-panel')
$('#'+panelId).toggle();
});
});
CSS:
.wrapper {
overflow: hidden;
width: 420px;
}
.wrapper > div {
width: 100px;
height: 100px;
background: green;
float: left;
margin-left: 5px;
margin-top: 10px
}
Apply css rule opacity = 0; to the div, instead of hiding it.
Like this:
$('.panel-button').on('click',function(){
var pnl = $('#' + $(this).data('panel'));
pnl.css('opacity', pnl.css('opacity') == '0' ? '1' : '0');
});
Solution for clickability issue:
$('.panel-button').on('click',function(){
var pnl = $('#' + $(this).data('panel'));
if(pnl.is(':visible'))
$('<div></div>').appendTo(pnl).width(pnl.width());
else
pnl.next().remove();
pnl.toggle();
});
But still you can use another approach
You can use the visibility property in CSS to achieve this as shown in the below Fiddle link : link
JS Snippet:
$(function() {
$('.panel-button').on('click',function(){
var panelId = $(this).data('panel');// attr('data-panel')
console.log($('#'+panelId).css('visibility'));
if($('#'+panelId).css('visibility') === 'hidden') {
$('#'+panelId).css('visibility','visible');
}
else {
$('#'+panelId).css('visibility','hidden');
}
});
});
The CSS visibility is designed to keep the space a DOM object occupies, but not actually rendering it. Opacity changes its appearance, but not its behavior (eg. still clickable).
So instead of .toggle(), combine visibility with jQuery's .toggleClass():
jsFiddle solution
$(function() {
$('.panel-button').on('click',function(){
var panelId = $(this).data('panel');// attr('data-panel')
$('#'+panelId).toggleClass('hideMe');
});
});

ToggleClass on multiple elements with similar class

I've got a navigation with links, that contain the same classes as the sections of the page. See HTML:
Link 1
Link 2
Link 3
<section class="one">Section 1</section>
<section class="two">Section 2</section>
<section class="three">Section 3</section>
Now I want to add class 'active' to both the link and the section when I click the link. I've got this working with the following jQuery:
$('a').click(function(){
$('.active').removeClass('active');
var activeClass = this.className;
$('.' + activeClass).toggleClass('active');
});
The only problem is that the classes don't toggle. I want the active state to disappear for both the link and the section, when I click an active link. I tried it with the if statement this way:
if($(this).hasClass('active')){
var activeClass = this.className;
$('.' + activeClass).removeClass('active');
}
I guess I'm missing some deeper knowledge here, can anyone help me out? Thanks in advance.
fiddle
You'll have to exclude the currently clicked class from the removeClass statement, otherwise toggleClass will always add the class as you always remove it first.
You should also remove the active from the className when you get it, otherwise you're sometimes getting one active etc. and not just one.
$('a').click(function(){
var activeClass = '.' + $.trim(this.className.replace('active',''));
$('.active').not(activeClass).removeClass('active');
$(activeClass).toggleClass('active');
});
FIDDLE
You just need to rework your script a bit..
<style>
a.active{
color: red
}
section{
height: 200px;
width: 100%;
border: 1px solid black;
margin: 10px 0 10px 0;
}
section.active{
border-color: red!important;
}
</style>
Link 1
Link 2
Link 3
<section class="one active">Section 1</section>
<section class="two">Section 2</section>
<section class="three">Section 3</section>
<script>
$(document).ready(function(){
$('a').on('click', function(){
//remove all active
$('.active').removeClass('active');
//get the class of this link
var activeClass = $(this).attr('class');
$('.' + activeClass).addClass('active');
});//end a.bind
});//end doc.ready
<script>
http://jsfiddle.net/7Q4ph/10/

js Find Class Within Div + toggle CSS/Hide One Show Other

I have 2 divs and each div has a span. By default each span class is set to display: none. I am trying to display: inline the span within whichever div is clicked. If the span is already display: inline then I am trying to revert back to display: none. In other words,
click div1 and span1 shows,
then click div2, span1 hides and span2 shows,
then click div2 again and span2 hides, span1 stays hidden.
How can I achieve this? I am currently stuck on selecting the correct div then I will move on to showing and hiding correctly.
Here is what I currently have:
<html>
<div class="button">foo</div>
<span class='inner'>hey</span> <div class="button">bar</div>
<span class='inner'>hey again</span> </html>
<style>
.inner {
display: none;
}
.button{
display: inline-block;
height:20px;
width:70px;
background-color:#000000;
color:#ffffff;
text-align:center;
} </style>
<script>
$(document).ready(function() {
$('.button').click(function() {
//first off, I am not able to find the span class='inner' within my div.button so this is not correct to find my .inner within $(this)
//alert($(this).find('.inner').html());
//alert($('.inner',this).html());
//then should I do something like this(sorry for the bad syntax, I'm not sure exactly how to write it yet):
//if $(this).('.inner').css('display', 'inline'); { //this span is visible
$(this).('.inner').css('display', 'none'); //so hide this span
else { //span is not visible
$('.inner').hide(); //hide other span
$(this).find('.inner').css('display', 'inline'); //show this span
});
}); </script>
Thank you
Use this,
$(document).ready(function() {
$('.button').click(function() {
var next = $(this).next('.inner');
next.toggle();
$('.inner').not(next).hide();
});
});
Demo Fiddle
Or CSS method,
$(document).ready(function() {
$('.button').click(function() {
var next = $(this).next('.inner');
var cssState = (next.css('display') === 'none')?'inline':'none';
next.css('display',cssState);
$('.inner').not(next).css('display','none');
});
});
Demo Fiddle
.next() - next <span> element.
.toggle() - show/hide based on current state.
You can use jQuery accordian to fix this
All you need to do is import below mentioned lib file
http://code.jquery.com/ui/1.10.4/jquery-ui.js
HTML
<div id="accordion">
<div class="button">foo</div> <span>hey</span>
<div class="button">bar</div> <span>hey again</span>
</div>
JavaScript/jQuery
$(document).ready(function () {
$("#accordion").accordion({
collapsible: true,
active: false
});
})
Please check this demo to get a clear idea
Demo Here
Try,
$('.button').click(function() {
var inner = $(this).next('.inner');
var display = inner.css('display');
inner.css('display',(display === 'none')?'inline':'none');
});
DEMO
Try this :
$(document).ready(function() {
$('.button').click(function() {
$('.inner').hide(); // hide all inner span
$(this).next('.inner').show(); // show next inner span
});
});
Here is the JSFiddle Demo
working code below,please check commenting to understand coding
<script>
$(document).ready(function() {
$(".inner").hide(); //hide all spans
$('.button:first').click(function() {//click on first div
var span1 = $('span:first').show(); // first span will show
});
$('.button:last').click(function() {//click on second div
var span1 = $('span:last').toggle();
var span2 = $('span:first').hide();
});
}); </script>
Test you view this code
.button{
display: inline-block;
height:20px;
width:70px;
background-color:#000000;
color:#ffffff;
text-align:center;
padding:20px;
cursor:pointer;
}
http://jsfiddle.net/kisspa/24jTa/

Categories