I've just finished a creating a bare bones JavaScript tabs functionality for website. Right now I'm having a bit of problem trying to add directional functions in order to switch between tabs. Here is what I've created so far. I'm not sue on how I can increment or decrement the index in order to use the directional arrows to switch tabs and also the content
$(document).ready(function() {
$('.tabs-list li:first-child').addClass('active'),
$('.tab-content .show-content:first-child').addClass('active');
$('.tabs-list li').click(function(e) {
event.preventDefault();
if (!$(this).hasClass('active')) {
var tabIndex = $(this).index();
var nthChild = tabIndex + 1;
// select the right elements
var $tabsList = $(this).parent();
var $tabContent = $tabsList.next('.tab-content');
$tabsList.find('li.active').removeClass('active');
$(this).addClass('active');
$tabContent.find('.show-content').removeClass('active');
$tabContent.find('.show-content:nth-child(' + nthChild + ')').addClass('active');
}
})
$('.prev').on('click', function() {});
$('next').on('click', function() {});
})
.tabs-list li {
display: inline-block;
}
.tab-content .show-content {
display: none
}
.tab-content .show-content.active {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<ul class="tabs-list">
<li>Tab 1</li>
<li>Tab 2</li>
<li>Tab 3</li>
</ul>
<div class="tab-content">
<div class="show-content">
Content 1
</div>
<div class="show-content">
Content 2
</div>
<di>
Content 3
</di>
</div>
</div>
<ul>
<li class="prev">Prev</li>
<li class="next">Next</li>
</ul>
You can do it using jQuery .prev() and .next() methods. You just need to get the current .active tab and change it accordingly.
Here's the code you need:
$('.prev').on('click', function() {
var current = $('.tab-content .show-content.active');
if (current.prev('.tab-content .show-content')[0]) {
current.removeClass('active');
current.prev('.tab-content .show-content').addClass('active');
}
});
$('.next').on('click', function() {
var current = $('.tab-content .show-content.active');
if (current.next('.tab-content .show-content')[0]) {
current.removeClass('active');
current.next('.tab-content .show-content').addClass('active');
}
});
Demo:
This is a working Fiddle and a working Demo snippet:
$(document).ready(function() {
$('.tabs-list li:first-child').addClass('active'),
$('.tab-content .show-content:first-child').addClass('active');
$('.tabs-list li').click(function(e) {
event.preventDefault();
if (!$(this).hasClass('active')) {
var tabIndex = $(this).index();
var nthChild = tabIndex + 1;
// select the right elements
var $tabsList = $(this).parent();
var $tabContent = $tabsList.next('.tab-content');
$tabsList.find('li.active').removeClass('active');
$(this).addClass('active');
$tabContent.find('.show-content').removeClass('active');
$tabContent.find('.show-content:nth-child(' + nthChild + ')').addClass('active');
}
})
$('.prev').on('click', function() {
var current = $('.tab-content .show-content.active');
if (current.prev('.tab-content .show-content')[0]) {
current.removeClass('active');
current.prev('.tab-content .show-content').addClass('active');
}
});
$('.next').on('click', function() {
var current = $('.tab-content .show-content.active');
if (current.next('.tab-content .show-content')[0]) {
current.removeClass('active');
current.next('.tab-content .show-content').addClass('active');
}
});
})
.tabs-list li {
display: inline-block;
cursor: pointer;
}
.tab-content .show-content {
display: none
}
.tab-content .show-content.active {
display: block;
}
.as-console-row-code {
display: none;
}
.prev,
.next {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<ul class="tabs-list">
<li>Tab 1</li>
<li>Tab 2</li>
<li>Tab 3</li>
</ul>
<div class="tab-content">
<div class="show-content">
Content 1
</div>
<div class="show-content">
Content 2
</div>
<div class="show-content">
Content 3
</div>
</div>
</div>
<ul>
<li class="prev">Prev</li>
<li class="next">Next</li>
</ul>
Edit:
To make it loop in a cyclic way and doesn't stop in first or last elements, we should just implement that in the else block of our if statement, so it won't stop.
Here's how will be your code:
$('.prev').on('click', function() {
var current = $('.tab-content .show-content.active');
if (current.prev('.tab-content .show-content')[0]) {
current.removeClass('active');
current.prev('.tab-content .show-content').addClass('active');
} else {
current.removeClass('active');
$(".tab-content .show-content:last").addClass('active');
}
});
$('.next').on('click', function() {
var current = $('.tab-content .show-content.active');
if (current.next('.tab-content .show-content')[0]) {
current.removeClass('active');
current.next('.tab-content .show-content').addClass('active');
} else {
current.removeClass('active');
$(".tab-content .show-content:first").addClass('active');
}
});
And this is an updated Fiddle taking in consideration these changes.
Related
when i scroll the page, i want to add class active menu item.
i can get the current div id like this var currSection = $(this).attr('id'). im stuck with id and data-id matching.
here is the codes. ty for helping guys.
$(document).scroll(function() {
var cutoff = $(window).scrollTop();
$('div').each(function(){
if($(this).offset().top + $(this).height() > cutoff){
$('div').removeClass('current');
$(this).addClass('current');
var currSection = $(this).attr('id');
console.log(currSection);
if ($('.circle li').data('id') == currSection) {
};
return false;
}
});
});
ul{
position:fixed;
z-index:9;
top:0;
}
.active{
color:red;
}
div{
height:500px;
}
div:nth-child(odd){
background:green;
}
div:nth-child(even){
background:blue;
}
<div id="home"></div>
<div id="who"></div>
<div id="team"></div>
<div id="why"></div>
<div id="contact"></div>
<ul class="circle">
<li data-id="home" class="active">a</li>
<li data-id="who">b</li>
<li data-id="team">c</li>
<li data-id="why">d</li>
<li data-id="contact">f</li>
</ul>
Change scroll event listener to this
$(document).scroll(function () {
var cutoff = $(window).scrollTop();
$('div').each(function () {
if ($(this).offset().top + $(this).height() > cutoff) {
$('div').removeClass('current');
$(this).addClass('current');
var currSection = $(this).attr('id');
console.log(currSection);
$('li').removeClass('active');
$('li[data-id=' + currSection + ']').addClass('active');
return false;
}
});
});
Using a variation of the following code, I was able to successfully add one set of Vanilla JavaScript tabs.
Yet how to do I add multiple sets of JavaScript tabs to one page using the same classes in the HTML.
I'm having difficultly creating unique dynamic IDs for the tab selectors and tab content areas using JavaScript. As you can see in https://www.w3.org/TR/wai-aria-practices/examples/tabs/tabs-1/tabs.html, these unique IDs are needed for accessible tags.
var accessibleTabsContainers = document.querySelectorAll('.accessible-tabs-container');
var tabSelector = document.querySelectorAll('.tab-selectors > li');
var tabContent = document.querySelectorAll('.tab-contents > div');
var largeRandNumber = Math.floor((Math.random() * 1000) + 1000);
accessibleTabsContainers.forEach(function(elem, indexAccessibleTabContainer) {
elem.setAttribute('data-id', indexAccessibleTabContainer);
tabSelector.forEach(function(singleTabSelector, i) {
var ariaControlTabContent = 'tab-content-' + largeRandNumber + '-' + i + '_' + indexAccessibleTabContainer;
var tabSelectorId = 'tab-selector-' + largeRandNumber + '-' + i + '_' + indexAccessibleTabContainer;
singleTabSelector.setAttribute('data-id', i);
singleTabSelector.setAttribute('id', tabSelectorId);
singleTabSelector.setAttribute('aria-controls', ariaControlTabContent);
tabContent[i].setAttribute('data-id', i);
tabContent[i].setAttribute('tabindex', 0);
tabContent[i].setAttribute('role', 'tabpanel');
tabContent[i].setAttribute('id', ariaControlTabContent);
tabContent[i].setAttribute('aria-labeledby', tabSelectorId);
if(i === 0) {
tabSelector[i].setAttribute('aria-pressed', 'true');
} else {
tabSelector[i].setAttribute('aria-pressed', 'false');
tabSelector[i].setAttribute('tabindex', -1);
}
});
});
function onTabSelectorClick(e) {
accessibleTabsContainers.forEach(function(accessibleTabsContainer, indexAccessibleTabContainer) {
var tabSelectorSelected = e.target;
var accessibleTabsContainerSelected = tabSelectorSelected.parentElement.parentElement;
if(!tabSelectorSelected.classList.contains('active-tab-selector')) {
var tabSelectorSelectedFromContainer = accessibleTabsContainerSelected.querySelectorAll('.tab-contents > div');
console.log(tabSelectorSelectedFromContainer);
tabSelector.forEach(function(singleTabSelected, i) {
if(tabSelectorSelected.getAttribute('data-id') === tabContent[i].getAttribute('data-id')) {
tabContent[i].classList.add('tab-content-active');
} else {
tabSelector[i].classList.remove('active-tab-selector');
tabSelector[i].setAttribute('aria-pressed', 'false');
tabSelector[i].setAttribute('aria-selected', 'false');
tabSelector[i].setAttribute('tabindex', -1);
tabContent[i].classList.remove('tab-content-active');
}
});
tabSelectorSelected.classList.add('active-tab-selector');
tabSelectorSelected.setAttribute('aria-pressed', 'true');
tabSelectorSelected.setAttribute('aria-selected', 'true');
tabSelectorSelected.removeAttribute('tabindex');
}
});
}
tabSelector.forEach(function(tabSelector) {
tabSelector.addEventListener('click', onTabSelectorClick);
});
.wrapper {
max-width: 960px;
margin: 0 auto;
}
.tab-selectors {
display: inline-block;
}
.tab-selectors > li {
padding: 10px;
}
.tab-selectors > .active-tab-selector {
border: 1px solid #f00;
}
.tab-content {
display: inline-block;
}
.tab-contents > div {
padding: 10px;
border: 2px solid #000;
height: 150px;
width: 150px;
display: none;
}
.tab-contents > .tab-content-active {
display: block;
}
<div class="wrapper">
<h1>Accessible Tabs using Vanilla JavaScript</h1>
<div class="accessible-tabs-container">
<ul role="tablist" aria-lable="Tabs Example" class="tab-selectors">
<li class="active-tab-selector">Tab Selector 1</li>
<li>Tab Selector 2</li>
<li>Tab Selector 3</li>
</ul>
<div class="tab-contents">
<div class="tab-content-active">
Tab Content 1
</div>
<div>
Tab Content 2
</div>
<div>
Tab Content 3
</div>
</div>
</div>
<div class="accessible-tabs-container">
<ul role="tablist" aria-lable="Tabs Example" class="tab-selectors">
<li class="active-tab-selector">Tab Selector 1</li>
<li>Tab Selector 2</li>
<li>Tab Selector 3</li>
</ul>
<div class="tab-contents">
<div class="tab-content-active">
Tab Content 1
</div>
<div>
Tab Content 2
</div>
<div>
Tab Content 3
</div>
</div>
</div>
</div>
I'm trying to generate these unique IDs in line 6 of the Vanilla JavaScript (accessibleTabsContainers.forEach) but it's not working.
Any assistance would be appreciated.
I solved my own issue. In the forEach loop that iterates inside the onTabSelectorClick function, I refactored the code to add the lines below:
var tabSelectorSelected = e.target;
var accessibleTabsContainerSelected = tabSelectorSelected.closest('.accessible-tabs-container');
var tabSelectorsSelectedFromTabs = accessibleTabsContainerSelected.querySelectorAll('ul > li');
Then in a forEach loop instead of iterating through tabSelector (which references var tabSelector = document.querySelectorAll('.tab-selectors > li');) and loops through all tabs li tags, not just the ones referenced by the element clicked, I used tabSelectorsSelectedFromTabs, which references the tab elements inside their parent div tag (var accessibleTabsContainerSelected = tabSelectorSelected.closest('.accessible-tabs-container');), from the tab element (li tag) clicked (var tabSelectorSelected = e.target;).
See https://codepen.io/hollyw00d/pen/JjYJWjG. Also, I added the correct code in this answer. Below is a more useful before and after description of the code:
Incorrect forEach Loop Snippet inside onTabSelectorClick function that is passed in Click Event Handler
var tabSelector = document.querySelectorAll('.tab-selectors > li');
function onTabSelectorClick(e) {
tabSelector.forEach(function() {
// Code here
});
}
Correct forEach Loop Snippet inside onTabSelectorClick function that is passed in Click Event Handler
var tabSelectorSelected = e.target;
var accessibleTabsContainerSelected = tabSelectorSelected.closest('.accessible-tabs-container');
var tabSelectorsSelectedFromTabs = accessibleTabsContainerSelected.querySelectorAll('ul > li');
function onTabSelectorClick(e) {
tabSelectorsSelectedFromTabs.forEach(function() {
// Code here
});
}
var accessibleTabsContainers = document.querySelectorAll('.accessible-tabs-container');
var tabSelector = document.querySelectorAll('.tab-selectors > li');
var tabContent = document.querySelectorAll('.tab-contents > div');
var largeRandNumber = Math.floor((Math.random() * 1000) + 1000);
accessibleTabsContainers.forEach(function(elem, indexAccessibleTabContainer) {
elem.setAttribute('data-id', indexAccessibleTabContainer);
tabSelector.forEach(function(singleTabSelector, i) {
var tabSelectorId = 'tab-selector-' + largeRandNumber + '_' + i + '_' + indexAccessibleTabContainer;
var ariaControlTabContent = 'tab-content-' + largeRandNumber + '_' + i + '_' + indexAccessibleTabContainer;
singleTabSelector.setAttribute('data-id', i);
singleTabSelector.setAttribute('id', tabSelectorId);
singleTabSelector.setAttribute('aria-controls', ariaControlTabContent);
tabContent[i].setAttribute('data-id', i);
tabContent[i].setAttribute('tabindex', 0);
tabContent[i].setAttribute('role', 'tabpanel');
tabContent[i].setAttribute('id', ariaControlTabContent);
tabContent[i].setAttribute('aria-labeledby', tabSelectorId);
if(i === 0) {
singleTabSelector.setAttribute('aria-pressed', 'true');
} else {
singleTabSelector.setAttribute('aria-pressed', 'false');
singleTabSelector.setAttribute('tabindex', -1);
}
});
});
function onTabSelectorClick(e) {
var tabSelectorSelected = e.target;
var accessibleTabsContainerSelected = tabSelectorSelected.closest('.accessible-tabs-container');
var tabSelectorsSelectedFromTabs = accessibleTabsContainerSelected.querySelectorAll('ul > li');
var tabContentsSelectedFromContainer = accessibleTabsContainerSelected.querySelectorAll('.tab-contents > div');
if(!tabSelectorSelected.classList.contains('active-tab-selector')) {
tabSelectorsSelectedFromTabs.forEach(function(singleTabSelected, i) {
if(tabSelectorSelected.getAttribute('data-id') === tabContentsSelectedFromContainer[i].getAttribute('data-id')) {
singleTabSelected.classList.add('active-tab-selector');
singleTabSelected.setAttribute('tabindex', 0);
singleTabSelected.setAttribute('aria-pressed', 'true');
tabContentsSelectedFromContainer[i].classList.add('tab-content-active');
} else {
singleTabSelected.classList.remove('active-tab-selector');
singleTabSelected.setAttribute('tabindex', -1);
singleTabSelected.setAttribute('aria-pressed', 'false');
tabContentsSelectedFromContainer[i].classList.remove('tab-content-active');
}
});
}
}
tabSelector.forEach(function(tabSelector) {
tabSelector.addEventListener('click', onTabSelectorClick);
});
.wrapper {
max-width: 960px;
margin: 0 auto;
}
.tab-selectors {
display: inline-block;
}
.tab-selectors > li {
padding: 10px;
}
.tab-selectors > .active-tab-selector {
border: 1px solid #f00;
}
.tab-content {
display: inline-block;
}
.tab-contents > div {
padding: 10px;
border: 2px solid #000;
height: 150px;
width: 150px;
display: none;
}
.tab-contents > .tab-content-active {
display: block;
}
<div class="wrapper">
<h1>Accessible Tabs using Vanilla JavaScript</h1>
<div class="accessible-tabs-container">
<ul role="tablist" aria-lable="Tabs Example" class="tab-selectors">
<li class="active-tab-selector">Tab Selector 1</li>
<li>Tab Selector 2</li>
<li>Tab Selector 3</li>
</ul>
<div class="tab-contents">
<div class="tab-content-active">
Tab Content 1
</div>
<div>
Tab Content 2
</div>
<div>
Tab Content 3
</div>
</div>
</div>
<div class="accessible-tabs-container">
<ul role="tablist" aria-lable="Tabs Example" class="tab-selectors">
<li class="active-tab-selector">Tab Selector 1</li>
<li>Tab Selector 2</li>
<li>Tab Selector 3</li>
</ul>
<div class="tab-contents">
<div class="tab-content-active">
Tab Content 1
</div>
<div>
Tab Content 2
</div>
<div>
Tab Content 3
</div>
</div>
</div>
</div>
I want to show 3 li and after 1 second these 3 li will be slide up and next 3 li will be automatically show up in the div.#content
<div id="content">
<ul>
<li>122</li>
<li>first</li>
<li>second</li>
<li>third</li>
<li>fourth</li>
<li>fifth</li>
<li>sixth</li>
</ul>
</div>
I tried toggle with setTimeout function, but it does fulfill on my requirements. I know this question may be stupid for someone but believe I really need your guideline please guide me how can i done this task. I will appreciate if someone guide me. I don't want to use any plugin.
A better way (not a semantic way, but) to achieve this is to wrap every 3 <li> and then walk through them. One way is:
$(function () {
var lis = $("ul > li");
for(var i = 0; i < lis.length; i+=3) {
lis.slice(i, i+3).wrapAll("<div class='slide'></div>");
}
$(".slide").hide();
$(".slide:first").slideDown();
setInterval(function () {
if ($(".slide:visible").next(".slide").length == 0) {
$(".slide:visible").slideUp(function () {
$(".slide:first").slideDown();
});
}
else
$(".slide:visible").slideUp(function () {
$(this).next(".slide").slideDown();
});
}, 2500);
});
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<div id="content">
<ul>
<li>122</li>
<li>first</li>
<li>second</li>
<li>third</li>
<li>fourth</li>
<li>fifth</li>
<li>sixth</li>
</ul>
</div>
You can use :lt() and :gt() pseudo selectors
var i = 2,
$ul = $('#content ul'),
int = setInterval(function() {
$('li', $ul).slideUp();
$('li:gt(' + i + '):lt(3)', $ul).slideDown();
i += 3;
if (i + 1 >= $('li', $ul).length) clearInterval(int);
},
2000)
#content ul li:nth-child(n+4) {
display: none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="content">
<ul>
<li>122</li>
<li>first</li>
<li>second</li>
<li>third</li>
<li>fourth</li>
<li>fifth</li>
<li>sixth</li>
<li>first</li>
<li>second</li>
<li>third</li>
<li>fourth</li>
<li>fifth</li>
<li>sixth</li>
</ul>
</div>
UPDATE:
If you want to slide continuously then following code can be used
var i = 2,
$ul = $('#content ul'),
int = setInterval(function() {
$('li', $ul).slideUp();
$('li' + (i == -1 ? '' : ':gt(' + i + ')') + ':lt(3)', $ul).slideDown();
i += 3;
if (i + 1 >= $('li', $ul).length) i = -1;
},
2000)
#content ul li:nth-child(n+4) {
display: none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="content">
<ul>
<li>122</li>
<li>first</li>
<li>second</li>
<li>third</li>
<li>fourth</li>
<li>fifth</li>
<li>sixth</li>
<li>first</li>
<li>second</li>
<li>third</li>
<li>fourth</li>
<li>fifth</li>
<li>sixth</li>
</ul>
</div>
You can try this:
$("li").hide(); // this will hide all li first
$('ul li:lt(3)').show(); // this will display first 3 li from all li
You can do like this,
$("#content ul li").hide();
i = 0;
setInterval(function() {
i = (i + 3) % $("#content ul li").length;
$("#content > ul >li").slideUp();
$("#content > ul >li:gt(" + i + ")").slideDown();
$("#content > ul >li:gt(" + (i + 3) % $("#content ul li").length + ")").hide();
}, 1000);
Fiddle
Here is another possibility:
var steps = 3;
$(function tick() {
setTimeout(function () {
var top = '-=' + (steps * 31) + 'px';
var lis = $('li:lt(' + steps + ')');
var clones = lis.clone().appendTo('ul');
$.when(
$('li').animate({ top: top }, 'slow')
).done(function () {
clones.remove();
lis.appendTo('ul');
$('li').css('top', 'auto');
tick();
});
}, 1000);
});
* {
padding: 0;
margin: 0;
}
ul {
overflow: hidden;
height: 92px;
}
li {
display: block;
position: relative;
line-height: 30px;
padding: 0 10px;
background: #DDD;
margin-bottom: 1px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul><li>A</li><li>B</li><li>C</li><li>D</li><li>E</li><li>F</li><li>G</li><li>H</li></ul>
I am new to YUI. I am wanting to achieve a drag and drop operation with contstraints. I am following the simple YUI 3 guide and was able to achieve the drag and drop according to the code they given which is.
http://yuilibrary.com/yui/docs/dd/scroll-list.html
HTML
<body>
<div id="demo">
<ul id="list1">
<li class="list1">Item #1</li>
<li class="list1">Item #2</li>
<li class="list1">Item #3</li>
<li class="list1">Item #4</li>
<li class="list1">Item #5</li>
<li class="list1">Item #6</li>
<li class="list1">Item #7</li>
<li class="list1">Item #8</li>
<li class="list1">Item #9</li>
<li class="list1">Item #10</li>
<li class="list1">Item #11</li>
<li class="list1">Item #12</li>
</ul>
<ul id="list2">
<li class="list2">Item #1</li>
<li class="list2">Item #2</li>
<li class="list2">Item #3</li>
<li class="list2">Item #4</li>
<li class="list2">Item #5</li>
<li class="list2">Item #6</li>
<li class="list2">Item #7</li>
<li class="list2">Item #8</li>
<li class="list2">Item #9</li>
<li class="list2">Item #10</li>
<li class="list2">Item #11</li>
<li class="list2">Item #12</li>
</ul>
</div>
CSS
yui3-dd-proxy {
text-align: left;
}
#demo {
width: 600px;
}
#demo {
border: 1px solid black;
padding: 10px;
margin: 10px;
zoom: 1;
}
#demo ul li {
border: 1px solid black;
background-color: #8DD5E7;
cursor: move;
margin: 3px;
list-style-type: none;
}
#demo:after { display: block; clear: both; visibility: hidden; content: '.'; height: 0;}
#demo ul {
border: 1px solid black;
margin: 10px;
width: 200px;
height: 400px;
float: left;
padding: 0;
zoom: 1;
position: relative;
overflow: auto;
}
#demo ul li.list1 {
background-color: #8DD5E7;
border:1px solid #004C6D;
}
#demo ul li.list2 {
background-color: #EDFF9F;
border:1px solid #CDCDCD;
}
Javascript
YUI().use('dd-constrain', 'dd-proxy', 'dd-drop', 'dd-scroll', function(Y) {
//Listen for all drop:over events
//Y.DD.DDM._debugShim = true;
Y.DD.DDM.on('drop:over', function(e) {
//Get a reference to our drag and drop nodes
var drag = e.drag.get('node'),
drop = e.drop.get('node');
//Are we dropping on a li node?
if (drop.get('tagName').toLowerCase() === 'li') {
//Are we not going up?
if (!goingUp) {
drop = drop.get('nextSibling');
}
//Add the node to this list
e.drop.get('node').get('parentNode').insertBefore(drag, drop);
//Set the new parentScroll on the nodescroll plugin
e.drag.nodescroll.set('parentScroll', e.drop.get('node').get('parentNode'));
//Resize this nodes shim, so we can drop on it later.
e.drop.sizeShim();
}
});
//Listen for all drag:drag events
Y.DD.DDM.on('drag:drag', function(e) {
//Get the last y point
var y = e.target.lastXY[1];
//is it greater than the lastY var?
if (y < lastY) {
//We are going up
goingUp = true;
} else {
//We are going down.
goingUp = false;
}
//Cache for next check
lastY = y;
Y.DD.DDM.syncActiveShims(true);
});
//Listen for all drag:start events
Y.DD.DDM.on('drag:start', function(e) {
//Get our drag object
var drag = e.target;
//Set some styles here
drag.get('node').setStyle('opacity', '.25');
drag.get('dragNode').set('innerHTML', drag.get('node').get('innerHTML'));
drag.get('dragNode').setStyles({
opacity: '.5',
borderColor: drag.get('node').getStyle('borderColor'),
backgroundColor: drag.get('node').getStyle('backgroundColor')
});
});
//Listen for a drag:end events
Y.DD.DDM.on('drag:end', function(e) {
var drag = e.target;
//Put our styles back
drag.get('node').setStyles({
visibility: '',
opacity: '1'
});
});
//Listen for all drag:drophit events
Y.DD.DDM.on('drag:drophit', function(e) {
var drop = e.drop.get('node'),
drag = e.drag.get('node');
//if we are not on an li, we must have been dropped on a ul
if (drop.get('tagName').toLowerCase() !== 'li') {
if (!drop.contains(drag)) {
drop.appendChild(drag);
//Set the new parentScroll on the nodescroll plugin
e.drag.nodescroll.set('parentScroll', e.drop.get('node'));
}
}
});
//Static Vars
var goingUp = false, lastY = 0;
//Get the list of li's in the lists and make them draggable
var lis = Y.all('#demo ul li');
lis.each(function(v, k) {
var dd = new Y.DD.Drag({
node: v,
target: {
padding: '0 0 0 20'
}
}).plug(Y.Plugin.DDProxy, {
moveOnEnd: false
}).plug(Y.Plugin.DDConstrained, {
constrain2node: '#demo'
}).plug(Y.Plugin.DDNodeScroll, {
node: v.get('parentNode')
});
});
Y.one('#make').on('click', function(e) {
YUI().use('dd-drag', 'dd-proxy', function(Y) {
//Selector of the node to make draggable
var dd = new Y.DD.Drag({
container: '#demo',
node: 'li'
}).plug(Y.Plugin.DDProxy); //This config option makes the node a Proxy Drag
var demo =Y.one('#demo ul');
for (var i = 1; i < 11; i++) {
//demo.append('<li class="list3">New item #' + i + '</i><br>');
demo.append('<li class="list3">Item #' + i + '</li>' )
}
})
});
//Create simple targets for the 2 lists.
var uls = Y.all('#demo ul');
uls.each(function(v, k) {
var tar = new Y.DD.Drop({
node: v
});
});
});
YUI().use('dd-delegate', 'dd-drop-plugin', 'dd-constrain', 'dd-proxy', function(Y) {
var del = new Y.DD.Delegate({
container: '#demo',
nodes: 'li'
});
del.on('drag:start', function(e) {
e.target.get('node').setStyle('opacity', '.5');
});
del.on('drag:end', function(e) {
e.target.get('node').setStyle('opacity', '1');
});
del.dd.plug(Y.Plugin.DDConstrained, {
constrain2node: '#play'
});
del.dd.plug(Y.Plugin.DDProxy, {
moveOnEnd: false,
cloneNode: true
});
var drop = Y.one('#drop').plug(Y.Plugin.Drop);
drop.drop.on('drop:hit', function(e) {
drop.set('innerHTML', 'You dropped: <strong>' + e.drag.get('node').get('innerHTML') + '</strong>');
});
});
I would like to Contrain the left drag meaning when i drag the blue over to the yellow. I would like to repopulate the blue item once it is dropped in the yellow area. The YUI guide has something similar to what I want to achieve here:
http://yuilibrary.com/yui/docs/dd/delegate-plugins.html
I am not quite clear on how to implement these two operations together to achieve the effect I need.
Any help would be good.
thanks
Javascript
YUI().use('dd-delegate', 'dd-drop-plugin', 'dd-constrain', 'dd-proxy', function(Y) {
var del = new Y.DD.Delegate({
container: '#demo',
nodes: 'li'
});
del.on('drag:start', function(e) {
e.target.get('node').setStyle('opacity', '.5');
});
del.on('drag:end', function(e) {
e.target.get('node').setStyle('opacity', '1');
});
del.dd.plug(Y.Plugin.DDConstrained, {
constrain2node: '#play'
});
del.dd.plug(Y.Plugin.DDProxy, {
moveOnEnd: false,
cloneNode: true
});
var drop = Y.one('#drop').plug(Y.Plugin.Drop);
drop.drop.on('drop:hit', function(e) {
drop.set('innerHTML', 'You dropped: <strong>' + e.drag.get('node').get('innerHTML') + '</strong>');
});
});
http://jsfiddle.net/deepansh/BHCZ4/2/ this is a fiddle.
I want to save toggle state in cookie so that after page reload I get the same state, and I want to close previously-open list after clicking for opening new list.
I want to do in in minimum lines.
HTML
<ul class="nav sidebar-nav" id="am_menu">
<li> <span>User</span>
<ul>
<li>Add User
</li>
<li>List User
</li>
<li>User Profile
</li>
</ul>
</li>
<li> <span>User</span>
<ul>
<li>Add User
</li>
<li>List User
</li>
<li>User Profile
</li>
</ul>
</li>
</ul>
CSS:
ul {
width: 200px;
}
img {
width: 14px;
}
li ul {
display: none;
}
li ul {
padding-left: 4em;
list-style:none;
}
li ul li {
line-height:35px;
}
li ul li ul {
padding-left: .5em;
}
JS
$(function () {
$('li').filter(function (i) {
return $('ul', this).length >= 1;
}).each(function (i) {
$(this).children("a")
.click(function (e) {
var $ul = $(this).next("ul");
if ($ul.is(":visible")) {
$ul.find("ul").toggle("slow()");
$ul.toggle("slow()");
} else {
$ul.toggle("slow()");
};
})
});
});
I'd personally take the approach (using, as in Arun's answer, the $.cookie plugin):
$(function () {
var toShow = $.cookie('lastShownIndex'),
topLevel = $('#am_menu').find('> li');
topLevel.click(function(){
$(this).children('ul').slideToggle().end().siblings().children('ul').slideUp();
$.cookie('lastShownIndex', $(this).index());
}).eq(toShow).find('ul').show();
});
JS Fiddle demo.
References:
children().
click().
end().
eq().
find().
index().
show().
slideUp().
jQuery cookie plugin is used
$(function () {
$('#am_menu li:has(ul) > a').click(function (e) {
var $ul = $(this).next("ul");
$ul.toggle("slow");
$('#am_menu li ul').not($ul).slideUp();
$.cookie('curr.menu', $(this).parent().index())
});
var cindex = $.cookie('curr.menu');
if (cindex != undefined) {
$('#am_menu li:has(ul)').eq(cindex).children('a').click()
}
});
Demo: Fiddle