How to vueJs filtering in on-click - vue.js

My code :
<ul id="filter"><li>All</li>
<li>In source</li>
<li>Out source</li></ul>
<div v-for="asessesment in listAssesmentList">
<li>In source - Jhon</li>
<li>Out source - Ryan</li>
Can I filter In source or Out source using in vueJs?
Thanks in advance

Are you mean this ??
var vm = new Vue({
el: '#app',
data: {
sources: [{
name: 'In Source',
lists: [
'John', 'Ryan', 'Matt'
]
}, {
name: 'Out Source',
lists: [
'Mimi', 'Mike', 'Edrick'
]
}],
filterText: ''
},
methods: {
filter: function(name) {
this.filterText = name;
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.17/vue.min.js"></script>
<div id="app">
<ul>
<li>All
</li>
<li>In Source
</li>
<li>Out Source
</li>
</ul>
<ul v-for="source in sources | filterBy filterText in 'name' ">
<li>
{{ source.name }}
<ol>
<li v-for="user in source.lists | orderBy 'user'">{{ user }}</li>
</ol>
</li>
</ul>
</div>
https://jsfiddle.net/quetzalarc/LdcdLqe3/2/

Related

VueJS renders variable twice in loop

When I press some key in editable <li> it shows this content twice. Out of this v-for loop, it shows only once. So in this array is for example ['a'] but in <li> it shows 'aa'
new Vue({
el: '#app',
data: {
component: {
items: ['']
}
},
methods: {
onKeydown(e, index) {
if(e.key === 'Enter') {
e.preventDefault()
this.component.items.push('')
}
},
onInput(e, index, item) {
this.component.items.splice(index, 1, e.target.innerHTML)
}
}
});
<div id="app">
<ul>
<li contenteditable="true"
v-for="(item, index) in component.items"
:key="index"
#keydown="onKeydown($event, index)"
#input="onInput($event, index, item)"
>{{ item }}</li>
</ul>
{{ component.items }}
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

error in loading the vue script for a drop-down list

This is my first project in vue and it is being very difficult for me to find functional examples in vue.
I'm trying to make a header component that shows a list of links, some of which I need to be a drop-down list of links. Here is my component
<template>
<nav class='header'>
<ul class='menu'>
<li class='menu-item'>
<a class='menu-link' href="https://www.esthima.fr/societe">QUI SOMMES-NOUS ?</a>
</li>
<li class="menu-item menu-item-dropdown" v-on:click="toggle('ranking')" v-bind:class="{'open' : dropDowns.ranking.open}">
<a class='menu-link menu-link-toggle'>QUAND L’ANIMAL S’EN VA</a>
<ul class='dropdown-menu'>
<li class='dropdown-menu-item'>
<a class='dropdown-menu-link'>TEST 1</a>
</li>
<li class='dropdown-menu-item'>
<a class='dropdown-menu-link'>TEST 2</a>
</li>
</ul>
</li>
<li class='menu-item'>
<a class='menu-link' href="https://boutique.esthima.fr">URNES ANIMAUX</a>
</li>
</ul>
<img src="../assets/logoesthima.png">
<a>NOS SERVICES</a>
URNES ANIMAUX
<a>TARIFS ET DEVIS</a>
<a>NOUS CONTACTER</a>
</nav>
</template>
<script>
export default{
let header = new Vue({
al: '.header',
ready: function()
{
var self = this
window.addEventListener('click', function(e){
if (! e.target.parentNode.classList.contains('menu__link--toggle'))
{
self.close()
}
}, false)
},
data: {
dropDowns: {
ranking: { open: false}
}
},
methods: {
toggle: function(dropdownName)
{
//alert(dropdownName)
this.dropDowns[dropdownName].open = !this.dropDowns[dropdownName].open;
},
close: function()
{
for (dd in this.dropDowns)
{
this.dropDowns[dd].open = false;
}
}
}
})
}
</script>
I'm following the few examples I've found and the documentation and they all return the same console loading error with the declaration inside the "new Vue" script whether I declare it directly or keep it as a constant.
Someone who can make me see my mistake.
Thank you very much in advance!
You should change the code to be a properly structured Single-File Component:
<template>
<nav class='header'>
<ul class='menu'>
<li class='menu-item'>
<a class='menu-link' href="https://www.esthima.fr/societe">
QUI SOMMES-NOUS ?
</a>
</li>
<li class="menu-item menu-item-dropdown" #click="toggle('ranking')" :class="{open: dropDowns.ranking.open}">
<a class='menu-link menu-link-toggle'>
QUAND L’ANIMAL S’EN VA
</a>
<ul class='dropdown-menu'>
<li class='dropdown-menu-item'>
<a class='dropdown-menu-link'>TEST 1</a>
</li>
<li class='dropdown-menu-item'>
<a class='dropdown-menu-link'>TEST 2</a>
</li>
</ul>
</li>
<li class='menu-item'>
<a class='menu-link' href="https://boutique.esthima.fr">URNES ANIMAUX</a>
</li>
</ul>
<img src="../assets/logoesthima.png">
<a>NOS SERVICES</a>
URNES ANIMAUX
<a>TARIFS ET DEVIS</a>
<a>NOUS CONTACTER</a>
</nav>
</template>
<script>
export default
{
mounted()
{
window.addEventListener('click', (evt) =>
{
if (! e.target.parentNode.classList.contains('menu__link--toggle'))
{
this.close()
}
}, false)
},
data()
{
return {
dropDowns:
{
ranking:
{
open: false
}
}
};
},
methods:
{
toggle(dropdownName)
{
//alert(dropdownName)
this.dropDowns[dropdownName].open = !this.dropDowns[dropdownName].open;
},
close()
{
for (dd in this.dropDowns)
{
this.dropDowns[dd].open = false;
}
}
}
};
</script>

VueJS 2 Directives insert event

I'm new VueJS Student, and i was trying to do a directive, and i stopped because i dont know why i can't get the element. What's am i doing wrong? I just want to get the el element.
Here is a JSFiddle or the code below.
HTML
<div class="container" id="vue-app">
<ul>
<li v-test v-for="item in itens">
{{item.name}}
</li>
</ul>
<span id="directiveLog"></span>
</div>
JS
Vue.directive('test', {
inserted: function (el) {
document.querySelector('#directiveLog').innerHTML = el;
}
})
new Vue({
el: '#vue-app',
data: {
itens:[
{name: "hello"},
{name: "fun"},
{name: "world"}
]
}
});
Parameter 'el' in function inserted(el) {...} - it is your element where v-test is inserted.
Vue.directive('test', {
inserted: function (el) {
document.querySelector('#directiveLog').innerHTML = el.innerHTML;
}
})
new Vue({
el: '#vue-app',
data: {
itens:[
{name: "hello"},
{name: "fun"},
{name: "world"}
]
}
});
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div v-test class="container" id="vue-app">
<ul>
<li v-for="item in itens">
{{item.name}}
</li>
</ul>
<span id="directiveLog"></span>
</div>

VueJS Custom dropdown buttons not working independently of each other

So I have a button dropdown which is working as expected but I have a bug where I can't reuse the same component as they both dont work independently of each other but instead when one is clicked the other changes too.
Please find a JSFiddle below and my code.
Thanks
<div id="app">
<div v-on:click="menuVisible = !menuVisible" class="dropdownBtn">
<div v-bind:class="{ active : menuVisible }"class="dropdownBtn__title">
<span v-if="!btnTitle">exploring</span>
<span v-else>{{ btnTitle }}</span>
</div>
<div v-show="menuVisible" class="dropdownBtn__content">
<ul v-for="reason in reasons">
<li v-on:click="updateTitle(reason)">{{ reason.title }}</li>
</ul>
</div>
</div>
<div v-on:click="menuVisible = !menuVisible" class="dropdownBtn">
<div v-bind:class="{ active : menuVisible }"class="dropdownBtn__title">
<span v-if="!btnTitle">exploring</span>
<span v-else>{{ btnTitle }}</span>
</div>
<div v-show="menuVisible" class="dropdownBtn__content">
<ul v-for="reason in reasons">
<li v-on:click="updateTitle(reason)">{{ reason.title }}</li>
</ul>
</div>
</div>
</div>
new Vue({
el: '#app',
data() {
return {
menuVisible: false,
btnTitle: false,
reasons: [{
title: 'family fun',
value: 1
},
{
title: 'relaxing',
value: 2
},
{
title: 'dining',
value: 3
},
{
title: 'meetings & events',
value: 4
},
{
title: 'what\'s on',
value: 5
},
{
title: 'gold',
value: 6
}]
}
},
methods: {
updateTitle($event) {
this.btnTitle = $event.title
}
}
})
So, for one, you haven't actually made a reusable component for the dropdown. You need to define that using Vue.component. Then you can use the tag for the custom component in the root template.
Secondly, if you are binding to the same data, then that is what will be reflected in both templates. You'll still need to pass separate data to the two separate dropdown components.
Vue.component('dropdown', {
template: `
<div v-on:click="menuVisible = !menuVisible" class="dropdownBtn">
<div v-bind:class="{ active : menuVisible }"class="dropdownBtn__title">
<span v-if="!btnTitle">exploring</span>
<span v-else>{{ btnTitle }}</span>
</div>
<div v-show="menuVisible" class="dropdownBtn__content">
<ul v-for="reason in reasons">
<li v-on:click="updateTitle(reason)">{{ reason.title }}</li>
</ul>
</div>
</div>
`,
props: ['menuVisible', 'btnTitle', 'reasons'],
methods: {
updateTitle($event) {
this.btnTitle = $event.title
}
}
})
new Vue({
el: '#app',
data() {
return {
fooReasons: [
{ title: 'family fun', value: 1 },
{ title: 'relaxing', value: 2 },
{ title: 'dining', value: 3 },
{ title: 'meetings & events', value: 4 },
{ title: 'what\'s on', value: 5 },
{ title: 'gold', value: 6 }
],
barReasons: [
{ title: 'family bar', value: 1 },
{ title: 'bar relaxing', value: 2 },
{ title: 'bar dining', value: 3 },
{ title: 'meetings & bars', value: 4 },
{ title: 'bar\'s on', value: 5 },
{ title: 'gold bar', value: 6 }
]
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script>
<div id="app">
<dropdown :menu-visible="false" :btn-title="false" :reasons="fooReasons"></dropdown>
<dropdown :menu-visible="false" :btn-title="false" :reasons="barReasons"></dropdown>
</div>

run loop backward in template in vuejs

<template>
<li v-for="r in recent">
{{r}}
</li>
</template>
recent is an array .
I don't want to list contents of recent from 0 to n-1 .
Instead i want to list it from n-1 to 0.
I tried ->
<template>
<li v-for="r=recent.length-1 ; r>=0 ; r--">
{{r}}
</li>
</template>
But, it didn't work.
Solution 1: Reverse array directly in template
You can actually reverse the array directly in your template before iterating through it, using recent.slice().reverse(). Using .slice() is necessary because this.recent is actually not an array per se. However, I do not prefer this method because it means placing logic in your template.
<template>
<li v-for="r in recent.slice().reverse()">
{{r}}
</li>
</template>
new Vue({
el: '#list',
data: {
recent: [
'Lorem',
'ipsum',
'dolor',
'sit',
'amet'
]
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<ul id="list">
<li v-for="r in recent.slice().reverse()">
{{ r }}
</li>
</ul>
Solution 2: Use a computed property
As what #vbranden has said, you can simply reverse an array in a method and use it in v-for. This is my preferred method.
new Vue({
el: '#list',
data: {
recent: [
'Lorem',
'ipsum',
'dolor',
'sit',
'amet'
]
},
computed: {
recentReversed: function() {
return this.recent.reverse();
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<ul id="list">
<li v-for="r in recentReversed">
{{ r }}
</li>
</ul>
You should use Array.prototype.reverse()
Source : link
In your computed
export default Vue.extend({
name: 'mainActivity',
data (){
return{
stuff: ['a', 'b', 'c', 'd']
}
},
computed:{
reverseArray(){return this.stuff.reverse()}
},
created(){}
})
HTML
<template>
<li v-for="r in reverseArray">
{{r}}
</li>
</template>
There is no for-loop form of v-for. There is a range form, which you can use to get the effect you want (with a little simple math).
You could do the same thing with a computed, as vbranden noted in his comment.
new Vue({
el: '#app',
data: {
stuff: ['a', 'b', 'c', 'd']
},
computed: {
stuffIndexCountdown() {
return this.stuff.map((_, i) => i).reverse();
}
}
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<div id="app">
<div v-for="i in stuff.length">
{{stuff.length - i}}
</div>
<hr>
<div v-for="i in stuffIndexCountdown">
{{i}}
</div>
</div>