How to reinitialize DT after updating DOM
How to reinitialize DT after updating DOM

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):