I'm using datatables and bootstrap for pagination but its not working.
The data is received via ajax ,as soon as i press any header to sort the table, the data dissappears.
The html for table itself
<table id="tablePersonnel"
class="table table-striped table-bordered table-sm" cellspacing="0"
width="100%">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>First Name</th>
<th>Phone number</th>
<th>Status</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tfoot>
<tr>
<th>#</th>
<th>Name</th>
<th>First Name</th>
<th>Phone number</th>
<th>Status</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</tfoot>
</table>
here is the javascript for the function responsible for getting the data
refreshTable = function() {
$
.ajax({
url : "listPersonnel",
dataType : 'json',
success : function(response) {
data = response;
var no = 1;
for (i = 0; i < data.length; i++) {
$("#tablePersonnel")
.append(
'<tr> <td>'
+ data[i].id
+ '</td> <td>'
+ data[i].firstname
+ '</td> <td>'
+ data[i].name
+ '</td> <td>'
+ data[i].phone
+ '</td> <td>'
+ data[i].status
+ '</td><td><input type="button" class="btn1" onclick="openEditPopup('
+ i
+ ')" value="Edit"></input></td> <td> <button type="submit" class="btn" onclick="openDeletePopup('
+ i
+ ');" value=""><i class="fa fa-trash"></i></button></td> </tr>');
no = no + 1;
}
}
});
}
Any help is greatly appreciated.
Your approach involves adding data to the HTML table (i.e. to the DOM). However, the DataTables object does not know about this data - which is why the data disappears whenever you perform any action which involves a DataTables refresh. DataTables is showing you its data - which is no data.
Instead, you can perform your ajax call from within DataTables itself - and then DataTables will handle the data for you.
I will assume the JSON returned by your ajax call has the following structure:
[
{
"id": 123,
"firstname": "Tom",
"name": "Smith",
"phone": "121-212-1212",
"status": "foo"
},
{
"id": 123,
"firstname": "Jane",
"name": "Jones",
"phone": "434-545=6767",
"status": "bar"
}
]
In that case, you can use the following table HTML:
<table id="example">
<thead>
<tr>
<th>ID</th>
<th>First Name</th>
<th>Name</th>
<th>Phone</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
</table>
And your DataTable configuration will be this:
<script type="text/javascript">
$(document).ready(function() {
$('#example').DataTable( {
"ajax": {
"url": "listPersonnel",
"dataSrc": ''
},
"columns": [
{ "data": "id" },
{ "data": "firstname" },
{ "data": "name" },
{ "data": "phone" },
{ "data": "status" },
{ "data": function ( row, type, val, meta ) {
var content = '<input type="button" class="btn1" onclick="openEditPopup('
+ row.id
+ ')" value="Edit"></input></td> <td> <button type="submit" class="btn" onclick="openDeletePopup('
+ row.id
+ ');" value=""><i class="fa fa-trash">trash</i></button>'
return content;
} }
]
} );
} );
</script>
The result looks like this (I don't have your trash icon):
Points to note:
There is no iteration logic here - it's handled for you by DataTables, as it consumes your JSON response.
If your JSON has a different structure, you will need to adjust the above. Examples of different approaches are shown here.
In your case, we use dataSrc = '' because your JSON is an array of objects - and it does not have a container object.
The data in the final column is generated via a function which builds the string you need.
You can define column headings directly in DataTable also, instead of in the HTML.
There are many variations on this approach - DataTables has a lot of flexibility.
Related
everything works fine. The only issue that i cannot fix/find is how to create a button and set the value of data: cvpdf inside a href of a button to open the cv
The cvpdf is the file name of a cv stored in the database.
<table id="dtBasicExample" class="table table-striped custom-table mb-0 datatable " >
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>surname</th>
<th>email</th>
<th>position</th>
<th>CV</th>
</tr>
</thead>
<tbody id="atn-tbody">
</tbody>
</table>
function showInformation(str) {
console.log(str);
$("#dtBasicExample").dataTable().fnDestroy();
$(document).ready(function(){
$("#dtBasicExample").dataTable({
scrollX: true,
"ajax":{
url: "data.php?q="+str ,
dataSrc:"",
},
"columns":[
{"data": "id"},
{"data": "name"},
{"data": "surname"},
{"data": "email"},
{"data": "position"},
{"data": "cvpdf"},
]
});
});
};
Let me help you out with this. you can apply this to any column data
columns: [
{
data: function(row){
return `Click This`
}
}
]
the "row" parameter will return the whole data for the current row, so you can access the object through the "row.your_key".
this is the best practice to make your code simpler.
the complete parameter can be accessed through This Link
Hope it can help!
i have created vue file to display data in frontend. but i'm unable to print 2 tables on same page at same time. only table 2 is displaying data , in first table it shows data for 2 seconds and than disappears. what i'm doing wrong? please help. i am super new in vuejs and have not much knowledge.
here is my index.vue file,
Table 1
<tbody>
<tr
v-show="items && items.length"
v-for="(data, i) in items"
:key="i">
<td></td>
<td></td>
</tr>
and this is function code,
async fetchData1() {
this.$store.state.operations.loading = true;
let currentPage = this.pagination ? this.pagination.current_page : 1;
await this.$store.dispatch("operations/fetchData", {
path: "/api/calldata?page=",
currentPage: currentPage + "&perPage=" + this.perPage,
});
table 2
<tbody>
<tr
v-show="items && items.length"
v-for="(data, i) in items"
:key="i">
<td></td>
<td></td>
</tr>
and here is the function for table 2
async fetchData2() {
this.Loading2 = true
let currentPage = this.Pagination2 ? this.Pagination2.current_page : 1;
await this.$store.dispatch("operations/fetchData", {
path: "/api/datacall/data2?page=",
currentPage: currentPage + "&perPage=" + this.perPage,
});
this.Loading2 = false;
and this are the controller functions
public function index(Request $request)
{
return DataResource::collection(Datamodl::with('user')->where('type',1)->latest()->paginate($request->perPage));
}
public function index2(Request $request)
{
return DataResource::collection(Datamodl::with('user')->where('type',0)->latest()->paginate($request->perPage));
}
And Route ,
Route::get('/calldata/data2', [DataController::class, 'index2']);
Route::apiResource('calldata', DataController::class);
Observation : You are updating same variable which is items for both the tables. Hence, it is overriding the latest items with the old items array.
Solution : Here is the implementation as per my comment.
new Vue({
el: '#app',
data: {
table1Items: null,
table2Items: null
},
mounted() {
this.fetchData1();
this.fetchData2();
},
methods: {
fetchData1() {
this.table1Items = [{
id: 1,
name: 'table 1 alpha'
}, {
id: 2,
name: 'table 1 beta'
}]
},
fetchData2() {
this.table2Items = [{
id: 1,
name: 'table 2 alpha'
}, {
id: 2,
name: 'table 2 beta'
}]
}
}
})
table, th, td {
border: 1px solid black;
margin: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<table>
<thead>
<th>ID</th>
<th>Name</th>
</thead>
<tbody>
<tr v-show="table1Items" v-for="(data, i) in table1Items" :key="i">
<td>{{ data.id }}</td>
<td>{{ data.name }}</td>
</tr>
</tbody>
</table>
<table>
<thead>
<th>ID</th>
<th>Name</th>
</thead>
<tbody>
<tr v-show="table2Items" v-for="(data, i) in table2Items" :key="i">
<td>{{ data.id }}</td>
<td>{{ data.name }}</td>
</tr>
</tbody>
</table>
</div>
you are using same property which is items for both. so second request will changed first items. so in both table same data will visible. you have to store in different state property for different data rendering.
solution :
make another action fetchData2.
call another mutation setItems2. add state propery item2: []. and setItems2 value from this mutation.
render second table like this.
<tr
v-show="items2.length"
v-for="(data, i) in items2"
:key="i">
<td></td>
<td></td>
</tr>
For code quailty:
give proper and related variable name . don't use items1 and items2 like that.
never used v-if/v-show and v-for in same element.for more info
use template first in this senerio.
use the item's unique id instead of the index in the key.
if you take the items default value as [], instead of null, then you only required to check items.length instead of items && items.length. so always use list default value []
if both requests are not dependent on each other then you should use Promise.all() for fetching data concurrently. which saved tremendous time and also in this case you don't require two loading property.
I want to filter the data and managed to do it. However, when I clicked filter, my datatable headers are missing but I couldnt figure out what the problem is.
My blade is:
<table id="table_data" class=" table-responsive table-striped table-hover table-bordered ">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">First Name</th>
<th scope="col">Last Name</th>
</tr>
</thead>
</table>
Filter function:
$('#filter').click(function(){
var table = $('#table_data').DataTable();
var name= $('#name').val();
var age= $('#age').val();
var gender= $('#gender').val();
if( $.fn.DataTable.isDataTable('#table_data')){
table.destroy();
$('#table_data').empty();
var dataTable = $('#table_data').DataTable({
processing: false,
serverSide: false,
ajax:{
url:'/filter-result',
data:{name:name, age:age,gender:gender}
},
columns: [
{
data:'id',
name:'id'
},
{
data:'First_name',
name:'First_name'
},
{
data:'Last_name',
name:'Last_name'
}
]
});
}
});
What is the reasons the header missing after clicked?
I want to send array of id's to backend with one button from vuejs table but i get error 500.
Logic
Check the check boxes
Collect the id's
Send id's to back-end when click on button
update the view
Code
template
<table class="table table-dark table-hover table-bordered table-striped">
<thead>
<tr>
<th class="text-center" width="50">
//the button
<button class="btn btn-outline-danger" #click="withdraw(index)">Withdraw</button>
</th>
<th class="text-center" width="50">#</th>
<th class="text-center">Amount</th>
</tr>
</thead>
<tbody>
<tr v-for="(income,index) in incomes" v-bind:key="index">
<td class="text-center">
//check box input
<input v-if="income.withdraw == '0'" type="checkbox" :id="income.id" :value="income.amount" v-model="checkedNumbers">
</td>
<td class="text-center">{{index+1}}</td>
<td class="text-center">Rp. {{formatPrice(income.amount)}}</td>
</tr>
<tr>
<td colspan="2"></td>
<td>
<span>Withdraw for today, Sum: <br> Rp. {{ formatPrice(sum) }}</span>
</td>
</tr>
</tbody>
</table>
script
export default {
data() {
return {
incomes: [],
checkedNumbers: [],
}
},
computed: {
sum() {
return this.checkedNumbers.reduce(function (a, b) {
return parseInt(a) + parseInt(b);
}, 0);
}
},
methods: {
withdraw(index) {
let checkedids = this.incomes[index]
axios.post(`/api/withdrawbutton/`+checkedids).then(response => {
this.income[index].withdraw = '1'
this.$forceUpdate()
});
}
}
}
route
Route::post('withdrawbutton/{id}', 'IncomeController#withdrawbutton');
controller
public function withdrawbutton($id)
{
$dowithdraw = Income::where('id', $id)->get();
$dowithdraw->withdraw = '1';
$dowithdraw->save();
return response()->json($dowithdraw,200);
}
Any idea where is my mistake and how to fix it?
......................................................................................................................
Don't send the list as a GET parameter, send it as a POST:
let params = {}
params.ids = this.checkedNumbers
axios.post(`/api/withdrawbutton/`, params)
.then(response => {
this.income[index].withdraw = '1'
this.$forceUpdate()
});
Controller
public function withdrawbutton(Request $request)
{
$dowithdraws = Income::whereIn('id', $request->input('ids', []));
$dowithdraws->update(['withdraw' => '1']);
return response()->json($dowithdraws->get(), 200);
}
Route
Route::post('withdrawbutton/', 'IncomeController#withdrawbutton');
And I don't think you need to update anything in the front because you already have them checked (if you want to keep them checked)
I have used ignited datable to integrate it in codeigniter but getting following error : DataTables warning: table id=example2 - Requested unknown parameter '0' for row 0.
$(document).ready(function() {
$('#example2').dataTable( {
"bProcessing": true,
"bServerSide": true,
"sServerMethod": "POST",
"sAjaxSource": "<?php echo base_url()?>auth/datatable"
} );
} );
Here is my html
<table id="example2" class="table table-bordered table-striped">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Class</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
here is the json generated
{"draw":0,"recordsTotal":2,"recordsFiltered":2,"data":[{"email":"admin#admin.com","first_name":"Admin","last_name":"istrator"},{"email":"subhadeepgayen#gmail.com","first_name":"Subhadeep","last_name":"Gayen"}]}
can seem to find any solution :(
Hello you need only specify the columns
"columns": [
{ "data": "id" },
{ "data": "name" }
]
Have you tried this - http://ellislab.com/forums/viewthread/160896/
And also this - http://www.ahmed-samy.com/php-codeigniter-full-featrued-jquery-datatables-part-1/
Do let me know if you succeed.
Best