I already installed dataTables using npm i dataTables --save, and now I can see the dataTable format in my vue component, the problem is the searchbar,paginations are not working well. See my screenshot
code in my component
<table class="table table-hover" id="myTable">
<thead>
<tr>
<th>Room Name</th>
<th>Building</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="room in roomsData" :key="room.id">
<td>{{room.room_desc}}</td>
<td>{{room.bldg}}</td>
<td>
<a href="#" data-toggle="modal" data-target="#exampleModal" #click="editModal(room)">
<i class="fa fa-edit"></i>
</a>
<a href="#" #click="deleteRoom(room.id)">
<i class="fa fa-trash text-red"></i>
</a>
</td>
</tr>
</tbody>
</table>
Methods
myTable(){
$(document).ready( function () {
$('#myTable').DataTable();
});
}
getRoomsDataTable(){
axios.get('/getRoomsDatatable')
.then((res) => {
this.roomsData = res.data
}) .catch((e) => {
console.log(e)
})
},
After you've instantiated data-tables, you can't update the data in it by updating the dom. You'll need to use the datatable api to trigger a refresh using the latest data.
In a mounted hook, instantiate dataTables and store the reference.
{
...
data() {
return {
dtRef: null
}
},
mounted() {
this.dtRef = $('#myTable').DataTable();
}
}
After that, clear & update the data once axios returns.
axios.get('/getRoomsDatatable')
.then((res) => {
this.roomsData = res.data
datatable.clear();
datatable.rows.add(res.data);
datatable.draw();
})
You'll need to fiddle with this a little bit, making sure your datatable is configured to correctly display the data.
Alternately, after the data has been fetched, you can destroy the datatable object and re-instantiate it, but you may experience a flash of content before the styling is readded.
Try to put only $('#myTable').DataTable(); inside the mounted hook as follows
methods:{
getRoomsDataTable(){
axios.get('/getRoomsDatatable')
.then((res) => {
this.roomsData = res.data
})
.catch((e) => {
console.log(e)
})
},
},
mounted(){
$('#myTable').DataTable();
}
Related
I referred to this link. It's the same way as mine.
Vuejs Ajax call and dataTable
(I'm using Vuejs and dataTable for one of my project. I make an Ajax call and push data into an array. After that I use v-for to loop the data in the tag.)
After creating Datatable, the table is displayed normally.
The problem is that v-for does not run normally when the list value in the data of vuejs changes.
The data expressed in v-for does not normally apply to html even if the statusList[] value changes!
js)
var tbapplyListApp = new Vue({
el: "#tbapplyList",
data: {
statusList: []
},
methods: {
getComregstList: function() {
var $this = this;
AjaxUtil.post({
url: GblVar.apiUrl + "/api/admin/regst/getRegstList",
param: {
...
},
reqType: "json",
success: function(res) {
console.log("----getComregstList");
$this.statusList = res.data;
},
finally: function(){
console.log("-----statusList changed!");
console.log($this.statusList);
$('#tbapplyListTable').DataTable().destroy();
$('#tbapplyListTable').DataTable( {
dom: 'Bfrtipl',
buttons: [
{
extend: 'excel',
text: 'DOWNLOAD'
}
]
});
}
});
},
},
mounted: function() {
this.getComregstList();
},
});
html)
<table id="tbapplyListTable" class="display">
<colgroup>
<col width="16%"/>
<col width="17%"/>
<col width="17%"/>
<col width="17%"/>
<col width="17%"/>
<col width="16%"/>
</colgroup>
<thead>
<tr>
<th>no</th>
<th>regstName</th>
<th>regstDt</th>
<th>regstStepName</th>
<th>mngName</th>
<th>confmTagStr</th>
</tr>
</thead>
<tbody>
<tr v-for="(status, index) in statusList" v-key="status.regstSeq" class="status_list">
<td v-text="statusList.length-index"></td>
<td v-text="status.regstName"></td>
<td v-text="status.regstDt"></td>
<td v-text="status.regstStepName"></td>
<td v-text="status.mngName"></td>
<td v-text="status.confmTagStr"></td>
</tr>
</tbody>
</table>
And AjaxUtil.post appears to be clear. (I'm calling the API normally and I'm importing data normally)
It would be great if I could get some help!
I changed the location and solved it.
success: function(res) {
$('#tbapplyListTable').DataTable().destroy();
$this.statusList = res.data;
},
finally: function(){
$('#tbapplyListTable').DataTable( {
...
I have a function which I am calling whenever a file is uploaded in order to refresh my table which holds the files.
The response.data is coming back with the correct data but my table is not reflecting it. Any idea what I could do in order to force update my table to show the new entries?
If I refresh the page, the data comes back correct.
function GetFileList(intID) {
//$("#fileuploadstbl").empty();
var ItemsVue = new Vue({
el: '#fileUploadContent',
data: {
items: []
},
mounted: function () {
var self = this;
axios.get("getUploads.ashx")
.then(response => {
self.items = response.data
}, function (err) {
console.log('error');
console.log(err.status);
console.log(err.response.status);
})
.catch(err => {
console.log('error');
console.log(err.status);
});
}
});
$("#fileUploadContent").show();
}
And this is how I bind my <tr>:
<tr
v-for="item in items" class="tddata"
v-bind:data-ID="item.ID"
v-bind:data-Uploadid="item.Uploadid"
>
<td>{{item.Filename}}</td>
<td
style="cursor: pointer;text-align:center;"
v-on:click="ViewFile(item.Filepath,item.Filename)"
>
View File
</td>
<td
style="cursor: pointer;text-align:center;"
v-on:click="DeleteFile(item.ID,item.guid,item.Filepath,item.Filename)"
>
View File
</td>
<td style="text-align:center;">{{item.UploadedBy}}</td>
</tr>
It will automatically update for your case. Maybe you can check is your response.data save in your "items". If still cannot, maybe try to use the forceupdate function
this.$forceUpdate();
This works for me
//HTML
<tr v-for="user in users" :key="user.id" v-bind="users_model">
//In your method
axios.get('sample-domain..com').then(response => {
this.users = response.data.data
this.users_model++
})
Can anyone help me about the best approach to add action button like edit, delete in each row in jquery data table?
I had gone through some links but didn't find a solution.
$(document).ready(function () {
$.ajax({
url: '#Url.Action("GetStudentGridData", "UserManagement")',
type: "GET",
dataType: 'json',
success: function (data) {
$('#student-datatable').DataTable({
data: data,
aoColumns: [
{ mData: "FirstName" },
{ mData: "Class" },
{ mData: "Roll" },
{ mData: "PresentAddress" },
{ mData: "BloodGroup" },
{ mData: "RegisterDate" },
{
mRender: function (data, type, full) {
return 'Edit';
}
}
]
});
},
error: function () {
alert("An error has occured!!!");
}
});
});
Here is the js code that I used to render data table. Each row has a student details and in my return 'data' object I had studentID property. I want to fetch data using that studentID when user click Edit button in a row.
Kindly help me about how to render edit and delete button and also how to handle them.
Solution :
I have tried a new approach. Instead of rendering column using datatable property I have added button in html
<table id="student-datatable" class="table table-striped table-bordered table-hover table-highlight table-checkable" cellspacing="0">
<thead>
<tr>
<th>Name</th>
<th>Class</th>
<th>Roll</th>
<th>PresentAddress</th>
<th>Blood Group</th>
<th>Register Date</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#{
foreach (var cl in Model)
{
<tr>
<td>#cl.FirstName #cl.LastName</td>
<td>#cl.Class</td>
<td>#cl.Roll</td>
<td>#cl.PresentAddress</td>
<td>#cl.BloodGroup</td>
<td>#cl.RegisterDate</td>
<td>
<div >
<button type="button" class="btn btn-default edit-student-btn" data-student-id="#cl.StudentID"><i class="fa fa-edit"></i></button>
<button type="button" class="btn btn-default"><i class="fa fa-trash"></i></button>
</div>
</td>
</tr>
}
}
</tbody>
Then I just call the jquery datatable method.
$(document).ready(function () {
$('#student-datatable').DataTable();
});
This give me nice output:
In this case, you have to use event delegation for elements added dynamically.
Event delegation allows us to attach a single event listener, to a
parent element, that will fire for all descendants matching a
selector, whether those descendants exist now or are added in the
future.
You should bind click event handler using .on() method.
$(document).on('click','.editUser',function(){
var studentID=$(this).closest('tr').find('td').eq(6).html();
});
Problem
I am making a Meteor.js app, and are importing .csv files via Papaparse.js, which I save in a Mongo collection for later use in a table. The data is saved in a standard Papaparse.js structure:
results = {
data: [ ... ], // parsed data
errors: [ ... ], // errors encountered
meta: { ... } // extra parse info
}
The data array looks like this (from Chrome console):
image
I output this in a front-end view, where this data is shown as a table. But sometimes, the data gets all unsorted. This often happens if I move the DB to another server or import the DB to local. Look at this image for a comparison: image
The question is why, and how I can fix it.
This is my table template:
(note that projectData.data is from Iron Router, which is the Papaparse data (results.data))
<template name="table">
<div class="table-responsive">
<table class="table table-striped table-hover sortable-theme-bootstrap table-fixedheader" data-sortable>
<thead>
<tr>
{{#each addStatusColToArray projectData.meta.fields}}
<th>{{this}}</th>
{{/each}}
<th class="data-controls-header"></th>
</tr>
</thead>
<tbody>
{{#each projectData.data}}
<tr>
{{#each tableObjectToKeyPairs this}}
<td class="{{key}}">
{{value}}
</td>
{{/each}}
<td class="data-controls">
<span class="glyphicon glyphicon-menu-right" aria-hidden="true"></span>
</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</template>
And this is the corresponding JS file:
Template.embedTable.helpers({
rowClassPropId: function (parentContext) {
var colLink = parentContext.projectData.meta.colLink;
var propId = this[colLink];
return propId;
},
tableObjectToKeyPairs: function (object) {
var filteredObject = _.omit(object, "_id"); // Omit the "_id" value
return _.map(filteredObject, function (value, key) {
return {
key: key,
value: value
};
});
}
});
Template.registerHelper("addStatusColToArray", function (array) {
if (array) {
array.push("Status"); // Pushes the "Status" last into array
return array; // Returns the modified array
}
});
Im trying to implement Vue.js + jQuery's DataTables but there's a weird things happening.
Check this fiddle on firefox (not working on chrome):
http://jsfiddle.net/chrislandeza/xgv8c01y/
when I change the state of DataTable (e.g. sort, search, etc.):
Newly added data on the list disappears
The DOM is not reading the directives or the vue properties
I'm pretty sure anyone who tried to mix vue.js+datatables experienced this problem. what did you do to solve this?
or is there a pure Vue.js script/plugin that has the same (or close) functionality like jquery's DataTable? (pagination, searching, sorting, number of entries to show, etc.).
here's the code from the fiddle above:
HTML:
<div class='container-fluid' id="app">
<div class='row'>
<div class='col-md-9'>
<table class="table table-bordered" id="app-datatable">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th></th>
</tr>
</thead>
<tbody>
<tr v-repeat="user: users">
<td>{{ user.name }}</td>
<td>{{ user.age }}</td>
<td>
<button type="button" v-on="click: foo(user)">Action</button>
</td>
</tr>
</tbody>
</table>
</div>
<div class='col-md-3'>
<div class="form-group">
<label>Name</label>
<input type="text"
class="form-control"
v-model="newUser.name"
>
</div>
<div class="form-group">
<label>Age</label>
<input type="name"
class="form-control"
v-model="newUser.age"
>
</div>
<button type="submit" class="btn btn-primary" v-on="click: addUser()">Add</button>
</div>
</div>
</div>
JavaScript:
$(document).ready(function () {
var dT = $('#app-datatable').DataTable();
});
var vm = new Vue({
el: '#app',
data: {
newUser: {},
users: [
{name: 'Chris', age: 1},
{name: 'John', age: 2}
]
},
methods:{
addUser: function(){
this.users.push(this.newUser);
this.newUser = {};
},
foo: function(user){
console.log(user.name);
}
}
});
any suggestions are greatly appreciated.
To get the DataTables plugin integrated correctly with Vue, there are a few things to keep in mind:
Per your example, you can use var dT = $('#app-datatable').DataTable(); to initialize the DataTables if you already have the data ready and rendered to the DOM. If you don't have the DOM <table></table> fully rendered (perhaps due to data populated via a delayed ajax call), you can't initialize the DataTables until the data is ready. As an example, if you have a fetchData method in your component, you can initialize the DataTable once the promise has been fulfilled.
To update the table once initialized, perhaps due to a change in the underlying table data, the best (perhaps the only way), is to first destroy the table, before the new data is received and written to the DOM by Vue:
var dT = $('#app-datatable').DataTable();
dT.destroy();
Then, once the data (in your case, the users array) has been updated,
re-initialize the DataTable as so:
this.$nextTick(function() {
$('#app-datatable').DataTable({
// DataTable options here...
});
})
The $nextTick is necessary to ensure Vue has flushed the new data to the DOM, before re-initializing. If the DOM is updated after the DataTable plugin has been initialized, you'll see the table data, but the usual sorting, paging, etc. won't work.
Another important point, is to have a row id in your dataset, and set the key in the <tr></tr>:
<tr v-repeat="user: users" track-by="id">
Without the track-by, Vue will complain when flushing new data to the DOM after DataTables has been initializing, likely due to not finding DOM elements hi-jacked by DataTables.
maybe you can use lifecycle hooks, infact these weird things are caused by competition of manipulating the DOM. in your vue instance, add a created() hook then initialize the DataTable, just like the following:
var vm = new Vue({
el: '#app',
data: {
newUser: {},
users: [
{name: 'Chris', age: 1},
{name: 'John', age: 2}
]
},
methods:{
addUser: function(){
this.users.push(this.newUser);
this.newUser = {};
},
foo: function(user){
console.log(user.name);
}
},
created(){
this.$nextTick(function() {
$('#app-datatable').DataTable();
})
}
});
I have externally supplied table data (not an Ajax call from DataTable) and destroying / re-creating the table using only these lifecycle hooks is working for me:
beforeUpdate: function() {
if (this.dataTable) {
this.dataTable.destroy()
}
},
updated: function() {
this.dataTable = $(this.$el).DataTable()
}
From https://alligator.io/vuejs/component-lifecycle/
"The beforeUpdate hook runs after data changes on your component and the update cycle begins, right before the DOM is patched and re-rendered. It allows you to get the new state of any reactive data on your component before it actually gets rendered."
"The updated hook runs after data changes on your component and the DOM re-renders. If you need to access the DOM after a property change, here is probably the safest place to do it."