Vue2 generated select triggers event for every other selects - vue.js

I have a Vue2 project with Buefy extension. Then I have an array of objects which is rendered in the template with one select component for each item. Everything works, but if I trigger #input event on one of the select elements it triggers input event for all selects in the list. I dont understand what is wrong with that.
<div v-for="(inv, index) in pendingInvitations" :key="index" class="columns is-desktop">
<div class="column is-4">{{inv.email}}</div>
<div class="column is-4">
<b-field class="mb-5">
<b-select v-if="invitationRoles"
:input="changeInvitationRole(index)"
v-model="pendingInvitations[index].role"
:placeholder="role">
<option v-for="(value, key) in invitationRoles"
:key="key"
:value="value">
{{ value }}
</option>
</b-select>
</b-field>
</div>
</div>
...
changeInvitationRole(index){
console.log(index);
},
If I change the role and there are three items in the list the console.log() writes 0, 1, 2 as indexes for all items. Why it happens to me? I expect only current itmes index in the log.

Try replacing input with change

Related

multiple select box using v-for

I have multiple select boxes which are rendered using a v-for loop, what I am trying to do is to store each option value for each select box in an array but when I select an option it only stores the chosen option, not multiple options
<template v-for="(gettailor) in gettailors" :key="gettailor.id">
<div class="col-sm-6" >
<div class="form-floating" >
<p>{{ gettailor.names }}</p>
</div>
</div>
<div class="col-sm-6">
<div class="form-floating">
<select class="form-select shadow-none" id="tailors" v-model="tailors" required>
<template v-for="(item) in gettailor.tailor" :key="item.id">
<option :value="item.id">{{ item.tailor }}</option>
</template>
</select>
<label for="tailors">Choose {{ gettailor.names }}</label>
</div>
</div>
</template>
<script>
import { ref, watch,onMounted } from 'vue';
const tailors = ref([]);
</script>
I think tailors should be an object, then you bind the select value to a value in the object:
<select
class="form-select shadow-none"
id="tailors[]" <-------- generates several selects with same id
v-model="tailors[gettailor.id]" <--------- bind to object value
required
>
Of course you can also use an array, but it does not work well with reactivity if you use loop index as key (if order changes, you don't know where the values came from), and if you use tailor id, you get a sparse array, which is probably hard to work with.

How do I take the value of my v-for and step them in mounted() and data() in vue.js, and i have a problem with combobox, i'll explain below?

basically what I'm trying to do is, I get the DateTime coming from my database along with some information of a possible meeting, if people are busy, they will have the option to extend that time through a combobox that pulls a enum in my backend which has values ​​in milliseconds, description and id. As I get these values ​​coming from my enum, I can extend the meeting, but I did this validation on the frontend through a function... where I get the value of the combobox, and add it to the dateTime coming from the BE, however, I can't change the database (legacy) to add a field to save the enum, and that's why I had to make an adapted function in the frontend, and the extension method is hardcoded and doesn't have a field in the BE it replicates the same combobox for all. pointing out that I can't pull the data still coming from my v-for to mounted() or data().
Please help me. I'm using Primevue.
i tried to catch the index/code coming from the v-for by #click the dropdown by creating the function in mounted(), but without success. When trying to manipulate this data, it returns me an undefined value enter image description here
my v-for loop
`<div
class="mt-2"
v-for="(item, index) in listaAlarme"
:key="index">
<!-- {{ item.codigo }}
{{ index }} :{{ listaAlarme[index].referencia }} -->
<Card class="cardContainer">
<template #content>
<div class="formgrid grid">
<UnoFormField
id="dateTimeReference"
:cols="4"
label="Date and Time">
<UnoFormCalendar
v-model="listAlarm[index].reference"
#click="handleAlterTime(index)"
:withTime="true" />
</UnoFormField>
<UnoFormField
id="extended"
:cols="3"
label="Extended">
<Dropdown
v-model="typeActivitiesExtend"
:options="typeActivitiesExtendList"
option-label="description"
option-value="milliSeconds"
placeholder="Extended"
:class="{
'w-full': true,
}"
class="p-dropdown-uno-trigger-black"></Dropdown>
</UnoFormField>
<UnoFormField
id="contact.name"
:cols="3">
<div class="phoneIcon">
<fa-icon
icon="phone"
#click="handleCall" />
</div>
</UnoFormField>
</div>
</template>
<template #footer>
<div class="formgrid grid">
<!-- <div class="flex"> -->
<UnoFormField
id="meeting"
:cols="3">
<Button
icon="pi pi-search"
class="p-button-uno-black"
#click="handleMeeting"></Button>
</UnoFormField>
<UnoFormField
id="description"
:cols="3">
<p class="text">
{{ listAlarm[index].shortDescription }}
</p>
</UnoFormField>
<div class="iconButtons">
<fa-icon
icon="ban"
class="banIcon"
#click="excludeItem" />
<fa-icon
icon="check"
class="checkIcon"
#click="onBtnSave" />
</div>
<!-- </div> -->
</div>
</template>
</Card>
`
the UnoFormField, is a label as you can see, that me return the label name and fied col just for display de fields with a size col in template
my function to extend the hours in methods:
i'm try to catch the value of datatime in v-for
`

The Bootstrap-vue3 table does not add buttons to each row of data

I'm trying to add a button to the bootstrap table using Vue3, but I ran into the following problem.
The logic of the button is stored in the parent component, and I plan to $emit on the logic from there. But in order for the button to delete a certain row, for example, I need to pass a special ID, I can't pass it to the ID, because I don't understand how to iterate through the data array in the bootstrap table correctly.
Maybe there is a soft and correct way to solve this problem?
ChildComponent.vue
<template>
<div v-if="data.length !== 0">
<div class="card inline" >
<div>
<b-table striped hover :items="data">
<button #click="$emit('remove', hereIneedTheID)">Remove</button>
</b-table>
</div>
</div>
</div>
<div class="card center" v-else>
<h4>No data available in the list</h4>
<button class="btn" #click="$emit('load')">Load list of data</button>
</div>
</template>
<script>
export default {
name: "AppDataList",
emits: ['load', 'remove'],
props: ['data']
}
</script>

Vue Component that Can Override What Child Renders Dynamically

I am working on a component (InfoCard) that should be able to render any number of fields passed into it with a 'fields' prop, as an array of json objects with a name, value, and some styling options. For certain fields, I want to be able to override what component is used to render, but do it from the parent (Table) rather than inside the InfoCard component, as it should be generic. My first thought was to use a <component :is='field.component'></component>, where it will render as plaintext if field.component is not defined, but to my understand it will be difficult to pass in any potential children necessary for the <component/>. My second thought is to use named slots from within the parent, but I don't think this is possible either in a good way. I'll show my current code.
In my example, I want to be able to detect if the field being rendered is 'status', and if it is, use a different rendering mechanism than displayValue(attribute), without hardcoding it inside InfoCard; I want the parent to be able to override this rendering conditionally. Is there a way to do this in Vue? Thanks
From Table, where data.records is an array of JSON objects:
<info-card
v-for="(record,index) in data.records"
:key="index"
:fields="record"
>
<div v-for="key in Object.keys(record)" :key="key">
<template v-if="field.name=='status'" v-slot:[`${field.name}_value`]>
<p> Field is status !</p>
</template>
</div>
</info-card>
From InfoCard:
<template>
<el-col
:lg="3"
:md="3"
:sm="3"
:xs="3"
v-for="(attribute, index) in fields"
:key="index"
class="attribute"
>
<div
#click="$emit('fieldClicked', attribute)"
>
<el-row
:class="`mid-gray f6 clipped fw5-ns m-b-10 ${attribute.nameClasses}`"
:title="displayName(attribute)"
:style="attribute.nameStyle?attribute.nameStyle:''"
>
<slot
v-if="Object.keys($scopedSlots).includes(`${attribute.name}_name`)"
:name="$scopedSlots[`${attribute.name}_name`]"
>
</slot>
<div v-else>
{{ displayName(attribute) }}
</div>
</el-row>
<el-row
:class="`mid-gray f6 clipped fw5-ns m-b-10 ${attribute.valueClasses}`"
:title="displayValue(attribute)"
:style="attribute.valueStyle?attribute.valueStyle:''"
>
<slot
v-if="Object.keys($scopedSlots).includes(`${attribute.name}_value`)"
:name="$scopedSlots[`${attribute.name}_value`]"
>
</slot>
<div v-else>
{{ displayValue(attribute) }}
</div>
</el-row>
</div>
</el-col>
</template>

Buefy Vue2 select does not react on input event

I have a code where I need to iterate over the array of objects and every one of them have a b-select inside. This select should react on input event but it deos nothing. The event is triggered on the first render but then it stops trigger event at all. Also the :v-model does not react on role change. The value is still the same.
<div v-for="(inv, index) in pendingInvitations" :key="index" class="columns is-desktop">
<div class="column is-4">{{inv.email}}</div>
<div class="column is-4">
<b-field class="mb-5">
<b-select v-if="invitationRoles"
:input="changeInvitationRole(index)"
:model="pendingInvitations[index].role"
:placeholder="$t('company.users.invitation.roles-placeholder')">
<option v-for="(value, key) in invitationRoles"
:key="key"
:value="value">
{{ value }}
</option>
</b-select>
</b-field>
</div>
</div>
The changeInvitationRole method looks like
changeInvitationRole(index){
console.log('aaaaaaa'); // Does not trigger after the change
console.log(index);
},
InvitationRoles looks like
{
aaa:"aaa",
bbb:"bbb",
ccc:"ccc",
user:"user,
}
PendingInvitations array looks like
[
{
active:1,
deleted:0
email:"xxxxxxxx#gmail.com"
id:8
role:"user"
token:"7l1nd8j2re"
}
]
Thanks for any help.
":" is bind sign. Methods are using "#" sign. Change to #input.native