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

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>

Related

Vue: Event does not emit several values. Is there something wrong with v-model?

I'm Vue beginner and have tried setting up a simple app that takes in some user input to display a result on an extra page / component.
Component A has 2 sliders. I'd like to pass both values to Component C. Currently only one value is passed.
I spent hours on this and have already received super valuable support on another question by #RoboKozo, but this keeps me from progressing any further.
Please find my current code here.
Bind both props, and emits
<component
:is="selectedComponent"
:modelValue="value"
:modelValue2="value2"
#update:modelValue="value = $event"
#update2:modelValue2="value2 = $event"
>
</component>
The event name for updating the model value of modelValue2 should be update:modelValue2 (not update2:modelValue2):
// ComponentC.vue
this.$emit('update:modelValue2', this.local2)
Then to bind component.modelValue2 to App.value2, specify modelValue2 as the v-model binding argument:
<component v-model="value" v-model:modelValue2="value2">
Note you don't need to specify the binding argument for modelValue because that's the default.
demo

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.

v-select/Vue: How to enter value not in the list?

I'm trying to find a way to add a new value using v-select previously not in the list. So that the new value entered will become the selected option.
This is my current code:
<v-select
ref="systemSelect"
v-model="reservation.system"
name="system"
label="Select System"
:disabled="isBusy"
:options="systems"
#input="getSystems"
/>
In UI the component looks like this. Here I use Vuex only to get :options. Currently if I enter a new value and click outside that value disappears since its not found in the list
Expected: Would like to enter a new value and use this value as current in the form and save it. Is there a way to achieve this?
Any help would be appreciated.
Thanks!
If you're using vue select, you can use the attribute taggable and multiple to push your own options:
<v-select taggable multiple />
See this link:
https://vue-select.org/guide/values.html#tagging

get complete Vuetify item from v-autocomplete

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

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/