How can we find out the parent element in which the vue draggable is dropped? - vue.js

There are multiple v-autocompletes and I want to know which v-autocomplete is my draggable element dropped in So that I can rearrange them properly. If I try to move the v-chips (draggable component) into another v-autocomplete it does not get positioned properly. I am using vue-draggable library, any kind of help will be appreciated thanks!!
v-autocomplete(
v-for="(cabinet, index) in cabinets"
:key="index"
v-model="selectedSystemCabinets[cabinet-1]"
#input="updateSelectedSystems()"
:items="systems"
:label="$t('Controllers')"
:rules="rules.nonEmptyArray"
:id="cabinet"
chips
multiple
return-object
outlined
color="primary"
item-text="name"
item-value="systemID"
)
template(#selection="data")
draggable(
:id="data.index"
:list="selectedSystemCabinets[cabinet-1]"
v-bind="dragOptions"
:move="move"
:group="{name: 'controllers', put: true}"
#change="change(cabinet, $event)"
#start="isDragging = true"
#end="endDrag"
)
v-chip(
draggable
:ripple="false"
:key="data.index"
v-model="selectedSystemCabinets[cabinet-1][data.index]"
#mousedown.stop
#click:close="remove(cabinet, data.index)"
#click.stop
style="cursor: move;"
:color="((isDragging && data.index === dragged.from) ? 'success' : 'primary')"
close
outlined
).ma-2
span {{ data.item.name }}
v-chip(
x-small
color="primary"
).primary-chip
span(v-if="showPrimary(data) && cabinet === 1").text-uppercase {{ $t('primary') }}
span(v-else) {{ getOrderNumber(data.index) }}

Related

Vue tabs multiple of same child component type wrong data

I have tabs which display forms. There are different types of forms, and each type of form can be open in its own tab 0 to X times. The issue is specifically when there are more than one of the same type of form open, plus at least one other type open:
In this scenario, when I change from Item Two back to Item One, the form shows the name prop from Item Two.
Here's how the tabs are setup:
<v-tabs
dark
background-color="blue-grey darken-4"
show-arrows
height="30"
v-model="activeModel"
class="fixed-tabs-bar"
v-if="openTabs.length"
>
<v-tabs-slider color="accent"></v-tabs-slider>
<v-tab v-for="item in openTabs" :key="item.id" class="pr-0 white--text" color="accent" active-class="" #click="setActiveTab(item)">
<template class="white--text text-capitalize">
<v-icon>
{{ item.icon }}
</v-icon>
{{ item.name }}
<div v-if="item.changes">*</div>
<v-btn plain width="10" class="px-0" #click="closeTab(item.id)">
<v-icon dark small width="10">mdi-close</v-icon>
</v-btn>
</template>
</v-tab>
</v-tabs>
<v-tabs-items v-model="activeModel" style="background-color: #232323;">
<v-tab-item v-for="item in openTabs" :key="item.id" style="height: 100%" :transition="false" eager>
<BlockForm
:key="item.id"
v-if="activeTab.type === 'blocks' && item.type === 'blocks'"
:name="openTabs[activeModel].name"
:activeProject="activeProject"
/>
<ItemForm :key="item.id" v-if="activeTab.type === 'items' && item.type === 'items'" :name="openTabs[activeModel].name" :projectName="activeProject" />
... More form types ...
</v-tab-item>
</v-tabs-items>
And set looks like:
setActiveTab: function(item) {
this.activeTab = item;
this.activeType = item.type;
}
The name prop is specifically what is wrong in the data.
<v-tab-item v-for="item in openTabs" :key="item.id" style="height: 100%" :transition="false" eager>
<BlockForm
:key="item.id"
v-if="activeTab.type === 'blocks' && item.type === 'blocks'"
:name="openTabs[activeModel].name"
:activeProject="activeProject"
/>
<ItemForm :key="item.id" v-if="activeTab.type === 'items' && item.type === 'items'" :name="openTabs[activeModel].name" :projectName="activeProject" />
... More form types ...
</v-tab-item>
The main problem is that when you set the activeTab variable, the v-tab-item element is not re-rendered. Because you are using item-id as key. You can use nextTick or directly apply the solution below.
You can take a look at Vue reactivity
:key="`${activeTab.id}-${item.id}`"

vuetify v-select multiple text values

i am trying to set mutliple text items in a v-select.
at the moment this is my v-select and its working with one :item-text.
But i need to display two fields. so i was checking the documentation and tried to use slots.
<v-select
:disabled="isReadOnly()"
v-show="!isHidden()"
:label="getLabel()"
:hint="field.description"
:items="selectVal"
:item-value="field.options.select.ValueField"
:item-text="field.options.select.TextField"
:multiple="isType(FieldType.ManyToMany)"
:chips="isType(FieldType.ManyToMany)"
v-model="fieldValue"
:rules=rules()
return-object
>
</v-select>
But when i am doing this:
<template slot="selection" slot-scope="data">
{{ data.item.name }} - {{ data.item.description }}
</template>
<template slot="item" slot-scope="data">
{{ data.item.name }} - {{ data.item.description }}
</template>
the default behavior of v-select must be reimplemented. (chips, displaying checkboxes on multiple select....
is there another way to do this? without copying the default behaviors und have duplicated code for this simple task?
thanks in advance.
sorry for the beginner question.
item-text can also be a function so you can do something like this
<v-select
:disabled="isReadOnly()"
v-show="!isHidden()"
:label="getLabel()"
:hint="field.description"
:items="selectVal"
:item-value="field.options.select.ValueField"
:item-text="getFieldText"
:multiple="isType(FieldType.ManyToMany)"
:chips="isType(FieldType.ManyToMany)"
v-model="fieldValue"
:rules=rules()
return-object
>
</v-select>
methods:
{
getFieldText (item)
{
return `${item.name} - ${item.description}`
}
}

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

How to add more properties to a slot on Datatables Vuetify 2.0?

How to add two or more properties on the same slot on Datatable Vuetify 2.0
I use below code for only one property called active, but if I want to use it for few other properties means (like status, is_user and etc), how can I use that? any OR condition on v-slot
<template v-slot:item.active="{ item }">
<v-icon class="font--style"> {{ item.active ? 'done' : 'clear' }} </v-icon>
</template>
Thanks in advance!
Maybe this extended example can help you to figure it out.
Here is the link https://codepen.io/anon/pen/aeVjBK?editors=1010
<template v-slot:item.fat="{ item }">
<v-icon :color="item.fat > 10 ? 'red' : 'green'">{{ item.fat > 10 ? 'done' : 'clear' }}</v-icon>
<span>({{item.fat}}%)</span>
</template>
After the response from Vuetify Discord Chennal
We can do something like this to achieve by having a list of column names in the array,
let listOfColumns = ['isActive', 'isUser']
<template v-for="(column, index) in listOfColumns" #[`item.${column}`]="{ item }">
<v-icon class="font--style" :key="index"> {{ item[column] ? 'done' : 'clear' }} </v-icon>
</template>
Thanks !!!

Vuetify concatenate two fields in v-select's item-text

Is there a way to concatenate two fields together in a v-select's item-text field?
I have it working for the drop down list values, but the visible entry doesn't show the two fields.
Problem is here: item-text="'${data.item.name}, ${data.item.group}'"
Code:
`<v-select label="Select" v-bind:items="people" v-model="e11"
item-text="'${data.item.name}, ${data.item.group}'"
item-value="name" max-height="auto" autocomplete >
<template slot="item" slot-scope="data">
<v-list-tile-content>
<v-list-tile-title
v-html="`${data.item.name}, ${data.item.group}`">
</v-list-tile-title>
<v-list-tile-sub-title
v-html="data.item.group">
</v-list-tile-sub-title>
</v-list-tile-content>
</template>
</v-select>`
Pen Example: https://codepen.io/anon/pen/dJveWM?editors=1010
Thank you
You need to define a template not only for the slot item but also for the slot selection when using <v-select>:
<template slot="selection" slot-scope="data">
<v-chip
close
#input="data.parent.selectItem(data.item)"
:selected="data.selected"
class="chip--select-multi"
:key="JSON.stringify(data.item)"
>
<v-avatar>
<img :src="data.item.avatar">
</v-avatar>
{{ data.item.name }}
</v-chip>
</template>
See
https://vuetifyjs.com/components/selects#6-scoped-slots
for reference.
This can also be a much simpler solution like the one you're trying to achieve:
<template slot="selection" slot-scope="data">
{{ data.item.name }}, {{ data.item.group }}
</template>
Also see it in action:
https://codepen.io/anon/pen/PEpaMM?editors=1011
For David Folkner: you can add the :filter="customFilter" property to the autocomplete component and then add in the methods block the customFilter function that achieves the custom search.
For example, if your items list is composed by n item objects with id, function and description properties, you should do this for searching through both function and description properties:
Autocomplete component:
<v-autocomplete v-model="itemSelected" :items="items" required box chips label="Select an Item" item-value="id" item-text="description" :filter="customFilter">
<template slot="selection" slot-scope="data">
<v-chip :selected="data.selected" class="chip--select">
{{data.item.function}} - {{ data.item.description }}
</v-chip>
</template>
<template slot="item" slot-scope="data">
<v-list-tile-content>
<v-list-tile-title v-html="data.item.function +' - '+ data.item.description"></v-list-tile-title>
</v-list-tile-content>
</template>
</v-autocomplete>
methods:
methods: {
customFilter (item, queryText, itemText) {
const textOne = item.function.toLowerCase()
const textTwo = item.description.toLowerCase()
const searchText = queryText.toLowerCase()
return textOne.indexOf(searchText) > -1 || textTwo.indexOf(searchText) > -1
}
}
<v-select
:items="unitTypes"
item-text="value"
item-value="id"
v-model="formData.unit_type"
prepend-icon="mdi-ammunition"
label="Unit Types"
required
:error-messages="errors"
>
<template slot="selection" slot-scope="data">
{{ data.item.value }} {{ data.item.type }}
</template>
<template slot="item" slot-scope="data">
{{ data.item.value }} {{ data.item.type }}
</template>
</v-select>
We are using
"vue-cli-plugin-vuetify": "2.0.5",
"vue-eslint-parser": "^7.10.0",
"vue-template-compiler": "^2.6.11",
And the following worked well for us.
<v-autocomplete v-model="data.alarmInfoId" :items="dbQueryResult" item-value="prop3" :item-text="(row) => {return row.prop1+ ' - ' + row.prop2;}"/>
dbQueryResult is a list of items returned from an API call
prop1, prop2, and prop3 are properties on each row in dbQueryResult
I believe that this will work with v-select as well. Though we use v-autocomplete so that users can type search in larger lists.
use slot="selection"
<template slot="selection" slot-scope="item">
{{ item.name }}-{{ item.group }}
</template>
To know more slot
https://vuetifyjs.com/en/api/v-autocomplete/#slots
item-text can accept a function
:item-text="item => `${item.first_value} ${item.second_value}`"