I am working on a Layered Navigation element where I have a v-for loop on filters in an array. Filters like color, size, gender etc...
Since the amount of options in some the filters can be quite overwhelming (color for example),I would like to add a button to show more options per filter.
I currently have the following function to show more options per filter
<div v-if="showMoreFilters === false">
<div
v-for="(attribute, index) in filter.attributes"
:key="attribute.index">
<div class="layered-navigation__item"
v-if="index < filter.facetsettings.nrofshownattributes"
>
<SfFilter
:label="attribute.title"
:count="attribute.nrofresults"
:selected="attribute.isselected"
#change="function(x)>
</SfFilter>
</div>
</div>
</div>
<div v-else>
<div
v-for="attribute in filter.attributes"
:key="attribute.index"
>
<div class="layered-navigation__item">
<SfFilter
:label="attribute.title"
:count="attribute.nrofresults"
:selected="attribute.isselected"
#change="function(x)">
</SfFilter>
</div>
</div>
</div>
</div>
<sfButton #click="showMoreFilters = !showMoreFilters">
Show more filters"
</sfButton>
The desired, initial, amount of filter-options per filter is given within each filter:
filter.facetsettings.nrofshownattributes
The problem, however, is that if I press the button (showMoreFilters), all filters show all of their options. Not just the array of option of the filter I clicked on. How could I resolve this?
The problem is that there are many filters but only one showMoreFilters flag. Consider adding a showMore property to every filter's facetsettings object...
<div v-if="!filter.facetsettings.showMore">
...
<sfButton #click="filter.facetsettings.showMore != filter.facetsettings.showMore">
Show more of just this filter"
</sfButton>
Related
I have a VueJS view that creates collapsed contents using Bootstrap Vue Collapse Component.
The data is dynamic and can contains hundreds of items, which is why you see in the code below it was created via a v-for loop in Vue.
<div class="inventory-detail" v-for="(partNumberGroup,index) in inventory" :key="index" >
<b-button block v-b-toggle="partNumberGroup.partNumber" v-bind:id="partNumberGroup.partNumber" variant="primary"
#click="(evt) =>{isActive = !isActive && evt.target.id == partNumberGroup.partNumber}">
<i v-bind:id="partNumberGroup.partNumber" class="float-right fa" :class="{ 'fa-plus': !isActive, 'fa-minus': isActive }"></i>
{{ partNumberGroup.partNumber }}
</b-button>
<div class="inventory-detail__card" v-for="item in partNumberGroup.items">
<b-collapse v-bind:id="partNumberGroup.partNumber" >
<b-card>
<!--Accordion/Collapse content -->
</b-card>
</b-collapse>
</div>
</div>
This works fairly well in that I can individually expand and collapse each content separately. However, the one issue I'm facing is each time I click the icon fa-minus (-) orfa-plus (+), all of them changed as per the images below.
Any tips on how I should implementing this? in my code I tried the dynamic CSS class switching but I still lack the ability to switch on specific element.
I feel like the solution to this is to somehow conditionally apply dynamic CSS class or somehow able to use the attribute 'aria-expanded'.
You can try something like this. Whenever somebody clicks on the icon, set its index as activeIndex (using the setActiveIndex method). Then you can set the class accordingly by comparing the activeIndex with current index
<i
#click="setActiveIndex(index)"
v-bind:id="partNumberGroup.partNumber"
class="float-right fa"
:class="{ 'fa-plus': !isActive(index), 'fa-minus': isActive(index) }">.
</i>
then in the script part:
...
data() {
return {
activeIndex: -1
}
},
methods: {
/* set active index on click */
setActiveIndex(index) {
this.activeIndex = index;
},
/* check if index is active or not */
isActive(index) {
return index === this.activeIndex;
}
}
In my example I want to draw a border around an element after clicking on it. In this example it works perfectly:
<div v-for="(parent, index) in $store.getters.getInfo" :key="index">
<div #click="setClicked" :id="child.id" v-for="child in parent"
:style="[child.clicked ? {'border-color': 'black'} : {'border-color': 'white'}]">
</div>
</div>
But when i try with a bit more complicated structure and template tags the style binding fails to be triggered:
<div v-for="i in 12">
<template v-for="(user, index) in $store.getters.getSharedUsers">
<div :id="child.id" v-for="child in $store.getters.getSharedInfo[user[0]][i-1]"
:userID="child.userID" #click="setClicked"
:style="[child.clicked ? {'border-color': 'black'} : {'border-color': 'white'}]">
</div>
</template>
</div>
In my mutation I set the attribute with:
Vue.set(state.element_map[payload.uID][payload.dID], 'clicked', true);
When I debug I see the change in both code examples in my data structure after calling the setClicked function, but only in the first one the style binding is triggered and the border is drawn. The only difference I see is the use of the template tag and the more complicated data structure. But it should also work in the second example as the clicked attribute is set correctly. So what am I missing? Thanks!
I try to use custom scrollbar using vuebar on dynamic Vue elements. Since v-if destroys and recreates elements, vuebar is not activated after that. On example provided you can see scrollbar works till you change tabs. I know you can use v-show and it starts working, but that solution is impossible to implement in nested components with complicated relations.
<div class="vuebar-element" v-bar v-if="tab==0">
<div>
tab 0
</div>
</div>
<div class="vuebar-element" v-bar v-if="tab==1">
<div>
tab 1
</div>
</div>
http://jsfiddle.net/ebwdnqfs/2/
After reading comment from #ssc-hrep3 I discovered that putting whole thing into
< transition > tag magically solves the problem.
<transition>
<div class="vuebar-element" v-bar v-if="tab==0">
<div>
tab 0
</div>
</div>
<div class="vuebar-element" v-bar v-if="tab==1">
<div>
tab 1
</div>
</div>
</transition>
Condider the following snippet:
<template v-if="tryIsMobile" >
<div class='device device-mobile-portrait' :class="deviceClass">
<div class="device-scroller-container">
<div class='device-scroller'>
<img id='tryit-img-mobile' :src="srcUrlMobile" v-on:load="onImgLoad" v-on:error="onImgError"/>
</div>
</div>
</div>
</template>
<template v-else>
<div class='device device-tablet-landscape' :class="deviceClass" >
<div class="device-scroller-container">
<div class='device-scroller'>
<img id='tryit-img-tablet' :src="srcUrlTablet" v-on:load="onImgLoad" v-on:error="onImgError"/>
</div>
</div>
</div>
</template>
This code conditionally renders one of the two images. Some user action results in the actual shown image to be toggled.
What I'm seeing is the following: When toggling from say, tryit-img-mobile to tryit-img-tablet, the image loaded as part of tryit-img-mobile will get displayed with different dimensions instantly. However, during the time the image loads it's new source :src="srcUrlTablet", the image with src :src="srcUrlMobile" still displays.
This is probably due to Vue using the same img-tag for both the templates. How can I prevent Vue from doing this, and instead use seperate img-tags?
In cases such as this, Vue uses a special key attribute that tells it not to reuse the same element. Give each element this attribute with a unique value, and Vue will no longer reuse the same element:
<div v-if="tryIsMobile"
class="device device-mobile-portrait"
:class="deviceClass"
key="mobile"
>
...
</div>
<div v-else
class="device device-tablet-landscape"
:class="deviceClass"
key="tablet"
>
...
</div>
I'm using nested accordions with Materializecss. I want to be able to have nested accordions, but to let each level to only have 1 item of the accordion opened (as of data-collapsible='accordion').
I can't get it to work: if I set data-collapsible='accordion' I cannot open nested accordions, and if I set data-collapsible='collapsible', I can open any number of items per accordion.
Any workaround?
Thanks!
If you are managing the inner elements of the collapsibles dinamically, then you need to "initialize" them using a jquery method included in "materialize.js". This is written in the "materializecss" documentation here.
I'll provide a practical example.
Given the next HTML:
...
<ul class="collapsible" data-collapsible="accordion">
<li>
<div class="collapsible-header">
My nested collapsible
</div>
<div class="collapsible-body">
<ul class="nested collapsible" data-collapsible="accordion">
<!-- No data initially -->
</ul>
</div>
</li>
<li>
<div class="collapsible-header">Second</div>
<div class="collapsible-body">
<p>Normal data...</p>
</div>
</li>
</ul>
...
I suppose the problem comes because you are appending data into the ".nested" div, and it's not working as an accordion as expected.
You should then do something like:
// ... Your handler code ...
// ... Data appended into $('.nested')
$('.nested').collapsible({accordion: true});
// ...
The {accordion: true} option is not mandatory, as it will be treated as an accordion by default.
It should work in this case. Good luck.