Vuejs Rebind an Html Select List - vue.js

I have a data-grid.
When the user clicks the "edit" button for a row in the grid, the div which contains the grid is made invisible (using v-if) and another div which contains an update form for that item is made visible (also using v-if).
As an added complication, the "edit" form contains a selectlist. This is bound to an array, but the array to which it is bound varies, depending on which item is selected in the grid (the items in the grid are different kinds of things).
How do I get that selectlist to rebind each time an item in the grid is clicked on for edit.
I realise I could do this by making a component, but that to me is overkill.
Is perhaps a slot the answer? Not sure how to proceed.
This is the relevant code:
<b-row v-if="editClaimFormVisible" class="mt-6 justify-content-md-center">
<b-col cols="6">
<b-form #submit.prevent="editClaimSubmit">
<b-form-group label="Enter New Claim Value:">
<b-form-select v-model="selectedClaimForEdit.claimValue" :options="getClaimOptions()" value-field="id" text-field="name" required>
<template #first>
<b-form-select-option :value="null" disabled>-- Please select a claim --</b-form-select-option>
</template>
</b-form-select>
</b-form-group>
<b-form-group>
<b-button type="submit" variant="primary">Save</b-button>
</b-form-group>
</b-form>
</b-col>
</b-row>

Related

Pass row.item.attribute value to a modal with Bootstrap Vuejs

I have a table where in the last column there is a button that pressing it pops-up a modal with some information and actions to do.
To this modal I want to pass a value from the table (from a specific cell of each row) but the modal shows always the cell value from the last row of the table (it is like it considers the whole table as one row).
To do some test I wrote the attribute to be appeared on the button title ,and so far it works well (to each button it appears the correct attribute of each row).
It seems that in the next level (inside the modal) there is a misunderstanding and whichever modal opens it presents always the cell value of the last row.
table
modal
<b-table
sticky-header
selectable
select-mode="single"
selected-variant="success"
w-auto
show-empty
small
stacked="md"
id="eventdataTable"
striped
hover
responsive
:items="items"
:fields="event_columns"
:per-page="perPage"
:current-page="currentPage"
:sort-by.sync="sortBy"
:sort-desc.sync="sortDesc"
:sort-direction="sortDirection"
:filter="filter"
:filterIncludedFields="filterOn"
#filtered="onFiltered"
>
<template v-slot:cell(nearby_venues)="row">
<div>
<b-button
variant="info"
class="text-center"
size="sm"
#click="show1 = true"
v-b-modal="'modal1'"
>Nearby Venues {{ row.item.api_id }}
</b-button>
<b-modal
id="modal1"
ok-variant="info"
v-model="show1"
size="sm"
title="Nearby Venues"
> {{ row.item.api_id }} *This appears correct*
<p align="left">Choose Venues close to</p>
<b-form-select
v-model="userdata.eventApiId"
class="mb-3"
>
<template slot="first">
<option :value="row.item.api_id">
{{ row.item.api_id }} *This appears wrong -the value of the column cell from the last row*
</option>
</template>
</b-form-select>
<label
class="mr-sm-3"
for="venue-category-selection"
></label>
<b-form-select
class="mb-2 mr-sm-2 mb-sm-0"
v-model="userdata.selectedVenueCategory"
:options="venue_categories"
value-field="id"
text-field="name"
id="venue-category-selection"
size="sm"
></b-form-select>
<hr width="300" align="left" />
<div>
<p align="left">Distance</p>
<label
class="mr-sm-3"
for="event-place-selection"
></label>
<b-form-input
v-model="userdata.distance"
placeholder="distance"
width="5px"
></b-form-input
>km.
<b-button
size="sm"
variant="success"
#click="VenuesFromSelectedEvent"
v-b-toggle.collapse-2
>
Click Here
</b-button>
</div>
</b-modal>
</div>
</template>
</table>
The problem here is that there is a loop in this component going through every row, rendering a new b-modal for each row. The problem is in this part of the code:
```
<b-form-select
v-model="userdata.eventApiId"
class="mb-3">
```
Each time a modal is rendered for a new row, it changes the userdata.eventApiId to the value for the current row. So the userdata.eventApiId will always end up being the api_id for the last row of the table.
One solution would be to change the code so that when the button is clicked, you change the userdata.eventApiId to the row.item.api_id.
I also wouldn't recommend putting the modal in the loop, as you would be creating a lot of hidden modals. I would just have one modal outside of the table that changes the value of userdata.

Aligning button and alert vertically in Bootstrap 4 + Vue

Using bootstrap-vue in my VueJS application I'd like to place a button and an alert next to each other in one row with both items aligned centered vertically. Although I used <b-row align-v="center"> this doesn't seem to work.
As you can see in this example on Codesandbox, the buttons are aligned but the alert is not.
How can I align all the items?
The b-alert works a bit other than the buttons, so you have to apply different CSS rules to achieve the same effect:
<b-container>
<b-row align-v="center">
<b-col cols="2">
<b-button variant="primary">Button 1</b-button>
</b-col>
<b-col cols="2">
<b-button variant="secondary">Button 2</b-button>
</b-col>
<b-col class="d-flex align-items-center">
<b-alert class="mb-0 w-100" show>An alert...</b-alert>
</b-col>
</b-row>
</b-container>
This will work.
aligns the items in the last b-col with the flex utility classes
remove the bottom margin (mb-0), so the item has nothing in the way to be positioned
– applies width: 100% (with w-100 class), so the alert doesn't shrink because of the d-flex of the parent; instead of this class, you could use flex-grow-1, so the v-alert takes up the available space.

VUEJS List items editable with button #click (button is in another component)

I need to make list items editable on click.
I have a template with a card displaying the list items, and a button component that contains, among others, a button that will trigger modify(). When this button is clicked the list items should become text inputs and a save button should appear at the bottom.
I read about contentEditable = true, but I don't know where to set it. If it's #click, the button component needs to be aware of the list items.
How to let the button know about those list items?
<button /> should be child of <detailActivity>... so Props?
Here's the template with the list items: <detailActivity />
<b-row>
<b-card
header-tag="header"
footer-tag="footer"
class="text-center"
>
<h3 slot="header" class="mb-0">Activity Details</h3>
<ul
v-for="value in currentActivity"
:key="value.id"
class="listValues">
<li>....</li>
<li>....</li>
<li>....</li>
</ul>
<div slot="footer">
<buttons />
</div>
</b-card>
</b-col>
<b-col xs="8">
<activity-map />
</b-col>
</b-row>
Inside the <button /> component, among others, the edit button:
<b-button
variant="warning"
#click="edit"
>
Any idea on how I should do this?
THANKS

BootstrapVue control columns number in form group

I have a simple form group in BootstrapVue with a couple of input fields and select boxes which are added dynamically on a button click and I need to display another element (button, div, whatever) to the right of it so I can bind a click event to it to remove the field.
This is my code (taken from the BootstrapVue page).
<b-card bg-variant="light">
<b-form-group horizontal
label="Street:"
label-class="text-sm-right"
label-for="nestedStreet">
<b-form-input id="nestedStreet"></b-form-input>
<div>X</div> # This gets pushed down to the next line...I need it in-line
</b-form-group>
<b-form-group horizontal
label="City:"
label-class="text-sm-right"
label-for="nestedCity">
<b-form-input id="nestedCity"></b-form-input>
</b-form-group>
<b-form-group horizontal
label="State:"
label-class="text-sm-right"
label-for="nestedState">
<b-form-input id="nestedState"></b-form-input>
</b-form-group>
<b-form-group horizontal
label="Country:"
label-class="text-sm-right"
label-for="nestedCountry">
<b-form-input id="nestedCountry"></b-form-input>
</b-form-group>
</b-card>
I see that BootstrapVue automaticaly adds a class col-sm-9 to every row in the form-group that's why, if I add another div after it, it will be pushed down to the next line but I want it to appear in-line. Is it possible to set the number of columns in the form-group row?
I figured out that rewriting it using regular Bootstrap <div class="form-group"> tag can allow me to customize the input field class, so instead of using <b-form-group> I used <div class="form-group">.

Bootstrap-vue modal open three times

I'm using bootstrap-vue package. In some component I have three card-flip components:
<b-row>
<b-col lg="4">
<card-flip :order="'fifth'"></card-flip>
</b-col>
<b-col lg="4">
<card-flip :order="'sixth'"></card-flip>
</b-col>
<b-col lg="4">
<card-flip :order="'seventh'"></card-flip>
</b-col>
</b-row>
and inside this card-flip component I'm displaying three different buttons depending on :order prop:
<template>
<!-- some not related content -->
<template v-if="order === 'fifth'">
<button class="card-flip__button card-flip__button--2"
v-b-modal.modalStandard="">
Sprawdź ofertę1
</button>
</template>
<template v-if="order === 'sixth'">
<button class="card-flip__button card-flip__button--2"
v-b-modal.modalPremium="">
Sprawdź ofertę2
</button>
</template>
<template v-if="order === 'seventh'">
<button class="card-flip__button card-flip__button--2"
v-b-modal.modalPremiumPlus="">
Sprawdź ofertę3
</button>
</template>
<modal-standard></modal-standard>
<modal-premium></modal-premium>
<modal-premium-plus></modal-premium-plus>
</template>
I'm using this template syntax to not create unnecessary divs.
And issue is that when I click some of this button it open correct modal but three times on top of previous ones.
I'm adding correct id's to <b-modal> inside those modal-* components.
This is done because each modal is rendered three times, one for each card-flip. You should also add v-if="order === 'fifth'" etc also for each modal in your card-flip template.