How to add dynamic button for each row in quasar table - vue.js

I am trying to add buttons for table rows without using a slot. I am trying to push buttons in the column I am sharing bellow:
const columns = [
{
name: 'name',
required: true,
label: 'Member No.',
align: 'left',
field: row => row.name,
format: val => `${val}`,
sortable: true
},
{ name: 'short_name', align: 'left', label: 'Short Name', field: 'short_name',
sortable:true},
{ name: 'address', align: 'left', label: 'Address', field: 'address', sortable:true},
{ name: 'ward_count', align: 'left', label: 'Ward No', field: 'ward_count', sortable:true},
{ name: 'bed_count', align: 'left', label: 'Bed No', field: 'bed_count'},
{ name: 'entry_by', align: 'left', label: 'Entry By', field: 'entry_by'}
]
From Template :
<q-table
title="Treats"
:rows="rows"
:columns="columns"
row-key="id"
v-model:pagination="pagination"
:loading="loading"
:filter="filter"
#request="onRequest"
binary-state-sort
>
<template v-slot:top-right>
<q-input borderless dense debounce="300" v-model="filter"
placeholder="Search">
<template v-slot:append>
<q-icon name="search" />
</template>
</q-input>
</template>
</q-table>
These buttons should pass current row id as well.

Here is some sample code from my project, this is how i do it.. let me know if you need more details..
<q-table row-key="id" title :rows="arrData" :columns="arrColumns"
v-model:pagination="pagination" :filter="filter" #request="request" binary-state-sort separator="cell" class="tableStyle outline">
<template v-slot:body-cell-your_button_column_name="props">
<q-td :props="props">
<q-btn round unelevated color="red" #click="onButtonClick(props.row.id)" label="Your Button Label"></q-btn>
</q-td>
</template>
</q-table>

Related

Vuejs 3 using i18n translation inside "script setup>

I have a Laravel + Inertiajs + Vue 3 with Vite
I user Quasar framework so in one vue file I have a Quasar table.
Now I need to translate the column labels.
<template>
<head title="Elenco utenti"></head>
<AuthenticatedLayout>
<template #header>
<div>
<q-toolbar class="q-gutter-sm">
<Link :href="route('list-utenti')" type="button" class="float-right"><q-btn flat round dense icon="people" /></Link>
<div class="text-subtitle1">{{ $t('utenti.pagetitle')}}</div>
</q-toolbar>
</div>
</template>
<div class="q-py-md q-gutter-sm">
<Link :href="route('register')" type="button" class="float-right"><q-btn icon="add_box" color="white" text-color="text-grey-7" :label="$t('utenti.btn_new')"></q-btn></Link>
</div>
<div class="q-py-xl">
<q-table
title=""
:rows="users"
:columns="columns"
row-key="id"
>
<template v-slot:body-cell-actions="props">
<q-td :props="props">
<q-btn icon="mode_edit" #click="onEdit(props.row)"></q-btn>
<q-btn icon="person_off" #click="onDelete(props.row)"></q-btn>
</q-td>
</template>
<template v-slot:body-cell-email="props">
<q-td :props="props">
<strong>{{ props.value }} </strong>
</q-td>
</template>
</q-table>
</div>
</AuthenticatedLayout>
</template>
As you can see in the template code, I configured i18n and I can correctly translate with {{ $t('utenti.pagetitle') }} when in template.
now this is the script part
<script setup>
import AuthenticatedLayout from '#/Layouts/AuthenticatedLayout.vue';
import { Inertia } from '#inertiajs/inertia';
import { Link } from '#inertiajs/inertia-vue3';
import { computed, ref} from '#vue/reactivity';
import { Quasar, useQuasar } from 'quasar';
const props = defineProps({
page_description : String,
title: String,
numero_record: Number,
users: Array
});
const columns = [
{
name: 'id',
required: true,
label: 'id',
align: 'left',
field: row => row.id,
format: val => `${val}`,
sortable: false
},
{ name: 'name', align: 'left', label: translated_name, field: 'name', sortable: true},
{ name: 'email', align: 'left', label: 'e-mail', field: 'email', sortable: false},
{ name: 'ruolo', align: 'left', label: 'ruolo', field: 'ruolo', sortable: true},
{ name: 'listino_grossista_visible', align: 'center', label: 'list. grossista', field: 'listino_grossista_visible', sortable: true},
{ name: 'enabled', align: 'center', label: 'Attivo', field: 'enabled', sortable: true},
{ name: 'actions', align: 'center', label: 'Azioni'}
]
const onEdit = (row) => {
Inertia.post(route('edit-utente'),
{ row } ,
{ onBefore: () => confirm('Vuoi veramente modificarlo?')}
)
}
const onDelete = (row) => {
alert('DELETE ' + row.email);
}
</script>
I would like to use in some way $t to get the correct translation for the grid columns labels (for example 'translated_name' but I don' understand how I can do it as it is in the script part and I can not use same as in template.
I probably understood that I need to add some computed properties but I didn't exactly figured out how. Consider I'm using composition api.
const translated_name = computed(() => {
return $t('utenti.nome')
})
I checked also this link Vue-i18n not translating inside component script tags but I didn't understood how to adapt to my case.
kind regards,
Matt

Checkbox in a table using Quasar

Im trying to insert a checkbox column using quasar. The way I did, it only appears as the first element of the table, and I want it as the second element. How do I do this?
Example:
export default {
name: 'DespesasGeraisBKOOnline',
data() {
return{
columns: [
{
name: 'acoes',
label: 'Ações',
field: (row) => row.acoes,
sortable: true,
align: 'center',
},
{
name: 'pc',
align: 'center',
label: 'PC ',
sortable: false,
},
{
name: 'criada_em',
label: 'Criada em',
field: (row) => row.criada_em,
sortable: true,
align: 'center',
},
{
name: 'nome',
label: 'Nome',
field: (row) => row.nome,
sortable: true,
align: 'center',
},
}
}
<q-table
:data="data"
:columns="columns"
row-key="id"
selection="multiple"
class="default-table q-mt-xs"
>
<template v-slot:no-data="{}">
<div class="full-width row flex-center no-data-finded q-gutter-sm">
<span>
{{ loading ? 'Carregando...' : 'Nenhuma despesa encontrada.' }}
</span>
</div>
</template>
</q-table>
If you run the code, you can see that the first column is the "checkbox". However, I want this as the second column.
<template v-slot:body="props">
<q-tr :props="props">
<q-td key="text" :props="props">{{ props.row.title }}</q-td>
<q-td key="radio" :props="props"><q-radio v-model="input" :label="props.row.label" /></q-td>
<q-td key="checkbox" :props="props"><q-checkbox v-model="input" :label="props.row.label" /></q-td>
<q-td key="button" :props="props"><q-btn label="btn" #click="method"/></q-td>
</q-tr>
</template>
This is the way i usually define table if i want to insert any form control peacefully within any column

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

How to combine an Expandable Table with an Expansion Panel in Vuetify?

I'd like to combine two separate Vuetify functionalities into one:
https://vuetifyjs.com/en/components/data-tables --> Expandable Rows Table (but ideally with more than one data row upon expansion)
https://vuetifyjs.com/en/components/expansion-panels --> External Control Expansion Panel
Ultimately, the goal is to have a table that looks like this (Grouping Table with expand/collapse all one): https://codepen.io/lzhoucs/pen/aadaJx
The issue with this table is that despite fitting the code into my project, certain functionalities don't work -- such as clicking to open and close a table. I believe this is due to this being a different version of Vue than what I'm using, which is the most up to date, as I spotted some old styles.
I've tried a bunch of things, but my most successful attempt is creating a table within a table. Here is the code for that:
<template>
<v-container>
<v-data-table
:headers="headers"
:items="projects"
:expanded="expanded"
item-key="name"
show-expand
class="elevation-1"
#click:row="clicked"
>
<template v-slot:expanded-item="{ headers }">
<td :colspan="headers.length">
<v-data-table
:headers="peopleHeaders"
:items="people"
item-key='name'
hide-default-footer
class='elevation-1'>
<template slot="item" slot-scope="props">
<tr>
<td>{{props.item.name}}</td>
<td>{{props.item.major}}</td>
<td>{{props.item.preference}}</td>
<td>
<v-btn color='success'>Accept</v-btn>
<v-btn color='error'>Reject</v-btn>
</td>
</tr>
</template>
</v-data-table>
</td>
</template>
</v-data-table>
</v-container>
</template>
<script>
export default {
data() {
return {
expanded: [],
headers: [
{
text: 'Name',
align: 'left',
sortable: true,
value: 'name',
},
{ text: 'Status', value: 'Status' },
],
projects: [
{
name: '#this is the project they applied to',
Status: 'Status: Pending',
},
],
peopleHeaders: [
{
text: 'Name',
align: 'left',
sortable: true,
value: 'name',
},
{
text: 'Major',
align: 'left',
sortable: true,
value: 'major',
},
{
text: 'Preference',
align: 'left',
sortable: true,
value: 'preference',
},
],
people: [
{
name: 'BORB',
major: 'SWE',
preference: 'idk',
},
],
};
},
methods: {
clicked(value) {
this.expanded.push(value);
},
},
};
</script>
Any advice for how to combine the two features to achieve the table desired would be greatly appreciated.

How to target specific vue table element?

I'm setting up a list that fetches from a database and displays a list of orders. onclick of the button, I would like to show the stars-rating div only in the row it was clicked on. How do I make a vue button trigger the appearance of a div only in the row that it is in.
I've tried using v-on:click= function to call another function in js but didn't seem to work. Here both templates are contained in
<div id="wrapper">
<v-toolbar flat color="white">
<v-toolbar-title style="font-family: 'Raleway', sans-serif;">Order
History</v-toolbar-title>
<v-spacer></v-spacer>
<d style="margin-right:20px;color:#a7a7a7;font-family: 'Raleway',
sans-serif;">click on an order for more information</d>
</v-toolbar>
<v-data-table
:headers="headers"
:items="orders"
:expand="expand"
item-key="number"
>
<template v-slot:items="props">
<tr #click="props.expanded = !props.expanded">
<!--trigger using this button--> <td class="text-xs-left" style='font-
weight:400;'><v-btn v-on:click="greet"
class="dark">{{ props.item.review }}</v-btn>
</td>
</tr>
</template>
<template v-slot:expand="props" style="font-
weight:500">
<v-data-table
:items="[props.item]"
:expand="expand"
item-key="name"
hide-actions
>
<template v-slot:headers="props">
</template>
<template v-slot:items="props">
<td width="15%" class="text-xs-left"
style='font-weight:300;'>
<!--trigger this div --> <div class="star-rating"></div>
</td>
</template>
</v-data-table>
</template>
</v-data-table>
</div>
//JS
var v = new Vue({
el: '#app',
methods: {
greet: function () {
$(".stars-rating").hide();
}
},
data() {
return {
expand: true,
headers: [
{
text: 'Order Number',
align: 'left',
sortable: false,
value: 'number',
width: '10%' },
{ text: 'Name/Message', value: 'name',
align: 'left',
width: '15%' },
{ text: 'Date/Start', value: 'date',
align: 'left',
width: '10%' },
{ text: 'Time/End', value: 'time',
align: 'left',
width: '10%' },
{ text: 'Provider/Receipts', value: 'provider',
align: 'left',
width: '10%' },
{ text: 'Amount/Labor', value: 'amount',
align: 'left',
width: '15%' },
{ text: 'Status/Tracking', value: 'status',
align: 'left',
width: '15%' },
{ text: 'Confirmation/Review', value: 'review',
align: 'left',
width: '15%' }],
orders: [],
};
} });
have you tried with
<div class="star-rating" v-if="props.expanded"></div>
First of all, you should remove the #click from your <tr #click="props.expanded = !props.expanded"> element.
In your greet function, you have to change the expand flag, something like:
greet: function () {
this.expand = false
}
As you are already biding the expand state with the v-data-table expand prop, it should work
<v-data-table
:headers="headers"
:items="orders"
:expand="expand"
item-key="number"
>