get complete Vuetify item from v-autocomplete - vue.js

I need to get the entire array element that makes up the Autocomplete item, I want the element so I can store it in Veux without store each item, such as first name, MI last name etc. I'm going to build upon another question that was very similar that was posted here Vuetify v-select get item index and with the jsfiddle answer solution
my code that I'm using is:
<v-list-tile>
<v-autocomplete
v-model="data"
:allow-overflow="false"
:items="named_items"
:item-text="getFullName"
:loading="loadingMembers"
:debounce-search="0"
:search-input.sync="searchInput"
class="purple-input search-input"
default
color="purple"
autofocus
placeholder="Search..."
item-value="MemberID"
hide-no-data
no-data-text="Add New Member"
#change="changeMember"
#keyup.enter="hitEnter"
/>
</v-list-tile>
the jsfiddle is at https://jsfiddle.net/Roland1993/fg461d55/1/
and my question is when an item is selected is it possible to get the element that makes up the ID, Question and Answers? so the it can be stored as an array?

It is entirely possible, for example, you have already bound to events, but you can have the name or values of their targets.
See: Method Event handlers

Related

Prevent list display filter from resetting v-list selection

Version info: Vuetify 2.6.3, Vue 2.6.14, Nuxt 2.15.8
I'm making a custom component that is supposed to be somewhat similar to v-autocomplete, except that it's rendered as bottom sheet. If user enters a display filter into v-text-field, the option list (v-list) is supposed to display only those options that match the filter.
In overall it works fine except one use case: let say the list has 5 items (aa, bb, cc, dd, ee) and user selected bb and cc from the list. Now, v-list-item-group's model selectedItems contains the 2 selected items bb and cc, perfect! However, when user enters b into display filter, the already selected item cc will be auto deleted from selectedItems. I can't tell if selectedItems change is caused by filter or by user selection. Is there a way to maintain the selection in model?
I'm considering a hack - if an item is selected, keep it in filteredChoices even if it does not match the filter. This behaviour is bearable but UX wise not as intuitive as the filter of v-autocomplete.
The simplified structure looks like the below:
<template>
<v-bottom-sheet scrollable>
<v-card>
<v-card-text>
<v-list>
<v-list-item-group
v-model="selectedItems"
:mandatory="!optional"
:multiple="multiple"
>
<v-list-item
v-for="item in filteredChoices"
:key="item.value"
:value="item"
>
</v-list-item>
</v-list-item-group>
</v-list>
</v-card-text>
<v-text-field
v-model="filterInput"
placeholder="filter choices..."
hide-details
></v-text-field>
</v-card>
</v-bottom-sheet>
</template>
<script>
...
filteredChoices() {
if (this.filterInput == null) {
return this.allItems
}
return this.allItems.filter((item) => {
return item.label
.toLocaleLowerCase()
.includes(String(this.filterInput).toLocaleLowerCase())
})
},
...
</script>
How I reach the solution:
I was quite new to front-end stuff. Previously, when I was learning how to implement v-model support for custom component, all web resources I came across say the same thing - bind inner component's value props to custom component's value props. However I just discovered that this is merely one of the ways rather than a must. With that new learning, more possibilities pop up in my mind and one of them lead me to below solution.
Solution:
Decouple the custom component value from bottomsheet's list
Bind the model of inner v-autocomplete to an array data, say internalValue. (this inner component is not included in question's template for simplification)
Bind the model of inner v-list-item-group (in bottomsheet) to a separate data, say bottomSheetSelections.
Update the custom component value based on user actions in bottomsheet
Add a watcher to bottomSheetSelections array:
if the array grows, it means the user has selected more item. We should push the additional item to internalValue.
if the array shrinks:
if the missing item is still there in filteredChoices, the removal is triggered by user de-selection. We should remove this item from internalValue.
else, we consider the removal is triggered by list filter. No action is needed.
Restore user selection in bottomsheet on clearing filter
Add a watcher for filteredChoices. Whenever the array grows, if the additional choice exist in internalValue, we should push it to bottomSheetSelections.
Summary
Strictly speaking, this doesn't solve the ask of question's title - the list selection in bottomsheet (bound to v-list-item-group) is still getting reset. However, at least we're able to restore it in bottomsheet on clearing filter.
More importantly, this solution achieved the objective mentioned in question details - retain the user selection value. We kept it in a separate data internalValue.
I haven't test this solution with long list of data. My guts feeling is that there could be more efficient solution. Please share it if you have a better solution.

Vue 2 - How / is it possible to create a unique layout during a v-for loop?

I am trying to create a questionnaire. I have an array of questions. Each question is an object. During the loop the <component :is> checks the component property inside the question object. If the property equals an Input for example then an input will be shown and so on.
This works for simple questions. However the last question requires a more complex layout. Here 'Please add items' needs to have two inputs and an add button. Once pressed a table will appear with each row displaying the values passed into the fields from above. At the moment I can't do this as I am looping though a sub set of questions.
There could be 1000+ questions eventually and I am not sure whether creating a component for each question is the right approach?
I know my current approach isn't right some how but I am completely stuck how to approach this. Is there a way of looping through data and providing unique layouts for each question? The data structure isn't set in stone so feel free to change it.
https://codesandbox.io/embed/blazing-wood-ifnxym?fontsize=14&hidenavigation=1&theme=dark
Within the v-for, you can wrap the elements in a <template>, and then just use v-if to determine which element is displayed.
For example :
<template v-for="question in question.questions" :key="question.id">
<Input v-if="quetion.type === 'text'" :question="question" />
<Radio v-if="quetion.type === 'choice'" :question="question" />
...
</template>

Display one object property value, and show another one on hover

the question I have might be hard to understand, so please help me re-organize the question if you can see the better way to put it in.
So, I am building a registration platform.
(1) First, I receive an array of objects of cases the user can sign time to.
(2) Each object consists of 2 properties, "name", "description".
(3) I store the array in the data, end use it in the element provided by a picker called "vue-multiselect", which basically accepts the array and loops over the objects and displays them.
(4) As you can see, it displays both properties and values, which I am trying to avoid. My question is, is it possible to pass only the "name" value into the picker, and display the description value when hovering the first value?
You can find this use case documentation here: https://vue-multiselect.js.org/#sub-custom-option-template
<multiselect v-model="value"
deselect-label=""
select-label=""
placeholder=""
selected-label=""
:show-pointer="true"
:options="projectCases">
<template slot="option" slot-scope="{ option }">
<strong :title="option.description">{{ option.name }}</strong>
</template>
</multiselect>
ps: I use title attribute to implement display-on-hover functionality. you can use any other tooltip library as well.

Vue-Multi-Select getting the array of data

Hello I am making a multi-select in Vue and my problem is I don't get the exact data from the selected items
Here is my code
<multiselect v-model="itemValue"
:show-labels="false"
:options="itemObj"
:multiple="true"
:close-on-select="false"
:clear-on-select="false"
:hide-selected="true"
:preserve-search="true"
label="itemName" track-by="itemName"
:preselect-first="true"
placeholder="List of Items"
#select="selectItem($event)">
<template slot="selection" slot-scope="itemValue"></template>
</multiselect>
<!---- TO SHOW THE CURRENT SELECTED ITEM ID --->
<pre>{{itemValue.map(a => a.id)}}</pre>
when I try to select an Item in the selection, right in the <pre> I'm able to see the selected Item ID but when I try to console.log(itemValue) it will not show anything but if I will select another item, there must 2 selected items now which is being shown in <pre> but in my console.log(itemValue) it will just show the first selected Item.
Does anyone know how can I get the exact selected items so I can able to search using this kind of filter because basically, I will use this as a search filter.
THANK YOU!
see this codesandbox for a working sample: https://codesandbox.io/s/1yml74p9xj
there were some issue's in your code, but you can see the sample how to get it working. 3 files to look at:
App.vue (were the multi select is added to vue globally)
index.html (import of css for style)
HelloWorld.vue (for the code)
in my sample, the selectedItems contains the items that were selected/unselected from the vue multi select

In VueJS, v-for doesn't create discrete items when new data is assigned

Currently, when I have a v-for loop like this:
<li v-for="record in records">
<my-vue-list-item :vue-title="record.title"></my-vue-list-item>
</li>
and I update the data driving the v-for (i.e. assign a new value to records), it doesn't actually create new list items based on the new data. It just updates some of the properties on the list item components components.
Here is a JSFiddle illustrating what I'm talking about. Try expanding one of the buttons (e.g. click "Expand Apple"), then click on "Set 2" to see that even when the list items switch, the component stays expanded.
What's the recommended way of getting around this behavior? I want each new list item (when the data is swapped out) to appear like new. (In the fiddle example, which I load a new set, it should not be already expanded.)
You need to let the Vue components know that the item is different. As far as they know, they're still rendering the same element index from the same list.
You can do this by specifying the key in your v-for iterator...
<li v-for="item in items" :key="item">
https://jsfiddle.net/ahxf44jk/21/