v-select displays object Object - vuex

I'm new to vuetify and I'm stuck on how to properly use v-select. I'm pulling the select values from an API to a store called FormatTypes that looks like this:
[{"id":5,"formatlabel":"RDBMS Table or View"}
,{"id":6,"formatlabel":"Microsoft Access"}
....
,{"id":23,"formatlabel":"ArcGIS for Server image services"}]
my v-select:
<v-select font-weight-regular subtitle-1
v-model=dataset.formattypeid
:name="FormatTypes"
:items="FormatTypes"
:item-value="FormatTypes.id"
:item-text="FormatTypes.formatlabel"
:label="FormatTypeLbl"
:outlined=true
>
I've used the item-text/item-value props but I'm still getting the "object Object" in the display.

You don't have to use binding and no need to link it back with the items in item-value and item-text
<v-select font-weight-regular subtitle-1
v-model=dataset.formattypeid
:name="FormatTypes"
:items="FormatTypes"
item-value="id" // No need of binding and no need of FormatTypes linking
item-text="formatlabel" // No need of binding and no need of FormatTypes linking
:label="FormatTypeLbl"
:outlined=true
>

Related

How to change HTML tags of the component dynamically after click in Vue3 composition-api?

I am writing my first app in Vue3 and I use composition-api with script setup.
Using v-for, I create components that are inputs (CrosswordTile) that make up the crossword grid.
A problem appeared during the implementation of the field containing a clue to the password.
Since the text doesn't allow text to wrap, I wanted to dynamically change the tag to after a click.
Function in parent component where I handle logic after click that change tile type works fine, but I need to change tag of "target" to and set maxLength to a different value.
If it would help here is whole code on github: https://github.com/shadowas-py/lang-cross/tree/question-tile, inside CrosswordGrid.vue.
function handleTileTypeChange(target: HTMLInputElement) {
if (target && !target.classList.contains('question-field')) {
addStyle(target, ['question-field']);
iterateCrosswordTiles(getNextTile.value(target), removeStyle, ['selected-to-word-search', 'direction-marking-tile']);
} else if (target) {
removeStyle(target, ['question-field']);
if (getPrevTile.value(target)?.classList.contains('direction-marking-tile')) {
iterateCrosswordTiles(
target,
addStyle,
['selected-to-word-search', 'direction-marking-tile'],
);
}
}
TEMPLATE of ParentComponent
<div
class="csw-grid"
#input="handleKeyboardEvent($event as any)"
#mousedown.left.stop="handleClickEvent($event)"
#click.stop="">
<div v-for="row in 10" :key="row" class="csw-row" :id="`csw-row-${row}`">
<CrosswordTile
v-for="col in 8"
:key="`${col}-${row}`"
#click.right.prevent='handleTileTypeChange($event.target)'
/>
</div>
</div>
I tried to use v-if inside CrosswordTile, but it creates a new element, but I just need to modify the original one (to add/remove HTML classes from it basing on logic inside CrosswordGrid component).
How can I get access to the current component instance properties when using the composition API in script setup or how to replace the tag dynamically?
:is and is doesn't work at all.

vue-tippy with a single global popup for multiple buttons

I'm using vue-tippy 6.0.0-alpha.63 for vue3.
I have a single component on the page which has a dynamic content and want to make a tooltip from it. This tooltip should be shown when user moves mouse over one of many buttons with class skill_tab. Those buttons are nested deeply inside the parent component of the current component.
I wrapped the component content with a <tippy> component and I'm trying to bind the tooltip to the buttons using to prop but it doesn't work.
I also tried using the triggerTarget prop providing the class .skill_tab as the value, but it looks like triggerTarget only works with refs.
Component for a button:
SkillTab.Vue
<div class="skill_tab">
...
</div>
Component for the tooltip:
SkillTooltip.Vue
<tippy followCursor=true to=".skill_tab" allowHtml=true placement="bottom-end" interactive=true>
<div id="skill_tooltip" class="skill_tooltip" :class="{active}" v-if="active">
...
</div>
</tippy>
Is there any way to bind the tooltip to all the buttons without passing refs via a global state or any other simple way?

Unable to use array element with Vuetify v-file-input

I have a component that uses multiple Vuetify v-file-input components
<v-file-input
:accept="allowedFileTypes"
label="Choose Attachment"
:loading="attachmentBeingProcessed"
name="file0"
id="file0"
:error='fileSizeError[0]'
outlined
dense
#change="fileSelectedForUpload(0)"
#click:clear="removeAttachment(0)"
></v-file-input>
I want to show a particular v-file-input in error mode through code. However, when I set this.fileSizeError[0] = true, it does not put the component in error mode. However, if I use a variable (not array), as show below, it works
<v-file-input
:accept="allowedFileTypes"
label="Choose Attachment"
:loading="attachmentBeingProcessed"
name="file1" id="file1"
:error='fileSizeError1'
:error-messages = "fileSizeErrorMsg1"
outlined
dense
#change="fileSelectedForUpload(1)"
#click:clear="removeAttachment(1)"
></v-file-input>
Is there a reason that I cannot use an array element with ":error"?
Thanks.
There is nothing wrong with assigning an array value to a prop, the problem is changing an array index value is not reactive in Vue 2. As the docs explain, to get around this issue you can update your array[0] value to true using $set:
this.$set(this.fileSizeError, 0, true);

Iterate form fields in Vue.js

I have a list of products and my product items have some specifications that are different depending on what type of product has been selected. So instead of making 3 different edit forms (1 for each product) I want to iterate over each form field in the list of my specifications.
However I can't use v-model on an iteration so I have to bind it to the :value, however I can't bind these values back dynamically to my form object.
How can I make my form dynamic by iterating over an object and binding it back to my form payload?
v-for
<div v-for="(spec, index) in item.specs" :key="index">
{{spec}}
<v-text-field :name="spec" :label="index" :value="spec"></v-text-field>
</div>
Object
I fill this object from my API return this.specs = response.data.specs
specs:{}
you can use v-model for two-way data bindings. As
<div v-for="(spec, index) in item.specs" :key="index">
{{spec}}
<v-text-field :name="spec" :label="index" :value="spec" v-model='item.specs[index]'></v-text-field>
</div>

How to v-bind content-class in v-checkbox component?

In first CodePen example https://codepen.io/anon/pen/ROXrRZ you can see tooltip message has padding using prop content-class="pl-5"
First picture
In second CodePen example https://codepen.io/anon/pen/qwebXR you can see that tooltip message doesn't have it using v-bind on same prop like :content-class="{'pl-5': true}"
Second picture
How to make v-bind work on content-class?
It looks like the content-class prop doesn't accept an object as value.
You can just use the following syntax:
<v-tooltip top :content-class="condition ? 'pl-5' : ''">