Boolean display value in BootstrapVue and VueJS - vue.js

In my project I'm using BootstrapVue and VueJS. I'm currently doing a b-table and I have a boolean field in its fields. It displays correctly true and false, but I'd like to display something else (e.g. : Active for true and Inactive for false). I haven't found anything on how to do that (if there is something built-in, I haven't seen it in the docs).
Here is my current field declaration for the b-table of BootstrapVue :
table_fields: [
{ key: 'username', sortable: true },
{ key: 'firstName', sortable: true },
{ key: 'lastName', sortable: true },
{ key: 'isActive', sortable: true, label: 'Status'},
{ key: 'actions', label: 'Actions' }
]
The field that i'd like to change the behavior of is isActive.
Thanks in advance for your tips ! :)

I've found a way to do it, using what I could read HERE. Indeed it is possible to define custom slots.
Finally my field declaration looks like :
table_fields: [
{ key: 'username', sortable: true },
{ key: 'firstName', sortable: true },
{ key: 'lastName', sortable: true },
{ key: 'isActive', sortable: true, label: 'Status' },
{ key: 'actions', label: 'Actions' }
]
the little snippet for the custom slot :
<template v-slot:cell(isActive)="row">
<b-badge
v-if="row.item.isActive"
variant="success">
Active
</b-badge>
<b-badge
v-else
variant="warning">
Archived
</b-badge>
</template>
and my whole b-table :
<b-table
hover
:items="users"
:fields="table_fields">
<template v-slot:cell(isActive)="row">
<b-badge
v-if="row.item.isActive"
variant="success">
Active
</b-badge>
<b-badge
v-else
variant="warning">
Archived
</b-badge>
</template>
<template v-slot:cell(actions)="row">
<span v-if="row.item.isActive">
<b-button
to="#"
size="sm"
variant="primary"
class="mr-1"
title="Edit">
<font-awesome-icon :icon="['fas', 'pen']"/>
</b-button>
<b-button
#click="archiveUser(row.item.id)"
size="sm"
class="mr-1"
title="Archive">
<font-awesome-icon :icon="['fas', 'archive']"/>
</b-button>
</span>
<b-button
v-else
#click="unarchiveUser(row.item.id)"
variant="success"
size="sm"
class="mr-1"
title="Unarchive">
<font-awesome-icon :icon="['fas', 'caret-square-up']"/>
</b-button>
<b-button
#click="deleteUser(row.item.id)"
size="sm"
variant="danger"
class="mr-1"
title="Delete">
<font-awesome-icon :icon="['fas', 'trash-alt']"/>
</b-button>
</template>
</b-table>
and what it looks like :
You can see that in the column Status the b-badge is displayed instead of true or false

Related

Vue Element UI Select Option Bug

Element UI
I have fetch the data from backend and use it as select option which does not come with value object, but
when I try to select any item in select option, the select option show all item list selected, but the model value is correct
Follow Code Fetch the Bug
<el-option
v-for="item in options"
:key="item.key"
:label="item.label"
:value="item">
</el-option>
This was the Sample Bug I created...
https://codepen.io/JackarooNg/pen/qBRdqgO
The problem is with model name is matched with select option's property of key and label
Step 1: Script will be like
<script>
new Vue({
el: "#app",
data: function () {
return {
visible: false,
options: [
{
value: "Option1",
label: "Option1"
},
{
value: "Option2",
label: "Option2"
},
{
value: "Option3",
label: "Option3"
}
],
options1: [
{
value: "Option1",
label: "Option1"
},
{
value: "Option2",
label: "Option2"
},
{
value: "Option3",
label: "Option3"
}
],
value: "",
value1: ""
};
}
});
Step 2: HTML template will be
<div id="app">
<el-button #click="visible = true">Button</el-button>
<el-dialog :visible.sync="visible" title="Hello world">
<p>Try Element</p>
</el-dialog>
<el-select v-model="value" placeholder="Select">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item"
>
</el-option>
</el-select>
{{value}}
<el-select v-model="value1" placeholder="Select">
<el-option
v-for="item in options1"
:key="item.value"
:label="item.label"
:value="item"
>
</el-option>
</el-select>
{{value1}}
</div>
DEMO

Bootstrap Vue table select

When I try with the below data, I get the first column as true/false instead of a checkbox.
Here is the vue table:
<b-table id="myTabel" hover striped :items="tableData" :fields="tableColumns">
<template slot="selected" slot-scope="row">
<b-form-group>
<input type="checkbox" v-model="row.item.selected" />
</b-form-group>
</template>
</b-table>
Here is the my table data:
tableData: [{
title: "title01",
desc: "desc01",
selected: false
},
{
title: "title02",
desc: "desc02",
selected: true
}
],
tableColumns: [{
key: "selected",
label: "",
sortable: false
},
{
key: "title",
label: "Title",
sortable: false
},
{
key: "desc",
label: "Description",
sortable: false
}
]
Change your template to:
<template v-slot:cell(selected)="data">
<b-form-group>
<input type="checkbox" v-model="data.item.selected" />
</b-form-group>
</template>
https://jsfiddle.net/ellisdod/wvLjhmou/
see custom data rendering

bootstrap vue get row data when click on cell in custom rendering

I have a table that have two custom fields index and a trash icon in separate column for remove that row. I want to get row's in click on just trash icon (on cell) for get index of row and then remove it from items in data object but my problem is I don't know how to get row data in onclick event in custom rendering. How can I do that??
<b-table :fields="fields" :items="items">
<template v-slot:cell(index)="data">
{{ data.index + 1 }}
</template>
<template v-slot:cell(remove)="data">
<i class="fas fa-trash"></i>
</template>
</b-table>
this is my data:
fields: [
{ key: 'index', label: 'index' },
{ key: 'cardNumber',label: 'card number'},
{ key: 'status',label: 'status'},
{ key: 'remove',label: 'remove'}
],
items: [
{ cardNumber: '123456', status: 'accepted' ,_cellVariants: { status: 'accepted-card-number'},_showDetails: true},
{ cardNumber: '123456', status: 'pending' ,_cellVariants: { status: 'pending-card-number'},_showDetails: true},
{ cardNumber: '123456', status: 'unaccepted' ,_cellVariants: { status: 'unAccepted-card-number'},_showDetails: true},
],
This should be what your looking for https://jsfiddle.net/q95otzbg/. You just need a click function on your trash icon passing it the index of the row.
<div id="app">
<div>
<b-table :fields="fields" :items="items">
<template v-slot:cell(index)="data">
{{ data.index + 1 }}
</template>
<template v-slot:cell(remove)="data">
<i class="fas fa-trash" #click=removeRow(data.index)></i>
</template>
</b-table>
</div>
</div>
methods: {
removeRow(index) {
this.items.splice(index,1)
}
}

Vue-bootstrap - when table changes items, buttons do not seem be to updated

I started using vue-bootstrap to generate a table with items. One of the columns "actions" contains button to show, edit and enable/disable the item (changing active property to true/false) based on item ID.
When I disable an item (click the button disable), the table is updated and does not show it anymore, however it looks like the buttons (show/edit/disable/enable) for that particular item stop working (e.g. not able to enable the project back or to edit it). Also the first item in the table does not have the buttons functional.
Item example:
{ id: '1', key: 'key1', name: 'name1', description: 'description1', active: 'true' }
Any idea what could be wrong?
<b-row class="mb-3">
<b-col cols="12">
<b-navbar type="light" variant="light">
<b-nav-form>
<i class="fas fa-search mr-3"></i>
<b-input-group>
<b-form-input v-model="filter" id="filterInput" placeholder="Search" ></b-form-input>
<b-input-group-append>
<b-button :disabled="!filter" #click="filter = ''" class="mr-sm-3">Clear</b-button>
</b-input-group-append>
</b-input-group>
<b-form-checkbox v-model="archivedChecked" size="sm">
Archived
</b-form-checkbox>
</b-nav-form>
</b-navbar>
</b-col>
</b-row>
<b-row>
<b-col cols="12">
<b-table bordered hover head-variant="dark" :filter="filter" :items="filteredProjects" :fields="fields">
<template v-slot:cell(actions)="row">
<b-button-group>
<b-button size="sm" variant="info" :to="'/msd/' + row.item.key" title="Show">Show</b-button>
<b-button v-b-modal="'edit-project-' + row.item.id" size="sm" variant="outline-info" :title="'Edit ' + row.item.name">
<i class="far fa-edit"></i>
</b-button>
<b-button v-if="!archivedChecked" v-b-modal="'disable-project-' + row.item.id" size="sm" variant="outline-secondary" title="Archive">
<i class="fas fa-archive"></i>
</b-button>
<b-button v-if="archivedChecked" v-b-modal="'enable-project-' + row.item.id" size="sm" variant="outline-secondary" title="Restore">
<i class="fas fa-trash-restore"></i>
</b-button>
<edit-project-modal :modal_id="'edit-project-' + row.item.id" :id="row.item.id" />
<disable-project-modal :modal_id="'disable-project-' + row.item.id" :id="row.item.id"/>
<enable-project-modal :modal_id="'enable-project-' + row.item.id" :id="row.item.id"/>
</b-button-group>
</template>
</b-table>
</b-col>
</b-row>
</div>
</template>
<script>
import EditProject from '~/components/modal/EditProject.vue'
import DisableProject from '~/components/modal/DisableProject.vue'
import EnableProject from '~/components/modal/EnableProject.vue'
import { mapGetters } from 'vuex'
export default {
layout: 'IncludeSidebar',
data() {
return {
fields: [
{
key: 'key',
sortable: false
},
{
key: 'name',
sortable: true
},
{
key: 'description',
sortable: true
},
{
key: 'actions',
sortable: false
}
],
archivedChecked: false,
filter: null
}
},
computed: {
loadedProjects() {
return this.$store.getters.loadedProjects;
},
filteredProjects() {
if (this.archivedChecked) {
return this.loadedProjects.filter(item => item.active === false)
} else {
return this.loadedProjects.filter(item => item.active === true)
}
}
},
methods: {
},
components: {
NewProjectModal: NewProject,
EditProjectModal: EditProject,
DisableProjectModal: DisableProject,
EnableProjectModal: EnableProject
}
}
</script>
Instead of calling the modals directly from buttons, I moved the trigger to a method and it solved the issue.
<b-button v-if="row.item.active" #click="showModal('disable-project-' + row.item.id)" size="sm" variant="outline-secondary" title="Archive">
methods: {
showModal(type, modal_id) {
this.$root.$emit('bv::show::modal', modal_id);
}
}

bootstrap-vue datatable show row details issue

trying to achieve the same result as https://bootstrap-vue.js.org/docs/components/table#row-details-support
My code:
<b-table ref="propertydata" striped hover
:items="datatable.items"
:fields="datatable.fields"
:current-page="datatable.currentPage"
:per-page="datatable.perPage"
:filter="datatable.filter"
:sort-by.sync="datatable.sortBy"
:sort-desc.sync="datatable.sortDesc"
:sort-direction="datatable.sortDirection"
#filtered="onFiltered">
<template slot="action" slot-scope="row">
<!-- we use #click.stop here to prevent emitting of a 'row-clicked' event -->
<b-button size="sm" #click.stop="row.toggleDetails" class="mr-2">
{{ row.detailsShowing ? 'Hide' : 'Show'}} Details
</b-button>
</template>
<template slot="row-details" slot-scope="row">
<b-card>
<ul>
<li v-for="(value, key) in row.item" :key="key">{{ key }}: {{ value}}</li>
</ul>
</b-card>
</template>
</b-table>
<b-row>
<b-col md="6" class="my-1">
<b-pagination :total-rows="datatable.totalRows" :per-page="datatable.perPage" v-model="datatable.currentPage" class="my-0" />
</b-col>
</b-row>
/* Datatable related */
datatable: {
fields: [
{
key: 'account_id',
sortable: true
},
{
key: 'account_name',
sortable: true
},
{
key: 'property_count',
sortable: true,
},
{
key: 'commission',
sortable: true,
variant: 'success'
},
{
key: 'action',
}
],
items: [],
currentPage: 1,
perPage: 20,
totalRows: 0,
pageOptions: [ 20, 100, 300, 500, 1000, 2000, 3000 ],
sortBy: null,
sortDesc: false,
sortDirection: 'asc',
filter: null
}
computed: {
sortOptions () {
// Create an options list from our fields
return this.datatable.fields
.filter(f => f.sortable)
.map(f => { return { text: f.label, value: f.key } })
}
}, // END COMPUTED
methods: {
onFiltered (filteredItems) {
// Trigger pagination to update the number of buttons/pages due to filtering
this.datatable.totalRows = filteredItems.length
this.datatable.currentPage = 1
}
}, // END METHODS
The result is:
As you can see, the show details is isolated to a single column instead of the full row.
What I want to achieve is for this show details section to be the full row width and if I could click the button to go to a method to call additional data to be displayed here as oppose to the native bootstrap-vue functionality.