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/
Related
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/
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();
});
I want to be able to drag an element on the page into a droppable element inside an ajax loaded div. I can get the code to work when I place the droppable element in the regular page but not when i have the same element on the ajax loaded div. Im pretty sure its because of the way I'm calling scripts and how they load on the dom, but I can't find the solution. Note: I have tried calling the code which loads the ajax content before calling jquery ui but that didn't work either.
Here is how I'm calling everything, I removed the extraneous code for brevity.
main page
<head>
<scripts -- jquery, jquery ui>
<script>
$(document).ready(function(){
$( "#site-preview" ).load( "/site/preview" );
});
</script>
</head>
<body>
<div class="draggable><img src=//etc/> </div>
//if I put this div here, I can drop to it, so i know the drop code works.
// <div class="droppable col-md-2" style="height:100px;border:1px solid gray"><p> </p></div>
<div id="site-preview"></div>
<script>
$(function() {
$( ".draggable" ).draggable({
helper:'clone',
appendTo: 'body',
scroll: false
});
$( ".droppable" ).droppable({
drop: function( event, ui ) {
$( this ).addClass( "ui-state-highlight" ).find( "p" ).html( "Dropped!" );
}
});
});
</script>
</body>
ajax loaded code
<div class="droppable col-md-2" style="height:100px;border:1px solid gray">
<p> </p>
</div>
This appends because you try to call the droppable on a non-existing element at that moment. To solve this, you could use the callback function that can be attached to the load function and run the rest after that.
$(document).ready(function(){
$("#site-preview").load("/site/preview", function() {
// Page loaded and injected
// We launch the rest of the code
$( ".draggable" ).draggable({
helper:'clone',
appendTo: 'body',
scroll: false
});
$( ".droppable" ).droppable({
drop: function( event, ui ) {
$( this ).addClass( "ui-state-highlight" ).find( "p" ).html( "Dropped!" );
}
});
});
});
You can find other information about the load function here. The callback can take arguments and can be used, for example to check if it's a 404 or not.
Well I was able to get it to work by adding the draggable/droppable code to the ajax loaded div itself.
So the above would be amended like so
ajax loaded code
<div class="droppable col-md-2" style="height:100px;border:1px solid gray">
<p> </p>
</div>
<script>
$(function() {
$( ".draggable" ).draggable({
helper:'clone',
appendTo: 'body',
scroll: false //stops scrolling container when moved outside boundaries
});
$( ".droppable" ).droppable({
drop: function( event, ui ) {
$( this ).addClass( "ui-state-highlight" ).find( "p" ).html( "Dropped!" );
}
});
});
</script>
And those script lines would be taken out of the main page
Ajax is Asynchronous. So if you call some ajax and then call some other command, the ajax will usually finish afterwards.
This is where callbacks are useful. Try adding a callback to the ajax load call as shown here: http://api.jquery.com/load/
Something like:
$( "#site-preview" ).load( "/site/preview", function(){
$( ".droppable" ).droppable({
drop: function( event, ui ) {
$( this ).addClass( "ui-state-highlight" ).find( "p" ).html( "Dropped!" );
}
});
});
Side note: you should probably start using scripts instead of <script> tags.
I'm not new to code here, but this is my first question on SO, so if my etiquette is off excuse me just this once. I've looked around for support on this, and it doesn't seem many people are running into this problem.
I'm playing with jQuery-UI for the dragging and dropping elements, and for the most part it's working fine. However when I drag something from a 'tabbed' div into a droppable area it jumps a couple hundred pixels below it. It's especially odd because I've got it set to revert it's position on an invalid drop, and that's working, but it ignores this rule on the first drop that makes it jump. I'm not sure if this is something in the CSS position style, or if I'm not setting my UI attributes correctly.
http://www.putoutsystems.com/jtest/
Hit the consumables tab > drag the item into the bin. You should see the behavior I'm describing. I'm using jQuery 1.10.2 and jQuery UI 1.10.4
This is all the code for the app:
<link href="css/pepper-grinder/jquery-ui-1.10.4.custom.css" rel="stylesheet">
<style>
#potion { width: 24px; height: 24px; position:relative;}
#tabs { width: 500px; height: 100px;}
#droppable { width: 500px; height: 100px;}
.inventoryTab { height: 40px; }
</style>
<!-- libraries -->
<script src="js/jquery-1.10.2.js"></script>
<script src="js/jquery-ui-1.10.4.custom.js"></script>
<!--functions -->
<script>
//functions
$(function() {
//Dragable Elements
$( ".draggable" ).draggable({ revert: "invalid"});
//Hover Text
$( document ).tooltip();
//droppable elements
$( "#droppable" ).droppable({
drop: function( event, ui ) {
$( this )
.addClass( "ui-state-highlight" )
.find( "p" )
.html( "FULL!" );
$(ui.draggable).appendTo($(this));
}
});
//Tab Interface
$( "#tabs" ).tabs();
});
</script>
</head>
<body>
<!-- Inventory tabs-->
<div id="tabs">
<ul>
<li>Equipment</li>
<li>Consumables</li>
<li>Items</li>
</ul>
<div id="tabs-1" class="inventoryTab" >
</div>
<div id="tabs-2" class="inventoryTab" >
<div id="potion" class="draggable">
<img src="sprites/potion.png" alt="potion" title="Minor Health Potion">
</div>
</div>
<div id="tabs-3" class="inventoryTab" >
</div>
</div>
<br>
<!-- The Bin --->
<h1>The BIN</h1>
<div id="droppable" class="ui-widget-header">
<p>Empty!</p>
</div>
UPDATE: I've come up with a bandaid solution that sets an exact position, that I suppose I could change using variables based on how many objects are in the bin. Check our this code for droppable event:
//droppable elements
$( "#droppable" ).droppable({
drop: function( event, ui ) {
$( this )
.addClass( "ui-state-highlight" )
.find( "p" )
.html( "FULL!" );
$(ui.draggable).appendTo($(this));
$(ui.draggable).css({
'top': '10px',
'left': '10px'
});
}
});
I'd prefer it if the object got the mouse position when it was dropped, but that's where my jQuery is failing me right now. I'll keep looking.
JSFIDDLE
It seems like you don't need this line $(ui.draggable).appendTo($(this));
//functions
$(function () {
//Dragable Elements
$(".draggable").draggable({
revert: "invalid"
});
//Hover Text
$(document).tooltip();
//droppable elements
$("#droppable").droppable({
drop: function (event, ui) {
$(this)
.addClass("ui-state-highlight")
.find("p")
.html("FULL!");
//$(ui.draggable).appendTo($(this)); // comment this out
}
});
//Tab Interface
$("#tabs").tabs();
});
JSFIDDLE DEMO
I've researched many posts and I still did not find a solution, either all sliderboxes (a box which slideDown() on click) open simultaniously with $('[id^="sliderbox-"]') or I just simply dont understand how to apply the jquery code specifically to my slider.
This is my code:
$( "#open2" ).click(function () {
if ( $( "#sliderbox2" ).is( ":hidden" ) ) {
$( "#sliderbox2" ).slideDown( "slow" );
$( ".arrow2").delay(300).fadeIn(500);
$(".balken2").delay(500).fadeIn(500);
$( "#sliderbox" ).slideUp( "slow" );
$( ".arrow" ).fadeOut(100);
$( ".balken" ).fadeOut(100);
var y = $(window).scrollTop(); //your current y position on the page
$('html, body').animate({
scrollTop: y+150
},500);
} else {
$( "#sliderbox2" ).slideUp( "slow" );
$( ".arrow2" ).fadeOut(100);
$( ".balken2" ).fadeOut(100);
}
});
I guess you can already see the "2" cause this is the second sliderbox to be opened, there are also the arrows for the slider which fade in and a thick border in the button.
I have 20 sliders, and i dont want to repeate css and jquery code 20 times!
This is the html:
<img src="images/pfeilunten2.png" class="pfeilunten" style="margin-left:0;" id="open3"/>
<div id="sliderbox3" class="sliderbox">
<div id="carousel">
<div id="carousel_inner">
<ul id="carousel_ul3" class="carousel_ul">
<div id="zentriercarousel">
<li>...</li>
</div>
</ul>
</div>
<div class="scroll_left scroll">
<img src="images/arrowleft.png" class="arrow3" /> </div>
<div class="scroll_right scroll">
<img src="images/arrowright.png" class="arrow3" />
</div>
<input id="hidden_auto_slide_seconds" type="hidden" value="0" />
<div class="balken3"></div>
</div>
</div>
Ans as you can see, there is already code for the third slider, and i have to rename EVERYTHING. That really sucks! Your help would be so much appreciated, please answer specific on this code, thanks in advance!
The way I would approach this is to give all the links that open a slider a class, say "open", I would give them all a data-slider property, something like this:
Open Slider
You jquery function can then become generic:
$( ".open" ).click(function () {
var sliderNumber = $(this).data("slider");
if ( $( "#sliderbox" + sliderNUmber ).is( ":hidden" ) ) {
$( "#sliderbox" + sliderNUmber ).slideDown( "slow" );
$( ".arrow" + sliderNUmber).delay(300).fadeIn(500);
$(".balken" + sliderNUmber).delay(500).fadeIn(500);
$( "#sliderbox" ).slideUp( "slow" );
$( ".arrow" ).fadeOut(100);
$( ".balken" ).fadeOut(100);
var y = $(window).scrollTop(); //your current y position on the page
$('html, body').animate({
scrollTop: y+150
},500);
} else {
$( "#sliderbox" + sliderNUmber ).slideUp( "slow" );
$( ".arrow" + sliderNUmber ).fadeOut(100);
$( ".balken" + sliderNUmber ).fadeOut(100);
}
});
Now your slider function is more generic, and you can re-use it as many times as you want, just have to make sure you add the data-slider number to each link and make sure the sliding elements have the right IDs
Hope this helps.