I currently have a datatable in vue with rows and columns. I am trying to make the row itself clickable instead of the toggle arrow on the left side of the table. But I am unable to find a proper solution so far. Could you please help me out with it??
I have posted my code below
template>
<div>
<PV-DataTable
:value="solutions"
sortMode="multiple"
stripedRows
selectionMode="single"
responsiveLayout="scroll"
v-model:expandedRows="expandedRows"
>
<template #empty> No solutions found </template>
<PV-Column :expander="true" headerStyle="width: 3rem" />
<PV-ColumnGroup type="header">
<PV-Row>
<PV-Column header=" " :rowspan="2" />
<PV-Column header="Solver" :rowspan="2" sortable />
<PV-Column header="Runtime" :colspan="3" sortable />
</PV-Row>
<PV-Row>
<PV-Column header="Total" :sortable="true" field="runtimeTotal" />
<PV-Column
header="Overhead"
:sortable="true"
field="runtimeOverhead"
/>
<PV-Column header="QPU" :sortable="true" field="runtimeQPU" />
</PV-Row>
</PV-ColumnGroup>
<PV-Column field="solution.solver" />
<PV-Column field="solution.runtime.total" />
<PV-Column field="solution.runtime.overhead" />
<PV-Column field="solution.runtime.qpu" />
<template #expansion="slotProps" >
<div class="solutions-subtable " >
<PV-DataTable
:value="getSampleWithEnergy(slotProps.data.solution)"
responsiveLayout="scroll"
selectionMode="single"
v-model:selection="selectedSample"
@rowSelect="onRowSelect"
>
<PV-ColumnGroup type="header" >
<PV-Row>
<PV-Column header="Sample" :rowspan="2"/>
<PV-Column header="Energy" :rowspan="2" />
</PV-Row>
</PV-ColumnGroup>
<PV-Column field="sample" />
<PV-Column field="energy" />
</PV-DataTable>
</div>
</template>
</PV-DataTable>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import axios from "@/api";
import type { Solution } from "@/types";
export default defineComponent({
props: {
optId: {
type: String,
default: "" as string,
},
},
data() {
return {
solutions: null,
expandedRows: [],
selectedSample: null,
};
},
mounted() {
this.fetchData();
},
methods: {
async fetchData() {
await axios
.get(`/api/optimizations/${this.optId}/solutions`)
.then((res: { data: any; }) => {
this.solutions = res.data;
})
.catch((e: { message: any; }) => {
console.error(e);
const content = {
severity: "error",
summary: "Solutions could not be loaded.",
detail: e.message,
life: 3000,
};
this.$emitter.emit("show-toast", content);
});
},
getSampleWithEnergy(solutionData: Solution) {
const samples = [];
for (let i = 0; i < solutionData.samples.length; i++) {
const sampleWithNums = solutionData.samples[i].map(function (
element: boolean
) {
return Number(element);
});
samples.push({
sample: sampleWithNums,
energy: solutionData.energies[i],
});
}
return samples;
},
onRowSelect(event: any) {
this.$toast.add({
severity: "info",
summary: "Sample Selected",
detail:
"Selected sample " +
event.data.sample +
". Check Solutions Tab for more details.",
life: 3000,
});
this.$emit("sampleSelected", this.selectedSample);
},
},
});
</script>
type here
I have tried going through the primevue datatable documentation but so far no use.
you can set a v-model:expandedRows
in DataTable, with this you can make an array of data that you want to expand and every row expand, add to this array and after collapse remove from this array.
so you can manipulate this array as you want.
you can change it when clicking on a row with @row-click
.
@row-click
pass you the data that you clicked on and the index of the row so that you can change expanded rows with this data.
here's an example of a situation in which you want only one row to expand:
<script setup lang="ts">
//? vue
import { ref } from 'vue'
//? components
import Column from 'primevue/column'
import DataTable from 'primevue/datatable'
//? Define and uses
const expandedRow = ref([])
//? End Define and uses
function setExpandedRow($event: DataTableRowClickEvent) {
// check if row expanded before click of not
const isExpanded = expandedRow.value.find((p) => p.id === $event.data.id)
if (isExpanded?.id) expandedRow.value = []
else expandedPlans.value = [$event.data]
}
</script>
<template>
<DataTable
v-model:expandedRows="expandedRow"
:value="yourData"
data-key="id"
:paginator="false"
@row-click="setExpandedRow"
>
<Column header="First Name" field="firstName" />
<Column header="Last Name" field="lastName" />
</DataTable>
</template>
and if you want to expand multirow you can push
and splice
the data that $event
pass and use its index
to find your data and remove it from the array.