vuetify: why the table is sorted whenever the user clicks into the input field - vue.js

I have a vuetify datatable, the original solution is dynamic allocation of search text field using v-for for each of the column and then multi filter is implemented. following is my solution:
<template v-for="(header, i) in columns" v-slot:[`header.${header.value}`]="{ }">
{{ header.text }}
<v-text-field :key="i"
v-model="multiSearch[header.value]"
class="pa"
type="text"
:placeholder="header.value"
prepend-inner-icon="mdi-magnify"
></v-text-field>
</template>
The problem is whenever an user clicks on the text field of a particular column, the sorting function also runs at the same time. I have a miniature solution on the following pen which has the same behaviour. I tried to put one div after template tag but still the same. Kindly have a look at it. Any help would be appreciated.
Code Pen

Wrap the text field with a DIV and attach an empty handler to prevent the bubbling of CLICK events:
<template v-for="(header, i) in columns" v-slot:[`header.${header.value}`]="{ }">
{{ header.text }}
<div #click.stop>
<v-text-field :key="i"
v-model="multiSearch[header.value]"
class="pa"
type="text"
:placeholder="header.value"
prepend-inner-icon="mdi-magnify"
></v-text-field>
</div>
</template>

Related

Vuetify v-data-table render multiple v-edit-dialog

The docs has example for adding inline edit dialog to a column. I'm trying to add it to each column.
Copy & Paste of course.
Rendering row - But it will remove default function (i.e: sortable) of v-data-table row --> I don't choose
Using v-for with v-slot - But has error demo
<template v-for="header in headers" v-slot:item[header.value]="propsAPI">
<v-edit-dialog
:return-value.sync="propsAPI.item[header.value]"
#save="save"
#cancel="cancel"
#open="open"
#close="close"
:key="header.value"
>
{{ propsAPI.item[header.value] }}
<template v-slot:input>
<v-text-field
v-model="propsAPI.item[header.value]"
:rules="[max25chars]"
label="Edit"
single-line
counter
/>
</template>
</v-edit-dialog>
</template>
Any suggestion
You can replace
<template v-for="header in headers" v-slot:item[header.value]="propsAPI">
with
<template v-for="header in headers" v-slot:[`item.${header.value}`]="propsAPI">
This should redefine slot for each column.

Uniquely identify button click for individual v-cards in vuejs

I am using vuejs with vuetify 1.5 i am little bit stuck in my code the issue here is i have an array of objects and based on that multiple v-cards getting generated for all the values present in the array of objects.
In multiple cards i have a button expand so by default i want to show only 4 values and onclicking expand the rest of values will be shown in the cards and that expand button but the issue is all cards will have the same expand button so on clicking expand all cards are expanding and its values are shown but I want uniquely that means when i click expand only one cards value gets expanded rest of the cards will not expand.
here is my code :-
expandToggleHandler() {
this.isExpand = !this.isExpand
},
<v-card
style="display: inline-block;"
class="cardView"
:key="rowIndex"
#sort="onSort"
#click.native = "onRowClicked(row)"
>
<v-layout wrap>
<v-flex xs12 style="text-align: center; font-weight: bold;" :style="fixedColumn && clickableColumn || clickableColumn ? 'color: #ad00ff !important;' : 'color: #3399bb'">
{{row[Object.keys(row)[0]]}}
<br />
</v-flex>
</v-layout>
<v-layout wrap>
<template v-if="!isExpand">
<template v-for= "(key, idx) of cardViewColumn">
<template v-for="(col, i) of key">
<template v-if="idx <= 1">
<v-flex xs6 sm6 md6 style="text-align: center;">
<span style="font-weight: bold;">{{ col }}</span> <br /> {{row[col]}}
</v-flex>
</template>
</template>
</template>
</template>
<template v-if="isExpand">
<template v-for= "(key, idx) of cardViewColumn">
<template v-for="(col, i) of key">
<v-flex xs6 sm6 md6 style="text-align: center;">
<span style="font-weight: bold;">{{ col }}</span> <br /> {{row[col]}}
</v-flex>
</template>
</template>
</template>
<md-button #click.stop="expandToggleHandler">{{ toggleExpandAndCollapse }}</md-button>
</v-layout>
</v-card>
and here is the image :-
in image you can see i have pressed expand button for single cards but event is getting fired for other cards too.
How can i resolve it any help with example would be appreciated.
You are using the single variable isExpand for multiple v-card components. To solve your problem I suggest to convert the variable to an array and use rowIndex as the index.
Your variable declaration should look like this:
isExpand: []
Your templates would use it like this.
<template v-if="!isExpand[rowIndex]">
</template>
<template v-else>
</template>
Please note that I replaced the second v-if with a v-else so the isExpand variable isn't checked twice.
The method would become:
expandToggleHandler(rowIndex) {
this.isExpand[rowIndex] = !this.isExpand[rowIndex]
}
And you access it like this:
<md-button #click.stop="expandToggleHandler(rowIndex)">{{ isExpand[rowIndex] ? 'Collapse' : 'Expand'}}</md-button>
I didn't know what toggleExpandAndCollapse does but I guess it handles the button label.

How to make the value of item-value a router link in Vuetify?

I am trying to add a router link for each element in this autocomplete component, but the links are not being added. How do I make the items in the list clickable corresponding to a URL with their id ?
I want the value of item-value to be a router link as below:
<router-link :to="'employee/'+ item.ID">{{item.ID}}</router-link>
here is the autocompelete
<v-autocomplete
:items="employees"
item-text="ID"
item-value="ID"
data-vv-name="search"
append-icon="mdi-magnify"
placeholder="Search for an employee"
outlined
id="search"
>
</v-autocomplete>
is changing the value the right approach to do this?
You can add the slot item to modify the item in the list.
Try this:
<v-select
:items="employees"
item-text="ID"
item-value="ID"
data-vv-name="search"
append-icon="mdi-magnify"
placeholder="Search for an employee"
outlined
id="search"
>
<template v-slot:item={item}>
<router-link :to="'employee/'+ item.ID">{{item.Name}}</router-link>
</template>
</v-select>

Why cannot I hide a div with v-if?

Scenario: I have two options for a signup page. In the second one, I have a few more input elements and I only want to render that div when I click the second checkbox. For that, I wrote a v-if and it does not work properly.
(the project is in Vue)
<v-checkbox v-model="checkboxes" label="Bireysel Üyelik" value="checkbox-1"></v-checkbox>
<v-checkbox v-model="checkboxes" label="Kurumsal Üyelik" value="checkbox-2"></v-checkbox>
<div v-if="checkboxes === 'checkbox2'">
<v-text-field
name="cellPhone"
label="Cep Telefonu"
type="text"
key="cell-phone"
outlined
dense
required
>
</v-text-field>
</div>
data() {
return {
checkboxes: "",
}
}
The Html and JS files are as above. The data is dynamically changed in the Vue instance and there is no problem with that. The problem is with the conditional rendering mentioned above.
In your checkbox you bind a value of checkbox-2
<v-checkbox v-model="checkboxes" label="Kurumsal Üyelik" value="checkbox-2"></v-checkbox>
but then you look for checkbox2
<div v-if="checkboxes === 'checkbox2'">
<v-text-field
name="cellPhone"
label="Cep Telefonu"
type="text"
key="cell-phone"
outlined
dense
required
>
</v-text-field>
change it to:
<div v-if="checkboxes === 'checkbox-2'">
<v-text-field
name="cellPhone"
label="Cep Telefonu"
type="text"
key="cell-phone"
outlined
dense
required
>
</v-text-field>
and it will work :) .
Hope this helps!

Wants to highlight only chars the user types in the input v-autocomplete

I have made a v-autocomplete but it highlights words/chars in the list that the user haven't typed.
the v-autocomplete code:
<v-autocomplete
:filter="() => true"
item-text="states.text"
:items="states"
filled
rounded
v-model="model"
:search-input.sync="search">
<template
slot="item"
slot-scope="{ parent,item }"
>
<v-list-tile-content >
<v-list-tile-title v-html="`${parent.genFilteredText(item.text)}`">
</v-list-tile-title>
</v-list-tile-content>
</template>
</v-autocomplete>
You can se it all in the codepen: https://codepen.io/maikenmadsen92/pen/ZEEZjYM?editors=1010
Is it possible just to highlight the words the user have typed in the input?
There are some issue with the implementation of you v-autocomplete.
You filter is useless since it will alway return true with is why all words/chars is highlights.
And the main issue is you item-text since following the doc vuetify
item-text :
Set property of items's text value
With mean you item-text=text since the items is already set to states.
<v-autocomplete
item-text="text"
:items="states"
filled
rounded
v-model="model"
:search-input.sync="search">
<template
slot="item"
slot-scope="{ parent,item }"
>
<v-list-tile-content >
<v-list-tile-title v-html="`${parent.genFilteredText(item.text)}`">
</v-list-tile-title>
</v-list-tile-content>
</template>
</v-autocomplete>
i am able to use getMaskedCharacters to do the trick