Disable one link in dropdown in vuejs - vuejs2

I want to disable one link from the b-dropdown item in vuejs based on their status.
I want to show both the values - name, but i want to disable the name which has status not complete
<span v-for="users in value.user">
<b-dropdown-item
:key="user.id"
active="active"
>
<span>
{{ user.name }}
</span>
</b-dropdown-item>
</span>
While i have the arrays of values from value.user as this
[
{
"id":"1",
"name":"XXX",
"status":"complete",
},
{
"id":"2",
"name":"XXX",
"status":"not complete",
}
]
Any suggestions?

From the documentation
Disable the dropdown item by setting the disabled prop.
<b-dropdown>
<b-dropdown-item
v-for="users in value.user"
:key="user.id"
active="active"
:disabled="user.status === 'not complete'"
>
<span>
{{ user.name }}
</span>
</b-dropdown-item>
</b-dropdown>

Related

Algolia vue auto select facets

I am developing an algolia search solution for an ecommerce app with around ~30000 products.
I tried to use the <ais-configure/> component to filter my results before showing them on the page, as I am working with different pages for each category of products and some facet filters also need to be applied if a user was to click on a promotion which would lead to this search result in the code below.
The problem is:
Whenever I use the filters in <ais-configure/> the same filters are not picked up by my <ais-refinement-list/> component which should have the refined facets highlighted.
The below code is not working but descriptive enough for the problem.
Template
<ais-instant-search :search-client.camel="searchClient" index-name="products">
<ais-configure
:filters.camel="searchParameters.filters"
:facet-filters.camel="searchParameters.facetFilters"
/>
<ais-infinite-hits>
<div
slot="loadMore"
slot-scope="{ isLastPage, refineNext }"
class="w-full my-12 px-6 text-sm-black-primary"
>
<button
class="
w-full
h-20
border-4
rounded-md
border-sm-black-primary
font-semibold
text-xl
mb-24
"
:disabled="isLastPage"
#click="refineNext"
>
See more
</button>
</div>
</ais-infinite-hits>
<products-filter-section>
<div v-for="(filterType, id) in filterTypes" :key="id">
<ais-refinement-list :attribute="filterType" searchable show-more>
<template
slot-scope="{
items,
isShowingMore,
isFromSearch,
canToggleShowMore,
refine,
createURL,
toggleShowMore,
searchForItems,
}"
>
<div>
<UtilsFancyTitle
:text="filterType"
text-size="text-lg"
class="ml-4 my-4"
/>
<input
class="bg-white"
#input="searchForItems($event.currentTarget.value)"
/>
<ul class="flex flex-wrap">
<li v-if="isFromSearch && !items.length">No results ...</li>
<li v-for="item in items" :key="item.value" class="my-4 mr-4">
<a
:href="createURL(item)"
:class="
item.isRefined
? 'font-semibold bg-sm-yellow-primary border-sm-yellow-primary '
: 'font-medium'
"
class="
border-4 border-sm-black-primary
py-1.5
px-2
rounded-md
text-sm
"
#click.prevent="refine(item.value)"
>
<ais-highlight attribute="item" :hit="item" />
( {{ item.count.toLocaleString() }} )
</a>
</li>
</ul>
<div class="flex justify-center items-center">
<div class="w-1/4 h-1 bg-sm-black-primary rounded-md"></div>
<button
class="w-2/4 font-semibold my-6"
:disabled="!canToggleShowMore"
#click="toggleShowMore"
>
{{ !isShowingMore ? 'Show more' : 'Hide' }}
</button>
<div class="w-1/4 h-1 bg-sm-black-primary rounded-md"></div>
</div>
</div>
</template>
</ais-refinement-list>
</div>
</products-filter-section>
</ais-instant-search>
Script
import {
AisInstantSearch,
AisRefinementList,
AisInfiniteHits,
AisConfigure,
} from 'vue-instantsearch'
import algoliasearch from 'algoliasearch/lite'
import { mapGetters } from 'vuex'
export default {
components: {
AisInstantSearch,
AisRefinementList,
AisInfiniteHits,
AisConfigure,
},
data() {
return {
searchClient: algoliasearch(
'[API-ENDPOINT]',
'[API-KEY]'
),
filterTypes: [
'type',
'color',
],
searchParameters: {
filters: `category:${this.$route.path.split('/').pop()}`,
facetFilters: `type:someProductType`,
},
}
},
head() {
return {
link: [
{
rel: 'stylesheet',
href: 'https://cdn.jsdelivr.net/npm/instantsearch.css#7.4.5/themes/reset-min.css',
},
],
}
},
}
Is there any working solution for this?
The facets should be auto selected and in their refined state (for example: having their isRefined property set to rue) whenever the algolia query loads and the page renders.
This question has been posted a while ago, so you might already have found an answer, but I'll post mine anyway since I landed here after having the same issue.
In my case, at least, there were 2 problems:
I hadn't configured the "Attributes for faceting". This is explained in the docs and can be done easily via the admin or via API.
I was specifying the facets incorrectly in code. In your example above I think you should have:
searchParameters: {
facetFilters: [[`type:someProductType`]],
},
Note that now facetFilters is an array within an array.
What helps me when I'm unsure I open the admin UI of Algolia, select a search and apply whichever filter I want and then check the raw output. An example from my admin ui:
This gives me an idea of the correct shapes InstantSearch needs.

vue.js how do I make a v-slot template dynamic?

Hello and thank you for reading my question! I am working with Vue.js, Vuetify and v-data-table and I am working on making my v-slot work with two different strings as the name of the header.
<template>
<v-container fluid>
<v-data-table
:options="data"
:headers="headers"
:items="data
:server-items-length="40"
:loading="loading"
:multi-sort="true"
#update:options="updateThePage"
>
<template v-slot:[`header.overalls`]="{ header }" class="flight-date-header">
<overallDatePicker
:options="data"
/>
{{ header.name }}
</template>
<template v-slot:[`item.name`]="{ item }">
<p class="company-name">
{{ item.companyName }}
</p>
</template>
<template v-slot:[`item.price`]="{ item }">
<p> {{ item.price }} </p>
</template>
<template v-slot:[`item.flightDate`]="{ item }">
<p class="style">
{{ item.startDate }}
</p>
</template>
</v-data-table>
</v-container>
</template>
and I store my headers like below
headers: [
{ text: 'Campaign Name', value: 'overalls' },
],
Ideally I would like the name of this slot
<template v-slot:[`header.overalls`]="{ header }" class="flight-date-header">
<overallDatePicker
:options="data"
/>
</template>
To work with two different data options. right now the name of the header is overalls but I want the name of the header so ['header.overalls'] to be like ['header.('overalls' || 'shoes')] ,
The reason I am doing this is right now when I click on the header the options.sortBy property of the table gets set to 'overalls', but I want the icon on the column to show up if the options.sortBy property of the table is "overalls" and also show up if it is "shoes"
Please help and thank you so much!
To reuse the slot content for multiple headers/columns, use Vue's dynamic slots names feature + v-for
data() {
return {
specialHeaders: ['overalls', 'shoes'],
}
}
<template v-for="column in specialHeaders" v-slot:[`header.${column}`]="{ header }">
Special:{{header.text}}
</template>

Is possible to pass data from slot-component to parent in vueJS?

I'm new in VueJS and I'm try to do something like this
I have 3 components, siderbar ; siderbar-item and sidebar-drop
siderbar.vue is a wrapper when you can put siderbar-item and sidebar-drop, and inside sidebar-drop you can put sidebar-item too
for example:
<sidebar>
<sidebar-item url="myurl" title="Dashboard" icon="fas fa-tachometer-alt" badge=""></sidebar-item>
<sidebar-drop title="News" icon="fas fa-tachometer-alt">
<sidebar-item url="myurl_news" title="News list" icon="fas fa-tachometer-alt" badge=""></sidebar-item>
<sidebar-item url="myurl_news_add" title="Add News" icon="fas fa-tachometer-alt" badge=""></sidebar-item>
</sidebar-drop>
<sidebar-drop title="Categories" icon="fas fa-tachometer-alt">
<sidebar-item url="myurl_categories" title="Categories List" icon="fas fa-tachometer-alt" badge=""></sidebar-item>
</sidebar-drop>
</sidebar>
sidebar.vue is very simple:
<aside>
<slot></slot>
</aside>
sidebar-item.vue
<template>
<ul class="menu-list" >
<li>
<a :href="url" :class="{'is-active': is_active }">
<span class="icon"><i v-if="icon" :class="icon"></i></span>
{{ title }}
<span v-if="badge" class="button badge is-info is-small is-pulled-right "> {{ badge }}</span>
</a>
</li>
</ul>
</template>
<script>
export default {
props: ['title', 'url', 'icon', 'badge'],
data() {
return {
is_active: this.$current_url === this.url
}
}
}
</script>
and sidebar-drop.vue
<template>
<ul class="menu-list" v-if="title">
<li #click="openMenu" :class="{'is-open': is_open}">
<a class="">
<span v-if="icon" class="icon"><i class="fas fa-tachometer-alt"></i></span>
{{ title }}
<span class="badge is-pulled-right" style=""> <i class="fas fa-chevron-left"></i> </span>
</a>
<slot></slot>
</li>
</ul>
</template>
<script>
export default {
props: ['title', 'icon'],
data() {
return {
is_open: false,
}
},
methods: {
openMenu(){
this.is_open = !this.is_open;
},
}
}
</script>
It works great, but I have a little problem. If you notice, sidebar-item has a data called "is_active", it only put a CSS class that this item is active. Great.
Now I'm trying to get into sidebar-drop if a least one of his children has data "is-active" in true, change the is_open sidebar-drop parent data to true.
Example: I click "News" item.
Ul li News is active... works!
Ul li parent drop is open... don't work
Is possible make that?
Thanks everyone!
Update:
I put it in Fiddler to more clear:
https://jsfiddle.net/h35qy2zs/
I do in sidebar-item a random is_active.
If any child of sidebar-drop (sidebar-item's) data is_active:true, sidebar-drop data is_open is true too.
So, it show in color yellow and open
Result:
But now, both are closed at refresh page.

Select element inside dropdown menu issue

I am currently experimenting in Element UI a beautiful VueJS frame for ui.
I am having issue when putting an select element inside a dropdown menu because when I select an item inside the select element it will close the dropdown also.
How should I make the dropdown stay whenever I select an item in select element?
Here is the sample demo. fiddle
https://jsfiddle.net/vy70ogbz/
I got the same problem and I solved it by small hack: when a dropdown is open I set disabled="true" property to the trigger button.
<el-button
:disabled="dropdownIsOpen"
slot="button"
>Open</el-button>
It works because in the source code we have condition for this case
https://github.com/ElemeFE/element/blob/dev/packages/dropdown/src/dropdown.vue#L121
Example: click
Why dont you use a menu to achieve this. I find it is more flexible, you can use the menu-trigger="click" attribute to toggle the menu only when clicked. like this
<el-menu
:default-active="activeIndex"
mode="horizontal"
menu-trigger="click"
#select="handleSelect">
<el-submenu
class="sub-menu-more">
<template slot="title">
<b>Click to dropdown</b>
</template>
<el-menu-item
index="1">
<span >Team</span>
</el-menu-item>
<el-menu-item
index="2">
<span >Product</span>
</el-menu-item>
<el-menu-item
index="3">
<span >item</span>
</el-menu-item>
<el-menu-item
index="4">
<el-select v-model="value" placeholder="Select">
<el-option
:label="'test1'"
:value="'test1'">
</el-option>
<el-option
:label="'test1'"
:value="'test1'">
</el-option>
<el-option
:label="'test1'"
:value="'test1'">
</el-option>
</el-select>
</el-menu-item>
</el-submenu>
</el-menu>
see fiddle
You can prevent the dropdown from hiding.
Use the following code in your template
<el-dropdown ref="dropdown" trigger="click">
<span class="el-dropdown-link">
Dropdown List<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>Action 1</el-dropdown-item>
<el-dropdown-item>Action 2</el-dropdown-item>
<el-dropdown-item>Action 3</el-dropdown-item>
<el-dropdown-item>
<el-select v-model="selectData" #change="handleChange">
<el-option value="1">Option 1</el-option>
<el-option value="2">Option 2</el-option>
<el-option value="3">Option 3</el-option>
</el-select>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
And this in your script
new Vue({
data: {
selectData: null
},
methods: {
handleChange() {
this.$nextTick(() => {
this.$refs.dropdown.show();
});
}
}
}).$mount('#app')

vue.js conditional rendering of an attribute [duplicate]

This question already has answers here:
VueJS conditionally add an attribute for an element
(11 answers)
Closed 4 years ago.
I'd like to learn what is the best way to conditionally render an HTML attribute in Vue.js. For example, add data-toggle="tooltip" if there is a tooltip message for current instance.
The code I have now:
<span
:data-toggle="!!col.col_spec.tooltip ? 'tooltip' : ''"
:title="col.col_spec.tooltip"
>
{{ col.col_spec.title }}
</span>
Though, I don't like the 2nd line much… Even if I use computed property here, I'd prefer not to have data-toggle attribute at all, when there is no tooltip to display.
Very so elegant solution:
<span
:data-toggle="!!col.col_spec.tooltip ? 'tooltip' : false"
:title="col.col_spec.tooltip"
>
{{ col.col_spec.title }}
</span>
Yes, yes, yes, it's just necessary that there is not an empty string, but a Boolean false
Something like:
<span ref="column">
{{ col.col_spec.title }}
</span>
And in Vue:
mounted(){
if (this.col.col_spec.tooltip){
this.$refs.column.setAttribute("data-toggle", this.col.col_spec.tooltip);
}
}
A bit late, but here is my take on it:
HTML:
<span
:data-toggle="tooltip"
:data-original-title="tooltipTitle"
>
{{ tooltipTitle }}
</span>
Vue:
methods: {
tooltipTitle: function() {
var title = this.col.col_spec.title;
if (!!title) return title;
return false;
}
}
This will remove the "data-original-title" attribute if there is none to display, consequently removing the tooltip altogether. You must use "data-original-title" instead of just "title" because Bootstrap will automatically add it once you initialise the "title" attribute, and changing "title" to false will not remove the "data-original-title".
Here's another working but not so elegant solution:
<span v-if="!!col.col_spec.tooltip" data-toggle="tooltip" >
{{ col.col_spec.title }}
</span>
<span v-else >
{{ col.col_spec.title }}
</span>