buefy table get data of clicked row - vue.js

Below is my code:
<b-table :data="sortTeachersAndPoints(topTeachers)" :columns="topTeachersColumns" :mobile-cards="false" #click="clickTeacher(data)"></b-table>
Everything above works good except the clickTeacher(data) part. What I'm trying to do is pass the selected row's data to clickTeacher but (understandably), I got this error Property or method "data" is not defined on the instance when clicking any row.
So actually what should I write to pass the selected row's data to clickTeacher?

use your clickTeacher and pass the $event
<b-table :data="sortTeachersAndPoints(topTeachers)" :columns="topTeachersColumns" :mobile-cards="false" #click="clickTeacher($event)" ></b-table>

Related

Why does my v-select not have any default values even though I am assigning v-model a string

I am editing a vue for a project that I am working on. Below is my code
<tr v-for="(program, index) in selectedGantryLocation.pickPrograms">
<v-select :items="program"
:v-model="selectedGantryLocation.pickProgramValues[index]">
</v-select>
</tr>
The selectedGantryLocation.pickPrograms is a list of a list of strings. So each "program" that is being used in the iteration is an array of strings, it is nothing more and nothing less. The array generally looks like ["Program1","Program2","Program3" etc.]. The :items are being populated correctly and are displayed correctly in the dropdown.
Now because in this vue each dropdown will already have a previously selected value that I am grabbing from the backend, I need each dropdown to show the already selected value. selectedGantryLocation.pickProgramValues[index] is indexing a list of strings, each being the default value of each v-select that is created.
For some reason the v-model is not showing any default values. I have verified that the selectedGantryLocation.pickProgramValues is indeed populated and filled with strings. Is there an issue with assigning v-model to a string? If that is the case then I do not know how to go about fixing this issue as I have no more properties to reference because I am only working with lists of strings.
I also know that this won't work if the v-model value does not exist in the :items but I have also verified that it does exist here so that should not be an issue.
If anyone has any ideas of why my v-selects do not have any default values I would appreciate your feedback, thank you!

Bootstrap Table row-clicked event

I'm using a <b-table> component in a Vue project and I need to define a function to be triggered when a row is clicked. I heard that there is a #row-clicked property in b-table so I tried to use it and I can put simple functions inside of it, I mean I can get console prints etc but nothing more complicated...
I want two functions to be executed when a row is clicked. The functions are now bound to a button inside of every row, but I dont want use it like this, I just need to click the related row to make them work. Here is the current version of the b-table component;
<b-table
:items="displayByType"
:fields="displayColumn"
responsive="sm"
:per-page="perPage"
:current-page="currentPage"
:sort-by.sync="sortBy"
:sort-desc.sync="sortDesc"
:filter="filter"
:filter-included-fields="filterOn"
#filtered="onFiltered"
hover
#row-clicked="test"
>
And here is the two functions that I want to be triggered when a row is clicked...
toggleRightBar(){
document.body.classList.toggle("right-bar-enabled");
}
changeRightBarContent(row){
this.$store.dispatch("rightbar/changeRightBarInfo", tableData[row]);
},
There is a JavaScript folder that I export column names and row data. I also a have Rightbar, when a row is clicked, I want to enable the rightbar so that the user can see detailed information about that specific row.
At last, here is the button that I use to make these two functions work;
<template #cell(detail)="row">
<button #click="toggleRightBar(); changeRightBarContent(row.index);" class="btn btn-outline-primary toggle-right">
<i class="bx bx-detail toggle-right"></i>
</button>
</template>
Basically, I dont want to use this button, instead, I want to click the row itself. Every row's rightbar information will be uniqe, my function does that. I just dont know how to use these 2 functions inside #row-clicked
Thanks in advance.
The row-clicked event will pass 3 parameters to your function.
The first being the item specific to the row that was clicked. The second will be the index of the row, and the third is a native click event.
This means you can use the arguments keyword to get the index and pass it to your function.
#row-clicked="toggleRightBar(); changeRightBarContent(arguments[1])".
Alternatively you can create a third method which will call the other two.
<b-table #row-clicked="onRowClicked" />
{
onRowClicked(item, index, event) {
this.toggleRightBar();
this.changeRightBarContent(index);
}
}
You can read more about the #row-clicked event on the docs component reference section.
https://bootstrap-vue.org/docs/components/table#comp-ref-b-table-events

Using inner component in a loop in Shopware 6 does not persist the values uniquely for each looped component

I am using a v-for over a custom component and passing the item as a prop. But the issue is that each component instance in the loop takes the same item prop. For e.g in the 1st loop a component field has text "abc", then the second looped component also will have the same "abc" text. If I change the text in the 2nd one, it changes in the 1st component too. Is there a way to make the prop unique for each loop ?
For e.g this is the code which calls the inner component:
<template v-for="(businesscase, index) in businessCase.fields">
<custom-case-freetext-field #field-changed="updateFields"
:key="index"
#field-removed="removeFields"
:fields="businessCase.fields"
:index="index">
</custom-case-freetext-field>
</template>
and inside this component I have a basic form
<sw-field :label="$tc('rma.modules.case.freetext.nameLabel')"
:placeholder="$tc('rma.modules.case.freetext.nameLabel')"
required
v-model="fields[index].name">
</sw-field>
<sw-single-select
labelValue="label"
valueProperty="label"
:options="fieldTypes"
:label="$tc('rma.modules.case.freetext.fieldType')"
:placeholder="$tc('rma.modules.case.freetext.fieldType')"
v-model="fields[index].type"
#input="changeType"
required>
</sw-single-select>
If I do :value instead of v-model, the entered value disappears as soon as the element loses focus.
If I use v-model, the data stays there, but then both (or as many are there in the loop) component instances, have data binding between them, so it defeats the purpose of having a loop for multiple components. As seen in the screenshot, I am typing in the 2nd component, but it changes the text for the first one too.
In the above example I am sending the whole array as prop, but I have also tried with individual field element instead of fields
Your are not using the businesscase variable inside your components. And since every component always works on the upper scope property, they will all change the same. Use the innerscope property. If you have problems with reactivity, because you try to mutate props directly work with events emitting the key and the changed value to the upperscope component.

How fix datepicker calendar position in element-ui

I have two datepickers in my code and i change them between each other by another parameter(duration which can be Single day or Multi day). By default it set as Single day. First calendar have right position, but when i change from single day to multi day and open range datepicker, calendar which have absolute position sets in top left corner of page (with top:0;left:0 parameters).
I tried change directive v-if to v-show in my code below, and it helps, but there is another problem. For some reason element-ui think that picked value is not range and throw parse error. So i need another solution.
That's piece of code with this datepickers:
<el-date-picker
v-if="duration === durations.SingleDay"
placeholder="Enter date"
value-format="yyyy-MM-dd"
#input="updateTime($event, 'dateValue')"
:value="value.dateValue"
></el-date-picker>
<el-date-picker
v-else-if="duration !== durations.SingleDay"
placeholder="Enter date"
type="daterange"
value-format="yyyy-MM-dd"
:value="value.dateValue"
#input="updateTime($event, 'dateValue')"
></el-date-picker>
I want to positionate range datepicker as usual, like in datepicker in Single day parameter.
FIDDLE
Demo on fiddle, first open calendar and change type and reopen it, you can see this bug
In that case, there're two ways to solve this:
Change v-if to v-show
Add different key attributes to the Datepicker components (Vue will know that this is two different components)
In fact, this is not a bug. You use the same component in v-if and v-else. The two component properties are basically the same, so Vue will reuse the previous components, but you should avoid multiplexing complex components in Vue. It's easy to go wrong, which is why you must add a key in v-for in vue.
You did not modify the internal reference this.$refs.reference when you reused the component, and the position of the popover cannot be calculated correctly.

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