retain toggle states of multiple elements on page reload - javascript

I'm trying to retain the toggle state of my elements when the page is reloaded. Right now, they all close on refresh.
I've tried to set a cookie on slideToggle, slideUp & slideDown but I have never used cookies before in this context.
jQuery
/* global jQuery */
jQuery( document ).ready( function( $ ) {
// The element to hide/reveal
$( '.bodhi-hide-reveal' ).hide();
$( '.bodhi-reveal-trigger' ).removeClass( 'closed' );
// The trigger to hide/reveal
$( '.bodhi-reveal-trigger' ).click( function( e ) {
e.preventDefault();
// Target only the next element to hide/reveal and toggle it
$( this ).next( '.bodhi-hide-reveal' ).slideToggle();
// Toggle the trigger class
$( this ).toggleClass( 'closed' );
});
// Expand/collapse all button
$( '.expand-collapse-all' ).click( function( e ) {
e.preventDefault();
// Check if there is at least one closed div
if ( $( '.bodhi-reveal-trigger.closed' ).length ) {
$( '.bodhi-reveal-trigger' ).removeClass( 'closed' )
$( '.bodhi-hide-reveal' ).stop().slideUp();
} else if ( $( '.bodhi-reveal-trigger.opened' ).length ) {
$( '.bodhi-reveal-trigger' ).addClass( 'opened' )
$( '.bodhi-hide-reveal' ).stop().slideDown();
} else {
$( '.bodhi-hide-reveal' ).slideToggle();
}
});
});
HTML
<button class="expand-collapse-all">
Expand / Collapse All
</button>
<div class="bodhi-reveal-trigger">
<button>The Trigger</button>
</div>
<div class="bodhi-hide-reveal">
<p>Some content inside the div that will be hidden and revealed.</p>
</div>
<div class="bodhi-reveal-trigger">
<button>The Trigger</button>
</div>
<div class="bodhi-hide-reveal">
<p>Some content inside the div that will be hidden and revealed.</p>
</div>
<div class="bodhi-reveal-trigger">
<button>The Trigger</button>
</div>
<div class="bodhi-hide-reveal">
<p>Some content inside the div that will be hidden and revealed.</p>
</div>
<div class="bodhi-reveal-trigger">
<button>The Trigger</button>
</div>
<div class="bodhi-hide-reveal">
<p>Some content inside the div that will be hidden and revealed.</p>
</div>
Fiddle
https://jsfiddle.net/Benbodhi/5k9syzhj/

Related

Toggle elements view on buttons click

I have different divs which all have the same class "textBox".
At the same time there should always just be one box displayed. For most Boxes there is a button on the bottom of my page which can be clicked and triggers
to make the box visible and hide the box which is already shown at this moment.
Edit: Fiddle https://jsfiddle.net/8uvsq7ta/
For this I have this JS-code:
$( "#gettingStartedButton" ).click( function () {
if (! $( "#gettingStarted" ).is( ":visible" ) ) {
if ( $( "#extension" ).is( ":visible" ) ) {
$( "#extension" ).fadeOut( function () {
$( "#gettingStarted" ).fadeIn();
});
}
else if ( $( "#executingBox" ).is( ":visible" ) ) {
$( "#executingBox" ).fadeOut( function () {
$( "#gettingStarted" ).fadeIn();
});
}
else if ( $( "#feedback" ).is( ":visible" ) ) {
$( "#feedback" ).fadeOut( function () {
$( "#gettingStarted" ).fadeIn();
});
}
else if ( $( "#impressum" ).is( ":visible" ) ) {
$( "#impressum" ).fadeOut( function () {
$( "#gettingStarted" ).fadeIn();
});
}
else if ( $( "#registration" ).is( ":visible" ) ) {
$( "#registration" ).fadeOut( function () {
$( "#gettingStarted" ).fadeIn();
});
}
}
else {
$( "#gettingStarted" ).fadeOut( function () {
$( "#executingBox" ).fadeIn();
});
}
});
The div boxes look like this:
<div id="gettingStarted" class="textBox">
test blabla
</div>
<div id="feedback" class="textBox">
test blabla
</div>
<div id="registration" class="textBox">
test blabla
</div>
<div id="impressum" class="textBox">
test blabla
</div>
CSS:
.textBox {
diplay: none;
}
This Code checks if the box is already shown and if yes it checks EVERY OTHER BOX to get the one which is visible and then fade it out to afterwards fade the reffered box in.
My problem is, I need this part of code for every box. I think there should be a better way to accomplish this.
What I am searching is kind a method openBox(id) where I give the id of the box as paramete and it automatically detects all other boxes with the class parameter and detects which is already faded in, then fades this out to fade the box with the id in.
Sadly my javascript skills aren't that good, so I seek to find some advices or examples how to achieve this.
Thank you very much for every input you can give me.
var $textBox = $(".textBox"); // get 'em all!
$textBox.eq(0).fadeIn(); // FadeIn first one
$("[data-showid]").on("click", function(){ // Buttons click (Use data-* attribute!)
var $box = $("#"+ this.dataset.showid); // Get the target box ID element
$textBox.not($box).hide(); // Hide all bot targeted one
$box.stop().fadeToggle(); // FadeToggle target box
});
.textBox{display:none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="gettingStarted" class="textBox">getting started blabla</div>
<div id="feedback" class="textBox">feedback blabla</div>
<div id="impressum" class="textBox">impressum blabla</div>
<button data-showid="gettingStarted">GS</button>
<button data-showid="feedback">FB</button>
<button data-showid="impressum">Imp</button>
If you don't want the current box to toggle, than instead of .fadeToggle() use .fadeIn().
http://api.jquery.com/fadetoggle/
https://api.jquery.com/data/
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset
With the addition of a data-* attribute on your button to link it to its content:
<button id="gettingStartedButton" data-link="gettingStarted">GS</button>
<button id="feedbackButton" data-link="feedback">FB</button>
<button id="impressumButton" data-link="impressum">Imp</button>
The javascript becomes very simple:
$( "#gettingStarted" ).fadeIn();
$('button').click(function(){
var link = $(this).data('link');
$('.textBox:visible').fadeOut(function(){
$('#' + link).fadeIn()
});
})
Updated fiddle: https://jsfiddle.net/8uvsq7ta/2/
I did it using class. The HTML would be like :
<div class="textBox gettingStartedButton" style="display: none;"> 1 test blabla </div>
<div style="display: none;" id="feedback" class="textBox .gettingStartedButton gettingStartedButton"> 2 test blabla </div>
<div id="registration" class="textBox gettingStartedButton" style="display: block;">3 test blabla </div>
<div id="impressum" class="textBox"> 4 test blabla </div>
And use the code below. Keep any element visible at first. Then on click of that element it fades it out and fades the next element in. and adds the class "gettingStartedButton" to the visible element to run click event again.
$( ".gettingStartedButton" ).on('click', function () {
var visible_element = $('.textBox:visible');
visible_element.next().fadeIn();
visible_element.next().removeClass('gettingStartedButton');
visible_element.next().addClass('gettingStartedButton');
visible_element.fadeOut();
});

How to find all events inside a container and delegate them

Suppose I have a markup like this
<div class="container">
<div class="abc" onclick="alert(this.innerHTML)">ABC</div>
<div class="abc1">ABC</div>
<div class="abc2">abc2</div>
<div class="xys3">xys3</div>
<div class="asd23">asd223</div>
</div>
And there are events which are bind to the children of a container like this
$( ".abc1" ).bind( "click", function(){
alert( $( this ).html() );
} );
$( ".abc2" ).bind( "click", function(){
alert( $( this ).html() );
} );
$( ".xys3" ).bind( "click", function(){
alert( $( this ).html() );
} );
$( ".asd23" ).bind( "click", function(){
alert( $( this ).html() );
} );
Now, I get the html out of container and set it back again :
var html = $( ".container" ).html();
// a set missing here to convert 'bind' events to 'on' events
$( ".container" ).html( html );
Events won't work now since they were not delegated to start with. Also, container may be having more elements (they are dynamic).
Is it possible to find all events inside a container and delegate them?
Here is a Fiddle
As of jQuery 1.7, the .on() method is the preferred method for attaching event handlers to a document. For earlier versions, the .bind() method is used for attaching an event handler directly to elements.
So just use event delegation on() and it will solve the problem :
$( "body" ).on( "click", ".abc2", function(){
alert( $( this ).html() );
});
You could add a general class to all divs then attach click event to it :
HTML :
<div class="container">
<div class="my-class abc" onclick="alert(this.innerHTML)">ABC</div>
<div class="my-class abc1">ABC</div>
<div class="my-class abc2">abc2</div>
<div class="my-class xys3">xys3</div>
<div class="my-class asd23">asd223</div>
</div>
JS :
$( "body" ).on( "click", ".my-class", function(){
alert( $( this ).html() );
});
Hope this helps.
$( "body" ).on( "click", ".my-class", function(){
alert( $( this ).html() );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="my-class abc" onclick="alert(this.innerHTML)">ABC</div>
<div class="my-class abc1">ABC</div>
<div class="my-class abc2">abc2</div>
<div class="my-class xys3">xys3</div>
<div class="my-class asd23">asd223</div>
</div>
The delegation methods are like this:
$(document).on( "click", ".abc1", function(){
alert( $( this ).html() );
});
You can change $(document) with an element in the DOM that hasn't change and it's parent of the children you need to delegate. With document will works in every cases, but the performance can be less.

paragraph Select() doesn't work in javascript

Here is my html code
<div id="dialog" title="Basic dialog" style="display: none">
<p id="para">Copy this key</p>
<p id="key">4567887654345678</p>
</div>
<button>Open dialog</button>
The div appears as a dialog on button click, and I would like to have the "key" text selected when the dialog opens
Here is the javascript for the same, but the < p> doesn't appear to be selected
$(function() {
$( "button" ).click(function() {
$("#dialog" ).dialog();
$( "#dialog" ).show( "slow" );
$("#key").select();
});
});
How can I make the < p> be pre-selected ?
Change the key paragraph to an editable element, such as a textarea:
<textarea id="key">4567887654345678</textarea>
JSFiddle
It appears you need an editable text field to select text in.
I think you should use jQuery dialog open event:
$( "#dialog" ).dialog({
open: function( event, ui ) {
$("#key").select();
}
});
JSFiddle

How can I have only one div shown at a time?

I have this code but I'm not sure how to make it so that each time one button is clicked, it closes the other div that is already open. New to jquery!
HTML:
<p class="profile-name">Name</p><br>
<p class="profile-title">Documentation Officer</p><br>
<button id="button-g" class="bio-button">Bio</button><br>
<a class="profile-email" href="mailto:email#test.com">email#test.com</a>
<div class="toggler">
<div id="effect-g" class="profile-bio">
<p>Bio information. Bio Information</p>
</div>
</div>
JQUERY:
<script>
$(function() {
$( "#button-a" ).click(function() {
$( "#effect-a" ).slideToggle( "visible");
});
$( "#button-b" ).click(function() {
$( "#effect-b" ).slideToggle( "visible");
});
$( "#button-c" ).click(function() {
$( "#effect-c" ).slideToggle( "visible");
$("#button-b").hide();
});
$( "#button-d" ).click(function() {
$( "#effect-d" ).slideToggle( "visible");
});
$( "#button-e" ).click(function() {
$( "#effect-e" ).slideToggle( "visible");
});
$( "#button-f" ).click(function() {
$( "#effect-f" ).slideToggle( "visible");
});
$( "#button-g" ).click(function() {
$( "#effect-g" ).slideToggle( "visible");
});
});
</script>
It's rarely wise to target a zillion elements by ID (or any other unique attribute) in a uniform, repetitive structure. Give all your buttons and all your collapsible siblings the same classes, respectively, then do this (or something similar--I can't be more specific without seeing your HTML):
$('.my-button-class').click(function() {
$(this).next('.my-collapsible-div-class').slideDown()
.siblings('.my-collapsible-div-class').slideUp();
});
This assumes markup like this:
<button class="my-button-class">Button</button>
<div class="my-collapsible-div-class"> ... </div>
<button class="my-button-class">Button</button>
<div class="my-collapsible-div-class"> ... </div>
<button class="my-button-class">Button</button>
<div class="my-collapsible-div-class"> ... </div>
Update based on your HTML:
$('.bio-button').click(function () {
$(this).nextAll('.toggler:first').slideToggle()
.siblings('.toggler').slideUp();
});
Demo
http://api.jquery.com/nextall
http://api.jquery.com/first-selector
Off-topic suggestion: Use CSS margin or padding rather than line breaks to format your content. Extra markup elements for spacing is ugly and inefficient.
Give the div's a common class, and a custom data attribute with the letter of the next div to open, then combine this into a single function. Sample div:
<div id="effect-a" class="effect"></div>
Sample button
<button id="button-a" class="button" data-letter="a">Click me</button>
Single function
$(".button").click(function() {
//Slide up any open divs
$(".effect").slideUp();
var divLetter = $(this).data("letter") //a
//Concatenate selector
$("#effect-" + divLetter).slideDown();
});

Jquery Expand Collapse

I am having trouble with jquery expand and collapse.
I am planning to have a read more function over my site and i want to make use of this example.
http://www.designgala.com/demos/collapse-expand-jquery.html
if you could see clicking the header expands the content and clicking twice gives a result of minimizing but my issue here is to show some part of the content like 30px height from the div and when the header is clicked it would expand and show the whole content.
I created a jsfiddle which shows a way to do what you are looking to do.
http://jsfiddle.net/cSvAB/2/
Here is the javascript:
$( '.section' ).each( function( index, value ){
$( value ).data( 'height', $( this ).height() );
$( value ).css( {height: 30} );
});
$( '.section .header' ).click( function(){
if( $( this ).data( 'expanded' ) ){
$( this ).parent().animate( {height: 30} );
$( this ).data( 'expanded', false );
}else{
$( this ).parent( ).animate( {height: $( this ).parent().data( 'height' )} );
$( this ).data( 'expanded', true );
}
});
and here is the HTML:
<div class="section">
<div class="header">Click to read more</div>
<div>Lots of text here</div>
</div>
<div class="section">
<div class="header">Click to read more</div>
<div>Lots of text here</div>
</div>
The only other important thing is that .section is given the css attribute overflow: hidden;
.section{ overflow: hidden; }
What you want is actually an Accordion. You can use jQuery UI's accordion if you want a more professional look. Here it is: jqueryui.com/accordion/

Categories

Resources