How to reinitialize DT after updating DOM
How to reinitialize DT after updating DOM
mimo_2005
Posts: 4Questions: 2Answers: 0
The DOM and datatable initialized correctly but when updating DOM with new record pushed to the main array "items" or when updating the DT destroyed but not initialized again
<DataTable id="tableId" :options="dt_options" class="display nowrap" width="100%">
<thead>
<tr>
<th class="text-uppercase text-secondary text-xs font-weight-bolder opacity-7">name</th>
<th class="no-sort text-secondary opacity-7">actions</th>
</tr>
</thead>
<tbody>
<tr v-for="(branch, index) in items" :key="branch.id" >
<td>
<div class="d-flex px-2 py-1">
<div class="d-flex flex-column justify-content-center">
<h6 class="mb-0 text-sm" dir="ltr">{{branch.name}}</h6>
</div>
</div>
</td>
<td>
<div class="align-content-start float-start" style="margin-left: 60px">
<button type="button" class="btn-glass" @click.prevent="startUpdating(branch)">
<font-awesome-icon icon="pen-to-square" style="color: orange" size="xl" data-toggle="tooltip" title="edit branch"/>
</button>
</div>
</td>
</tr>
</tbody>
</DataTable>
</div>
</div>
</div>
</template>
<script>
import DataTable from "datatables.net-vue3";
export default {
name: "Branches",
props: ['branches'],
components: {DataTable},
created() {
this.items = this.branches;
},
data() {
return {
items: [],
editedItemIndex: null,
dt_options: {
select: false,
responsive: true,
lengthMenu: [5, 10, 25, 50],
columnDefs: [
{
targets: 'no-sort',
orderable: false,
}
]
}
};
},
mounted() {
this.freshDataTable();
},
beforeUpdate() {
this.refreshDataTable();
},
methods: {
push(newItem) {
this.items.unshift(newItem);
},
update(newUpdatedItem) {
if (this.editedItemIndex !== null) {
this.items.splice(this.editedItemIndex, 1, newUpdatedItem);
this.editedItemIndex = null;
}
},
clean(index) {
this.items.splice(index, 1);
},
freshDataTable() {
this.$nextTick(() => {
const table = $('#tableId');
if (!$.fn.dataTable.isDataTable(table)) {
table.DataTable(this.dt_options);
}
});
},
destroyDataTable() {
const table = $('#tableId');
if ($.fn.dataTable.isDataTable(table)) {
table.DataTable().clear();
table.DataTable().destroy(true); // Pass true to remove the table from the DOM
}
},
refreshDataTable() {
this.destroyDataTable();
this.freshDataTable();
}
}
};
</script>
This question has an accepted answers - jump to answer
Answers
Don't use
v-for
to populate the DataTable. It would mean that both Vue and DataTables are trying to control the same DOM element, which simply won't work.If you have a local array of data to want to show, you need to populate it using the
data
attribute - see the documentation here.I'll add a clear note to that page saying not to use
v-for
as there have been a number of posts with the same issue recently.Allan
I got it, and reformatted the component but I can't fire the call back function by the rendered button as following:
You need to use a slot if you are planning to have the button interact with the rest of the document through events.
Allan
@allan I'm trying to inject a component to the body of the table( without datatable with a normal table it works like expected but I don't know the trick to make it done in datatable):