HTML :
<div class="datatable-header">
<button type="button" name="add" id="add" class="float-right btn btn-info">Add</button>
</div>
<div class="table-responsive">
<table class="table datatable-basic table-striped table-hover table-bordered"
data-data-url="<?= $this->url('bla/blabla/ajax', ['action' => 'list']) ?>
id="text-dataTable"
>
<thead>
<tr>
<th>Text</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
JQuery:
const textTable = $('#text-dataTable');
const textDataTable = textTable.DataTable({
"lengthMenu": [[10, 25, 50, 75, -1], [10, 25, 50, 75, "All"]],
"dom": '<"top"fBr><"datatable-scroll-wrap"t><"bottom mt-2"ilp>',
"lengthChange": true,
"pageLength": 25,
"autoWidth": false,
"searching": false,
"order": [[0, 'asc']],
"ajax": {
"url": textTable.data('data-url'),
"type": "POST"
},
"columnDefs": [
{ targets: [1], className: "text-center"},
],
"columns": [
{ data: "text", "render": function (data, type, full, meta) {
return '<textarea style="width: 100%" contenteditable id="text" class="update" data-id="'+full.id+'" data-column="text">' + data + '</textarea>';
}
},
{ data: "textId", "render": function (data, type, full, meta) {
let $html = '<a class="btn bg-success m-1 update" data-id="'+data+'"><i class="icon-floppy-disk"></i> Update</a>';
$html += '<a class="btn bg-danger m-1 remove" data-id="'+data+'"><i class="icon-trash"></i> Delete</a>';
$html += '<a class="btn bg-grey m-1 reset" data-id="'+data+'"><i class="icon-reset"></i> Reset</a>';
return $html;
}
},
],
"rowCallback": function (row, data, index) {
if (data.hasOwnProperty('rowClass')) {
$(row).attr('class', data.rowClass);
}
$('td:last', row).attr('class', 'text-center');
}
});
$('#add').click(function(){
const addedRow = textDataTable.row.add(
{
"text": "aa",
"textId": "bb",
}
);
textDataTable.draw( false );
const addedRowNode = addedRow.node();
$(addedRowNode).addClass('highlight');
});
Result:
it's updating the text for the first column and the data-id of the second column, my goal is to add a new empty row, which means i want the first column to have 'aa' and the second column to have 'bb' instead of the buttons. I tried hundreds of things in vain.
See Screenshot:
Second Thing I tried: which is a problem because if the user adds multiple rows at the same time and click insert one by one, it will always insert the value of the first new row added, since it's getting the value by id. And all the new rows have the same ID.
$('#add').click(function(){
let html = '<tr>';
html += '<td><textarea contenteditable id="new-row-text">aa</textarea></td>';
html += '<td><a class="btn bg-grey m-1 insert"><i class="icon-plus22"></i> Insert</a></td>';
html += '</tr>';
$('#text-dataTable tbody').prepend(html);
});
textDataTable.on('click', 'a.insert', function(){
swal.fire({
title: 'Are You Sure?',
showCancelButton: true,
confirmButtonClass: "btn-success",
reverseButtons: true,
showLoaderOnConfirm: true,
preConfirm: function (data) {
return new Promise(function (resolve, reject) {
$.post(
textDataTable.data('insert-url'),
{
text: $('#new-row-text').val()
},
(function data($data) {
resolve()
}),
'json'
).fail((function(xhr, status, error) {
swal.fire('Error', xhr.responseJSON.error, 'error');
}));
})
}
}).then(result => {
if (result.value) {
textDataTable.ajax.reload();
} else {
}
}, (function () {
}));
});
Solution:
const addedRow = textDataTable.row.add(
{
"text": "aa",
"textId": "bb",
"newRow": true
}
);
Then in the render function test to see if the newRow flag exists:
{ data: "textId", "render": function (data, type, full, meta) {
// Return data if new row
if (full.hasOwnProperty('newRow') {
return data;
}
.
.
},
Credit User 2Fkthorngren: https://datatables.net/forums/discussion/61522/problem-with-adding-new-empty-row/p1?new=1
Related
I have a datatable like this
What I want is to get the latest notes with the corresponding shipment_id (the topmost notes) when clicking the copy summary report button above and paste it to some text editors for email template. But what I get is
Hi,
Below are the updates on the reimbursement requests for 3 shipment/s:
//first row
FBA15MQMW8BB: 23-Feb-21 06:08,PM Super Updated
23-Feb-21 06:06 PM :New Notes (updated) ----> not included
23-Feb-21 06:06 PM Invoice and BOL ----> not included
//2nd row
FBA15TX03JTX: 23-Feb-21 07:01 PM,Latest
23-Feb-21 07:01 PM New Notesss ----> not included
//3rd row
FBA15M1SQ8VH: 23-Feb-21 07:01 PM, Invoice and BOL
Will be sending updates again once I have additional information.
Thank you.
what i tried is
Swal.fire({
title: '<h2>Email Template copied to clipboard!</h2>',
icon: 'info',
html: '<p>You can now paste them anywhere completely.</p>',
confirmButtonText: 'Send Updates',
showCancelButton: true,
showCloseButton: true,
showLoaderOnConfirm: true,
preConfirm: (confirm) => {
var str='';
var emailBody='';
var count_shipments = $(".data-row").length;
var SearchFieldsTable = $("#tbl-inbound-shipments-in-progress tbody");
var trows = SearchFieldsTable.children(".data-row");
$.each(trows, function (index, row) {
var shipment_id=$(row).attr("data-shipment-id");
var notes = $(row).attr("data-notes");
//this is the code for copying the notes
str += shipment_id + ": " + (notes ? notes : "No notes") + "\n\n";
});
//the email body/template to be pasted
emailBody = 'Hi, \n\nBelow are the updates on the reimbursement requests for '+ count_shipments +' shipment/s: \n\n' + str +
'Will be sending updates again once I have additional information.\n\nThank you.'
var el = document.createElement('textarea');
el.value = emailBody;
el.setAttribute('readonly', '');
el.style = {position: 'absolute', left: '-9999px'};
document.body.appendChild(el);
el.select();
document.execCommand('copy');
document.body.removeChild(el);
},
EDIT: table structure and data fetch included as requested
<table class="table table-bordered table-striped table-hover display compact" id="tbl-inbound-shipments-in-progress" style="width:100%">
<thead class="text-primary">
<tr>
<th>#</th>
<th>{{ __('Client') }}</th>
<th>{{ __('SHIPMENT ID') }}</th>
<th>{{ __('Case ID') }}</th>
{{-- <th>{{ __('P/A/R') }}</th> --}}
<th>{{ __('Updated Date') }}</th>
<th>{{ __('Maturity') }}</th>
<th>{{ __('Action') }}</th>
</tr>
</thead>
</table>
table data
function load_inbound_shipment_in_progress() {
window.ISIP = $('#tbl-inbound-shipments-in-progress').DataTable({
//processing: true,
serverSide: true,
"fnInitComplete": function (oSettings, json) {
toastr.options.progressBar = true;
// toastr.info('Requested Inbound Shipment data is now loaded.');
$('#loading').hide();
},
"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]],
iDisplayLength: 10,
ajax: "{{ route('admin.clients.inbound-shipment-in-progress', ['client'=>$client->id]) }}",
createdRow: function( row, data, dataIndex ) {
var red = ((data.maturity > 5) && (data.pending > 0)) ? 'bg-danger' : '',
notes = (data.notes!='') ? data.notes : '',
shipment_id = (data.shipment_id_nolink !='') ? data.shipment_id_nolink : '';
$(row).attr('data-row_id', data.id).attr('data-notes', notes).attr('data-shipment-id', shipment_id).attr('data-case_id', data.case_id).attr('data-pending', data.pending).attr('data-shipment_id', data.shipment_id).addClass(red);
$(row).addClass('data-row');
},
dom: 'lBfrtip<"actions">',
buttons: [
{
extend: 'copy',
className: 'btn btn-custom-summary',
text: 'Copy Summary Report',
action: function ( e, dt, node, config ) {
copyEmail();
}
}
],
columns: [
{ data: 'notes', name: 'notes', "class": "text-nowrap text-center", render: function(data) { return ''; }, fnCreatedCell: function (nTd, sData, oData, iRow, iCol) {
if (oData.notes != '') $(nTd).addClass('details-control');
}, orderable: false
},
{ data: 'client', name: 'client', "class": "text-nowrap text-center" },
{ data: 'shipment_id', name: 'shipment_id', "class": "text-nowrap text-center" },
{ data: 'case_id', name: 'case_id', "class": "text-nowrap text-center", render: function(data, type, full) {
console.log(this)
var link = ''+(data )+'';
return '<span class="link-mode-'+full.id+'">' + link + '</span><input style="display: none;" id="edit-mode" class="edit-mode-'+full.id+'" type="text" value="'+ data +'">' + ' <button onclick="popup_save_case_id(this)" id="edit-case-id" class="btn btn-primary btn-xs"> <i class="fas fa-edit"></i> Edit<input type="hidden" class="case_id" value="'+data+'"> </button>';
}},
// { data: 'p_a_r', name: 'p_a_r', "class": "text-nowrap text-center" },
{ data: 'updated_at', name: 'updated_at', "class": "text-nowrap text-center" },
{ data: 'maturity', name: 'maturity', "class": "text-nowrap text-center" },
{ data: 'action', name: 'action', "class": "text-nowrap text-center bg-light", orderable: false, searchable: false }
]
});
}
Every time I reload the page I receive a pop-up window with error:
DataTables warning: table id=data-table - Requested unknown parameter
'apply_to_workdays' for row 0, column 5. For more information about
this error, please see http://datatables.net/tn/4
Assuming from the link data table is trying to get some value but it is unable to get it. The table shows up fine. I get no other errors, just those two on reload.
it shows error about apply_to_workdays but the column with it shows up perfectly, and everything works fine. I get no other errors in console/network tab.
my blade.php
<div class="table-responsive dt-responsive">
<table id="data-table" style="width: 100%;" class="display">
<thead>
<tr>
<th class="text-center">Unit</th>
<th></th>
<th>Competence Level</th>
<th style="padding-left: 0" class>Quantity</th>
<th style="padding-right: 0" class="text-right">Start -</th>
<th style="padding-left: 0" class="text-left">Finish</th>
<th style="width: 1px">Workdays</th>
<th style="width: 1px">Weekends</th>
<th style="width: 1px">Holidays</th>
<th class="text-center">Practice Type</th>
<th style="width: 10%">Action</th>
</tr>
</thead>
</table>
</div>
JS for it:
(function () {
const url = 'rotation-needs';
const positionUrl = url + '/position';
const buttonColumn = 9;
const definitionFieldValues = ['name', 'description', 'active', 'apply_to_workdays', 'apply_to_weekends', 'apply_to_holidays'];
const definition_id = 'schedule_need_definition_id';
const required = [true, false, true];
const columnDefs = [
{targets: [1, 2, 3, 4, 5, 6, 7, 8], orderable: false},
{orderable: false, className: 'reorder', targets: [buttonColumn]},
{
targets: buttonColumn,
render: function (data, type, row) {
return "<button type=\"edit-button\" data-toggle=\"modal\" data-target=\"#edit-position-Modal\"class=\"tabledit-edit-button btn btn-primary waves-effect waves-light\" style=\"float: none; margin-right: 1vw;\"><span class=\"icofont icofont-ui-edit\"></span></button>"
+ "<button type=\"button\" id=\" \" data-toggle=\"modal\" data-target=\"#remove-Modal\"class=\"tabledit-delete-button btn btn-danger waves-effect waves-light active\" style=\"float: none;\"><span class=\"icofont icofont-ui-delete\"></span></button>";
}
},
{
targets: 0,
"createdCell": function (td, data, rowData, row, col) {
$(td).css('background-color', data.color);
$(td).css('color', colors.getContrasting(data.color));
},
render: function (data, type, row) {
if (type === 'display') {
return '';
} else {
return data;
}
}
},
{
targets: [1], className: 'text-center',
render: function (data, type, row) {
var result = '';
if (row.competence_level_id_min.name !== null) {
result = result + 'min. ' + row.competence_level_id_min.name + ' <br>';
}
if (row.competence_level_id_max.name !== null) {
result = result + 'max. ' + row.competence_level_id_max.name;
}
return result;
},
"createdCell": function (td, data, rowData, row, col) {
$(td).css('background-color', rowData.organization_unit.color);
$(td).css('border-top', '1px solid #ddd');
$(td).css('color', colors.getContrasting(rowData.organization_unit.color));
}
},
{
targets: 2, className: 'text-center'
},
{
targets: 3, className: 'text-right',
render: function (data, type, row) {
return data.substring(0, 5);
}
},
{
targets: 4, className: 'text-left',
render: function (data, type, row) {
return data.substring(0, 5);
}
},
{
targets: 5, className: 'text-center',
render: function (data) {
if (data !== 0) {
return "<label class=\"badge badge-success\">✔</label>";
}
}
},
{
targets: 6, className: 'text-center',
render: function (data) {
if (data !== 0) {
return "<label class=\"badge badge-success\">✔</label>";
}
}
},
{
targets: 7, className: 'text-center',
render: function (data) {
if (data !== 0) {
return "<label class=\"badge badge-success\">✔</label>";
}
}
},
{
targets: 8, className: 'text-center',
render: function (data, type, row) {
var result = '';
if (row.practice_type_id === 1) {
/*result = result + row.practice_type_id.name + ' <br>'; - na szybko bo nie wiem czmeu nie pobiera name*/
result = 'On-call';
} else if (row.practice_type_id === 2) {
result = 'Rotation';
} else {
result = 'Not assigned';
}
return result;
}
},
]
;
const columns = [
{"data": "organization_unit"},
{"data": "competence_level_id_min"},
{"data": "quantity"},
{"data": 'time_start'},
{'data': 'time_finish'},
{'data': 'apply_to_workdays'},
{'data': 'apply_to_weekends'},
{'data': 'apply_to_holidays'},
{'data': 'practice_type_id'},
{'data': 'schedule_need_definition_position_id'}
];
create.setOnHashSuccess(hash.switchToNew);
create.createHashItemButton(definitionFieldValues, url, required);
update.updateHashMenuItem(definitionFieldValues, url + '/get');
update.confirmUpdateHashMenuItem(url + "/update", definition_id, definitionFieldValues, required);
remove.removeHashMenuItem();
remove.confirmRemoveHashMenuItem(url, hash.onRemove);
dataTable.rowGrouping(0);
dataTable.displayLength(100);
need.initializeSelects();
need.initializeCreate();
need.initializeTableCRUD(url + '/position');
need.generate();
update.setOnSuccess(function () {
sidebar.loadContent(undefined, function () {
sidebar.setActive(hash.getCurrent());
});
});
errorHandling.alertDismissButton();
});
}());
Solved my issue, in my columnDefs (target 5,6,7) I had if statements without else statements I changed from:
{
targets: 5, className: 'text-center',
render: function (data) {
if (data !== 0) {
return "<label class=\"badge badge-success\">✔</label>";
}
}
},
to:
{
targets: 5, className: 'text-center',
render: function (data) {
if (data !== 0) {
return "<label class=\"badge badge-success\">✔</label>";
} else {
return "<label class=\"badge badge-danger\">X</label>";
}
}
},
I want to add a button to the column Action but I cant put the value of data-activateUser= item["AspNetUserId"]. I am jusing a plugin DataTables btw.
My Table
DataSource
$.getJSON("/Account/InactiveAccounts").then(function (items) {
var item = items;
console.log(item["UserAccounts"]);
$('#inactive-accounts').DataTable({
columnDefs: [{ targets: 'no-sort', orderable: false }],
data: item["UserAccounts"],
"processing": true,
columns: [
{ data: "Username" },
{ data: "Password" },
{ data: "Email" },
{
data: function () {
return `<button onclick="clickDeactivateUser(this)" class="btn btn-danger btn-sm" data-activateUser=`+ item["AspNetUserId"] +`>Activate</button>
`;
}
}
]
});
JSON Data
Please change your
data: function () {
return `<button onclick="clickDeactivateUser(this)" class="btn btn-danger btn-sm" data-activateUser=`+ item["AspNetUserId"] +`>Activate</button>`;
}
to
render: function (data, type, row, meta) {
return '<button onclick="clickDeactivateUser(this)" class="btn btn-danger btn-sm" data-activateUser="'+ row.AspNetUserId +'">Activate</button>';
}
For further details about renderers, please check this
I'm trying to add an index column like this example ( https://datatables.net/examples/api/counter_columns.html ), in my table. I try to implement the code from the example to my program, but the results don't appear. How do I add an index column like the example, to my table ?
thank you
Table :
<table id="order_data">
<thead >
<tr >
<th style="text-align:center;" width="21%">Number</th>
<th style="text-align:center;" width="21%">Datetime </th>
<th style="text-align:center;" width="19%">Temp</th>
<th style="text-align:center;" width="21%">Humidity</th>
</tr>
</thead>
</table>
Javascript :
$(document).ready(function(){
$('.input-daterange').datepicker({
todayBtn:'linked',
format: "yyyy-mm-dd",
autoclose: true
});
fetch_data('no');
function fetch_data(is_date_search, start_date='', end_date='')
{
var dataTable = $('#order_data').DataTable({
dom: 'Bfrtip',
buttons: [
{
extend: 'print',
title: '<h3 align ="center">Monitoring</h3>',
text: '<i class="fa fa-pencil"></i>',
messageTop: '<p align ="center"><strong>PDF</strong> created by PDFMake with Buttons for DataTables.</p>'
},
{
extend: 'pdfHtml5',
customize: function (doc) {
doc.content[1].table.widths =
Array(doc.content[1].table.body[0].length + 1).join('*').split('');
},
title: 'Monitoring',
titleAttr: 'PDF',
text: 'PDF',
}
],
"columnDefs": [ {
"searchable": false,
"orderable": false,
"targets": 0
} ],
"order": [[ 1, 'asc' ]],
"processing" : true,
"serverSide" : true,
bFilter:false,
"ajax" : {
url:"fetch.php",
type:"POST",
data:{
is_date_search:is_date_search, start_date:start_date, end_date:end_date
},
},
});
}
$('#search').click(function(){
var start_date = $('#start_date').val();
var end_date = $('#end_date').val();
if(start_date != '' && end_date !='')
{
$('#order_data').DataTable().destroy();
fetch_data('yes', start_date, end_date);
//$("#tabel").show();
document.getElementById('tabel').style.display = "block";
}
else
{
alert("Both Date is Required");
}
});
dataTable.on( 'order.dt search.dt', function () {
dataTable.column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {
cell.innerHTML = i+1;
} );
} ).draw();
});
The example you're referencing isn't using server side processing. Rather it's assuming a static data source. You have serverSide: true and using an AJAX request to retrieve the data from a source so there are a couple of ways to handle this:
1) Use column render to generate the index value after the data is retrieved:
{
"sName": "Index",
"render": function (data, type, row, meta) {
return meta.row; // This contains the row index
}
}
2.) Add the index value to your data source and retrieve it along with your url:"fetch.php" request. Though this would actually act more like a unique ID and less like row numbering.
There is also an api call for row().index() that you could leverage in a number of ways.
my question is not how to put the empty row its why the empty row appear as first row
function BindCenterTable(ID,val) {
var strSearchLang = " ";
txtCenetrTotal.value = val;
if (lang == 'en-US') {
strSearchLang = " Search ";
}
$.ajax({
type: "Post",
url: 'Query.asmx/FillSubTransCenters',
contentType: "application/json; charset=utf-8",
dataType: "json",
data: '{SubTransID: ' + ID + '}',
success: function (data) {
if (typeof CenterTable != 'undefined')
CenterTable.destroy();
CenterTable = $('#tableCenters').DataTable({
"aaData": JSON.parse(data.d),
"bFilter": true,
"bInfo": false,
"lengthChange": false,
"oLanguage": {
"sSearch": strSearchLang
},
"paging": false,
"columns": [
{ "data": "id" }, { "data": "Center_No" },
{ "data": "CenterName" }, { "data": "Value" },
{ "data": "Val_Percent" }
],
"columnDefs": [
{
"targets": [0],
"visible": false,
"searchable": false
}, {
"targets": 5,
"data": null,
"defaultContent":
' <button class="btn btnEdit" type="button"> <i class="fa fa-pencil " style="font-size:20px"></i> </button> <button class="btn btnDelete" type="button"> <i class="fa fa-trash " style="font-size:20px"></i> </button>'
}
],
});
AddCenterEmptyRow();
},
error: function (err) {
// alert(err);
}
})
}
function AddCenterEmptyRow() {
var rowNode = CenterTable.row.add({
"id": "0", "Center_No": "0", "CenterName": "0",
"Value": "0", "Val_Percent": "0"
}).draw().node();
if (rowNode) {
var jqTds = $('>td', rowNode);
jqTds[0].innerHTML = '<table style="width:100%"><tr><td><input type="button" id="btnNewCenter" value="..." ></td><td><input type="text" class="twitterStyleTextbox" style="width:60px" id="txtNewCenter_No" readonly ></td></tr></table>';
jqTds[1].innerHTML = '<input type="text" class="twitterStyleTextbox" readonly id="txtNewCenterName" >';
jqTds[2].innerHTML = '<input type="number" style="width:60px" id="txtNewCenterVal" class="twitterStyleTextbox">';
jqTds[3].innerHTML = '<input type="number" style="width:60px" id="txtNewCenterPerc" class="twitterStyleTextbox">';
jqTds[4].innerHTML = '<button class="btn btnSubNewCenterSave" type="button"> <i class="fa fa-save " style="font-size:20px"></i> </button> '
}
var e = document.getElementById('txtNewCenterVal');
e.oninput = CenterValChange;
e.onpropertychange = e.oninput; // for IE8
var e = document.getElementById('txtNewCenterPerc');
e.oninput = CenterPercChange;
e.onpropertychange = e.oninput; // for IE8
//var e = document.getElementById('txtNewEchange_Rate');
//e.oninput = DebitChange;
//e.onpropertychange = e.oninput; // for IE8
}
every thing works fine but the data appear after the empty row
1-is there a way to select the order where to put the empty row
2- is there a better way for inserting an empty row
Note : i can not use the footer because it is used for summery but that code is not included
Thank you
Edit
According to the creator of Datatables answering a related question:
The row will be positioned according to the ordering applied to the
table. Where ever the table's ordering positions the row, that is
where it will appear.
My solution would be to use the sorting functionality to do this
Here is a live example of what i would do...
Hope this helps
Don't need jquery for this just put it in the footer <tfoot></tfoot> of your HTML table.