Up and down slide dropdown in vue js - javascript

.main ul {
height: 100px;
width: 200px;
background: gray;
overflow:hidden
}
.main a {
margin: 10px 0;
}
<div class="main">
Up
<ul>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
</ul>
Down
</div>
Now i want if i click up button then list item should be slide up and if i click down button the list item should going down. How can i do this by vue js please anyone help me.

Is this the effect that you were hoping to achieve? Liberal use of querySelector, querySelectorAll and various sibling selectors make this a relatively straight forward task.
// assign event handler to each hyperlink which themselves have a dataset attribute to aid identification
document.querySelectorAll('a[data-dir]').forEach( a=>a.addEventListener('click',function(e){
// the css class that will be assigned to indicate selected item
const cn='active';
let ul=this.parentNode.querySelector('ul');
let col=Array.from( ul.querySelectorAll('li') );
// prevent highlist disappearing
if( ( ul.querySelector('li.active')==ul.lastElementChild && this.dataset.dir=='down' ) || ( ul.querySelector('li.active')==ul.firstElementChild && this.dataset.dir=='up' ) )return false;
// If no active element is found, make the first LI active.
if( !ul.querySelector('li.active') )ul.firstElementChild.classList.add( cn );
else{
// otherwise process all LI elements until we find the active element
col.some( li=>{
if( li.classList.contains(cn) ){
// clear an other instances of the active class
col.forEach(n=>n.classList.remove(cn));
// highlight appropriate previous/next LI element
switch( this.dataset.dir ){
case 'up':
if( li.previousElementSibling!=null && li.previousElementSibling.tagName=='LI' )li.previousElementSibling.classList.add(cn)
break;
case 'down':
if( li.nextElementSibling!=null && li.nextElementSibling.tagName=='LI' )li.nextElementSibling.classList.add(cn);
break;
}
return true;
}
});
}
}));
.main ul {
min-height: 100px;
width: 200px;
background: gray;
overflow:hidden;
list-style:none inside;
}
.main a {
margin: 10px 0;
}
li{
padding:0.25rem;background:whitesmoke;
}
.active{
background:pink;
}
<div class="main">
<a href="#" data-dir='up'>Up</a>
<ul>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
<li>dropdown 1</li>
</ul>
<a href="#" data-dir='down'>Down</a>
</div>

#Professor Abronsius has a good solution using pure Javascript but if you want to do this in Vue you'll need to have your times in your data object and a scoped variable to keep track of which item is selected.
To expand on this you'd probably want to dynamically update your times array as the user cycled through them.
new Vue({
el: "#app",
data: {
selected:2,
times: [
"11:00am",
"10:00am",
"9:00am",
"8:00am",
"7:00am",
"6:00am"
]
},
methods: {
up: function(){
this.selected--;
},
down: function(){
this.selected++;
}
}
})
ul {
width:100px;
}
li.active {
background-color:lightgrey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>Times:</h2>
<span v-on:click="up">Up</span>
<ul>
<li v-for="(time, index) in times" :class="{ active : selected == index}">
{{time}}
</li>
</ul>
<span v-on:click="down">Down</span>
</div>

Related

toggle menu with JavaScript. Target multiple variables with 1 click function

I am trying to make a menu that collapses on click.
I also want to add some more changes on that same function.
For instance I want to change the background of another object.
In this snippet you can see it works on only the first link. The other toggleable link is not targeted.
var pill = document.querySelector(".navpill");
var sub = document.querySelector(".submenu");
pill.onclick = () => {
sub.classList.toggle("collapse");
pill.classList.toggle("active");
}
.mainmenu {
background-color: #1f1f1f;
}
.navpill {
padding: 15px;
}
.navpill.active {
background: red;
}
.navpill a {
text-decoration: none;
color: white;
}
.submenu {
display: none;
}
.submenu.collapse {
display: block;
}
<div>
<ul class="mainmenu">
<li class="navpill">Link collapse 1
<ul class="submenu">
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
</ul>
</li>
<li class="navpill">Link collapse 2
<ul class="submenu">
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
</ul>
</li>
<li class="navpill">no link</li>
<li class="navpill">no link</li>
</ul>
</div>
From a previous answer I got this piece of code which makes it work on all the links, but I have no idea how to add more var and toggles to the function.
var pills = document.querySelectorAll(".expand");
pills.forEach(function(pill) {
pill.onclick = () => {
var sub = pill.querySelector(".submenu");
sub.classList.toggle("collapse");
}
});
I tried adding this to the code but it does not work.
var navpill = pill.querySelector(".navpill");
navpill.classList.toggle("active");
If possible I would also like a way of clearing what has been done when clicked on the next submenu.
If I use the code above. It stays open when I click on the second link and then they are both open. I want the first one to close if the second is clicked.
I think this is probably closer to what you want.
(It's unclear if you wanted the submenu items to be highlighted when they're clicked - currently, clicking them just collapses the menu anyway so you wouldn't see. Also I removed the hrefs because they aren't adding anything useful.)
var pills = document.querySelectorAll(".expand");
var subs = document.querySelectorAll(".submenu");
pills.forEach(function(pill) {
pill.addEventListener("click", function() {
var sub = pill.querySelector(".submenu");
var alreadyOpen = false;
if (sub.classList.contains("collapse")) alreadyOpen = true;
pills.forEach(function(pill2) {
pill2.classList.remove("active");
});
subs.forEach(function(sub2) {
sub2.classList.remove("collapse");
});
if (!alreadyOpen) {
sub.classList.toggle("collapse");
this.classList.add("active");
}
});
});
.expand.active {
background-color: red;
}
.expand.active > .submenu
{
background-color: #1f1f1f;
}
.mainmenu {
background-color: #1f1f1f;
}
.navpill {
padding: 15px;
color: white;
}
.submenu {
display: none;
}
.submenu.collapse {
display: block;
}
<div>
<ul class="mainmenu">
<li class="navpill expand">Link collapse 1
<ul class="submenu">
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
</ul>
</li>
<li class="navpill expand">Link collapse 2
<ul class="submenu">
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
<li class="navpill">sub Link 1</li>
</ul>
</li>
<li class="navpill">no link</li>
<li class="navpill">no link</li>
</ul>
</div>

Disable mouseenter when over element on page load

I'm trying to find a way to disable mouseenter when the top-level navigation item is clicked & on pageload and re-enable again when the mouse leaves and enters the element again.
User hovers over element = show submenu
User clicks menu = hide submenu and only show submenu when user leaves menu elements and enters again.
If user is over the element onLoad then only show submenu when user leaves element and enters again.
$('.navmenu li').on('mouseenter', function(e) {
$(e.target).next().addClass('js-hover')
}).on('mouseleave', function(e) {
$(e.target).next().removeClass('js-hover')
});
$('.navmenu').on('click', function(e) {
$(e.target).next().removeClass('js-hover')
location.reload(true);
})
.navmenu .submenu {
display:none;
}
.navmenu li {
display: inline;
}
.navmenu .submenu {
position:absolute;
top:40px;
left:0
}
.navmenu li:hover .js-hover {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav class="navmenu">
<ul>
<li>
Menu
<nav class="submenu">
<ul>
<li>Submenu 1</li>
<li>Submenu 2</li>
<li>Submenu 3</li>
</ul>
</nav>
</li>
<li>
Menu 2
<nav class="submenu">
<ul>
<li>Submenu 4</li>
<li>Submenu 5</li>
<li>Submenu 6</li>
</ul>
</nav>
</li>
</ul>
</nav>
this could be done using variables and storing a state of element (if it should be hidden or not). But since you tried to do this through class attributes, I did the same. Here is simle example of one menu item, everything should be clear.
<nav class="navmenu">
<ul>
<li>
Menu
<nav class="submenu" hidden>
<ul>
<li>Submenu 1</li>
<li>Submenu 2</li>
<li>Submenu 3</li>
</ul>
</nav>
</li>
</ul>
</nav>
and javascript:
$menuLink = $("nav.navmenu li > a");
$menuLink.click(function () {
$(this).addClass("dontHide");
});
$menuLink.mouseenter(function () {
$(this).next("nav.submenu").removeAttr("hidden");
$(this).removeClass("dontHide");
});
$menuLink.mouseleave(function () {
if(!$(this).hasClass("dontHide")) {
$(this).next("nav.submenu").attr("hidden", true);
}
});
Live demo: https://jsfiddle.net/g3fua461/24/

Jquery Nested Accordion to Show Only one Level

Suppose I have a following structure:
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3
<ul>
<li>Item11</li>
<li>Item12</li>
<li>Item13</li>
</ul>
</li>
This tree structure can have many levels.
Initially, I want to show following list:
Item 1
Item 2
Item 3 +
When I click on + list becomes
Item 3 -
Item 11
Item 12
Item 13
So, parent list disappears and sublist is shown.
If I click -, then everything is returned to the previous list.
Is there some jquery plugin for doing this?
Perhaps, some options in accordion?
Thanks in advance.
Used Dkouk his version to create what you need.
EDIT 1: Hide other menu items
EDIT 2: Second level menu
$(function () {
$('ul li').each(function () {
if ( $(this).find('ul').length > 0 ){
$(this).addClass('child');
}
});
$('ul li.child span').click(function() {
$(this).parent().toggleClass('open').find('ul').first().slideToggle();
$(this).parent().siblings().slideToggle();
});
});
ul {
list-style:none;
}
ul li.child span:after {
content:"+";
}
ul li.child.open span:after {
content:"-";
}
li ul { display:none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<ul class="main">
<li>Item 1</li>
<li>Item 2</li>
<li>
<span>Item 3</span>
<ul>
<li>Item 1</li>
<li>
<span>Item 2</span>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</li>
<li>Item 3</li>
</ul>
</li>
</ul>
You can add a class to your list when it's have a sublist, and toggle the list and toggle another class for parent of list so can change the '+' to '-'.
You can as many levels, and the code will work,
I've add a span to the list have child, but so can trigger the click only at text, if you trigger click for LI list and have sublist open then will close again.
You can style the content.
Here a simple example :
$(function () {
$('ul li').each(function () {
if ( $(this).find('ul').length > 0 ){
$(this).addClass('child');
}
});
$('ul li.child span').click(function() {
$(this).toggleClass('open').parent().find('ul:first').slideToggle();
$(this).parent().siblings().slideToggle();
});
});
ul {
list-style:none;
}
ul li.child span:after {
content:"+";
}
ul li.child span.open:after {
content:"-";
}
ul li ul { display:none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>
<span>Item 3</span>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>
<span>Item 3</span>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</li>
</ul>
</li>
</ul>

CSS and jQuery universal tree menu

I want to create universal tree menu, with ul li ul. And I've made something like this using just CSS:
CSS
.category-list {
}
.category-list li ul {
display: none;
}
.category-list li:hover > ul {
display: block;
}
HTML
<ul class="category-list">
<li>
Category 1
<ul>
<li>Sub-category 1</li>
<li>Sub-cateagory 1</li>
<li>Sub-category 1</li>
</ul>
</li>
<li>
Category 2
<ul>
<li>Sub-category 2</li>
<li>Sub-category 2</li>
<li>Sub-category 2</li>
</ul>
</li>
</ul>
https://jsfiddle.net/usz9ycmj/1/
--
And I want to make similar effect, but on click, so just current clicked tab displays its parent content.
Even more important for me is the ability to add and remove class on specific action:
.category-list li.current -- while is currently clicked (active)
.category-list li -- removed while different li is clicked (active)
Just, the trigger li has two different states for active and inactive. It changes the colors and arrow from closed to opened to give it a look of a tree menu - I bet You get the point.
I want the simple jquery code, if someone has time to help. feel welcome.
Here is a working code.
Please read the comments and let me know if something not clear.
// listen to the click event
var all_items = $('.category-list>li').click(function(event) {
// stop the propagation - this will abort the function when you click on the child li
event.stopPropagation();
var elm = $(this);
// remove the class from all the items
all_items.not(elm).removeClass('current');
// add class if it's not the current item
elm.toggleClass('current', !elm.is('.current'));
});
.category-list {
}
.category-list li ul {
display: none;
}
.category-list li.current > ul {
display: block;
}
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<ul class="category-list">
<li>
Category 1
<ul>
<li>Sub-category 1</li>
<li>Sub-category 1</li>
<li>Sub-category 1</li>
</ul>
</li>
<li>
Category 2
<ul>
<li>Sub-category 2</li>
<li>Sub-category 2</li>
<li>Sub-category 2</li>
</ul>
</li>
</ul>
http://jsbin.com/tocewe/edit?html,css,js

Parsing JSON with jQuery Mustache template [duplicate]

I have a list, and each item is linked, is there a way I can alternate the background colors for each item?
<ul>
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
<li>Link 4</li>
<li>Link 5</li>
</ul>
How about some lovely CSS3?
li { background: green; }
li:nth-child(odd) { background: red; }
If you want to do this purely in CSS then you'd have a class that you'd assign to each alternate list item. E.g.
<ul>
<li class="alternate">Link 1</li>
<li>Link 2</li>
<li class="alternate">Link 3</li>
<li>Link 4</li>
<li class="alternate">Link 5</li>
</ul>
If your list is dynamically generated, this task would be much easier.
If you don't want to have to manually update this content each time, you could use the jQuery library and apply a style alternately to each <li> item in your list:
<ul id="myList">
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
<li>Link 4</li>
<li>Link 5</li>
</ul>
And your jQuery code:
$(document).ready(function(){
$('#myList li:nth-child(odd)').addClass('alternate');
});
You can achieve this by adding alternating style classes to each list item
<ul>
<li class="odd">Link 1</li>
<li>Link 2</li>
<li class="odd">Link 2</li>
<li>Link 2</li>
</ul>
And then styling it like
li { backgorund:white; }
li.odd { background:silver; }
You can further automate this process with javascript (jQuery example below)
$(document).ready(function() {
$('table tbody tr:odd').addClass('odd');
});
This is set background color on even and odd li:
li:nth-child(odd) { background: #ffffff; }
li:nth-child(even) { background: #80808030; }
Try adding a pair of class attributes, say 'even' and 'odd', to alternating list elements, e.g.
<ul>
<li class="even">Link 1</li>
<li class="odd">Link 2</li>
<li class="even">Link 3</li>
<li class="odd">Link 4</li>
<li class="even">Link 5</li>
</ul>
In a <style> section of the HTML page, or in a linked stylesheet, you would define those same classes, specifying your desired background colours:
li.even { background-color: red; }
li.odd { background-color: blue; }
You might want to use a template library as your needs evolve to provide you with greater flexibility and to cut down on the typing. Why type all those list elements by hand?
Since you using standard HTML you will need to define separate class for and manual set the rows to the classes.
You can do it by specifying alternating class names on the rows. I prefer using row0 and row1, which means you can easily add them in, if the list is being built programmatically:
for ($i = 0; $i < 10; ++$i) {
echo '<tr class="row' . ($i % 2) . '">...</tr>';
}
Another way would be to use javascript. jQuery is being used in this example:
$('table tr:odd').addClass('row1');
Edit: I don't know why I gave examples using table rows... replace tr with li and table with ul and it applies to your example
If you use the jQuery solution it will work on IE8:
jQuery
$(document).ready(function(){
$('#myList li:nth-child(odd)').addClass('alternate');
});
CSS
.alternate {
background: black;
}
If you use the CSS soloution it won't work on IE8:
li:nth-child(odd) {
background: black;
}
You can by hardcoding the sequence, like so:
li, li + li + li, li + li + li + li + li {
background-color: black;
}
li + li, li + li + li + li {
background-color: white;
}

Categories