Using "later" variable in jQuery DataTables - javascript

My DataTables configuration is something like this:
(function ($) {
"use strict";
$(document).ready(function () {
$('#data-table-users').DataTable({
"processing": true,
"serverSide": true,
"filter": true,
"orderMulti": false,
"ajax": {
"url": "/Users/GetUsersData",
"type": "POST",
"datatype": "json"
},
"columnDefs":
[{
"targets": [0],
"visible": false,
"searchable": false
}],
"columns": [
.............................
{
"data": "Image",
"orderable": false,
"render": function (data, type, row, meta) {
var imgSrc;
if (data != null) {
imgSrc = '"data:image/jpeg;base64,' + atob(data) + '"';
}
else {
imgSrc = "/svg/" + "A" + ".svg";
}
return '<div><img class="small-img" src=' + imgSrc + '></div>';
}
},
{
"data": "UserName",
"render": function (data, type, row, meta) {
return '<div class="positioned"> <div class="editable" data-name="userName" contenteditable="true">'
+ data + '</div > <i class="fa fa-pencil pushright" aria-hidden="true"></i> </div>';
}
},
{
"data": "FirstName",
"render": function (data, type, row, meta) {
if (data == null)
data = "";
return '<div class="positioned"> <div class="editable" data-name="userName" contenteditable="true">'
+ data + '</div > <i class="fa fa-pencil pushright" aria-hidden="true"></i> </div>';
}
},
............................
],
"order": [[8, "desc"]]
});
});
})(jQuery);
For Image column I have in the Render function:
else {
imgSrc = "/svg/" + "A" + ".svg";
}
What I would like is instead of having imgSrc = "/svg/A.svg" is to construct it based on UserName column like so:
imgSrc = "/svg/" + userName[0].toUpperCase() + ".svg";
How can I do that without changing code on server side? It seems to me that DataTables is rendering UserName cell at a later time, so Image cell is already rendered. Can somehow a trigger be added when UserName is rendered to alter Image cell content?
I can change the values for all cells in Image column after the whole table gets rendered, but somehow I dislike that idea because it might look ugly. So, please, don't suggest that.

Just got it. I can access all data for the current row using row parameter.
So it's just:
imgSrc = "/svg/" + row['UserName'][0].toUpperCase() + ".svg";

Related

Display Show More / Show Less option if text if more then 20 length

I try to add option in my Debatable column Description if text length is more then 20 character long display Show more option and collapse this column.
I try couple of option and one which work for me is something like this
function loadDataTable() {
dataTable = $('#tblData').DataTable({
"ajax": {
"url": "/Manager/Ticket/GetAll"
},
"columnDefs": [{
"targets": 0,
"data": "description",
"render": function (data, type, row, meta) {
return type === 'display' && data.length > 20 ?
'<span title="' + data + '">' + data.substr(0, 17) + '...</span>' :
data;
}
}],
"columns": [
{
"data": "description",
"width": "10%",
//"render": function (data) {
// return 'Prikazi vise'
//}
},
{ "data": "shortDescription", "width": "10%" },
{ "data": "dateAndTime", "width": "10%" },
{ "data": "ticketType.name", "width": "10%" },
{ "data": "status", "width": "10%" },
{
"data": "applicationUser.name",
"width": "10%",
"render": function (data) {
return '<a id="' + data + '" class="text-info user-details" data-toggle="modal" data-target="#userDetails" href="' + data + '" target_blank>' + data + '</a>'
}
},
{
"data": "id",
"render": function (data) {
return `
<div class="text-center">
<a href="/Manager/Ticket/Details/${data}" class="btn btn-success text-white" style="cursor:pointer">
<i class="fas fa-info-circle">Detalji/Chat</i>
</a>
<a href="/Manager/Ticket/Upsert/${data}" class="btn btn-primary text-white" style="cursor:pointer">
<i class="fas fa-edit">Uredi</i>
</a>
</div>
`;
}, "width": "15%"
}
]
});
}
After I add columnsDef
"columnDefs": [{
"targets": 0,
"data": "description",
"render": function (data, type, row, meta) {
return type === 'display' && data.length > 20 ?
'<span title="' + data + '">' + data.substr(0, 17) + '...</span>' :
data;
}
}],
This option works but only when User hover column it display text. I add ... and I want to create that this tree dots needs to be as <a> and should be clickable and when user click it needs to Show More and Show Less option.
I check couple of post here starting from this
REFERENCE 1
The problem here is that I am noob in jQuery and JavaScript and I have no idea how to implement this side.
This is how it look like right now
UPDATE
I found some solutions but doesn't work at all. I change my columnDef
"columnDefs": [{
"targets": 0,
"data": "description",
"render": function (data, type) {
return type === 'display' && data.length > 20 ?
'<span id="outer" data-shrink="' + data.substr(0, 17) + '" title="' + data + '"></span><span id="show">...</span>' :
data;
}
}],
Here is my JavaScript
$(document).ready(function () {
$(".tblData").hide();
$(".showmore").on("click", function () {
var txt = $(".tblData").is(':visible') ? 'Vise' : 'Manje';
$(".showmore").text(txt);
$(this).next('.tblData').slideToggle(200);
});
});
I successfully add ... to be clickable, but when I click text is not showing.
UPDATE
"columnDefs": [{
"targets": 0,
"data": "description",
"render": function (data, type) {
return type === 'display' && data.length > 20 ?
'<span id="outer" title="' + data + '">' + data.substr(0, 17) + '</span><span id="show">...</span>' :
data;
}
}],
$('#show').click(function () {
var text = $('#outer').attr('title');
$(this).text(text);
$('#show').after('<a id="less" onclick="someFunction()" href="#"> Show less</a>');
$('#outer').text('');
});
function someFunction() {
console.log('test');
$('#less').remove();
var txt = $('#outer').attr('data-shrink');
$('#show').text('');
$('#outer').text(txt);
$('#show').text('...');
}
var len = $('#outer').text();
if(len.length > 20) {
var txt = $('#outer').attr('data-shrink');
console.log(txt);
$('#outer').text(txt);
$('#show').text('...');
}
$('#show').click(function() {
var text = $('#outer').attr('title');
console.log('text', text.length);
$(this).text(text);
$('#show').after('<a id="less" onclick="someFunction()" href="#"> Show less</a>');
$('#outer').text('');
});
function someFunction() {
console.log('test');
$('#less').remove();
var txt = $('#outer').attr('data-shrink');
$('#show').text('');
$('#outer').text(txt);
$('#show').text('...');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span id="outer" data-shrink="Das ist ein" title="Das ist ein ganzer Text langer Text">Das ist ein sehr langer Text</span><span id="show"></span>
Just replace the html with your variables.

How can I get the current page from within the $().DataTable() function?

I am working on an ASP.Net Core 2.1 MVC web application and I am using DataTables.Net datatable v1.10.19 for my lists.
I am creating master/detail drill downs where the first list (DataTable) of job activity provides a link on each row to the respective detail record. I am using pagination as well.
On the detail record, I want to have a breadcrumb that takes me back to the job activity list, and to the correct page number where I was at then I clicked on the detail link.
What I am doing is passing the query properties I am using on the Job Activity DataTable as query string parameters to the detail page so I can correctly populate the breadcrumb URL back to the job activity page.
I can see on the DataTable.Net API reference that I can use page.info() from the API to get the current page using something like this;
var table = $('#example').DataTable();
var info = table.page.info();
$('#tableInfo').html(
'Currently showing page '+(info.page+1)+' of '+info.pages+' pages.'
);
The problem is that I initialize the DataTable as part of the table setup and in the body of that function is where I am populating the link data for the detail page. I can't seem to do two .DataTable() calls, such as doing the call to the DataTable function to get the page info to initialize a pageNumber variable and then call the main .DataTable function as it causes the init of the main DataTable function to fail.
So, I need a way to get the current page from within the main .Datatable() function, if possible.
Here is my main DataTable() function;
jQuery(document).ready(function($) {
//Get the Timezone offset between local time and UTC
var d = new Date();
var m = d.getTimezoneOffset();
var minutesToOffset = parseInt(m, 10);
var companyId = $('#company-filter').val();
var siteId = $('#site-filter').val();
var aging = $('#aging-filter').val();
console.log(`companyId: [${companyId}], siteId: [${siteId}], Aging Days: [${aging}]`);
var table = $("#ssflist").DataTable({
//"dom": "lrtip",
"initComplete": function() {
$('#spinner1').hide();
$('#spinner2').hide();
},
"processing": true,
"serverSide": true,
"filter": true,
"orderMulti": false,
"order": [[6, "desc"]],
"ajax": {
"url": `/JobActivity/LoadData?companyId=${companyId}&siteId=${siteId}&agingDays=${aging}`,
"type": "POST",
"datatype": "json"
},
"oLanguage": {
"sSearch": "Filter"
},
"columnDefs": [
{ "orderable": false, "targets": [9, 10] },
{ "className": "text-center", "targets": [0, 9, 10] },
{
"targets": [6, 7],
"render": function(data) {
if (data != null) {
return moment(data).subtract(minutesToOffset, 'minutes').format('M/D/YYYY h:mm a');
}
}
}
],
"columns": [
{
"render": function(data, type, full, meta) {
if (full.ManifestStatus === 0) {
return '<i class="far fa-clock text-primary" title="Not started"></i>';
} else if (full.ManifestStatus === 1) {
return '<i class="fas fa-sync-alt text-primary" title="Pending"></i>';
} else if (full.ManifestStatus === 2) {
return '<i class="far fa-file-alt text-primary" title="Manifested"></i>';
} else if (full.ManifestStatus === 3) {
return '<i class="far fa-times-circle text-danger" title="Failed"></i>';
} else if (full.ManifestStatus === 4) {
return '<i class="far fa-check-circle text-primary" title="Uploaded"></i>';
} else return '<i class="far fa-question-circle text-primary" title="Unknown status"></i>';
},
"name": "ManifestStatus"
},
{
"render": function(data, type, full, meta) {
if (type === 'display' && data != null) {
data =
`<a href="/shippingServicesFileDetail/detail?id=${full.Id
}&returnTitle=Job Activity List&companyId=${companyId}&siteId=${siteId}&agingDays=${
aging}">
<button type="button" class="btn btn-outline-primary btn-sm">` +
data +
`</button></a>`;
}
return data;
},
"data": "Id",
"name": "Id"
},
{ "data": "TransactionId", "name": "TransactionId", "autoWidth": true, "defaultContent": "" },
{ "data": "CompanyName", "name": "CompanyName", "autoWidth": true, "defaultContent": "" },
{ "data": "SiteName", "name": "SiteName", "autoWidth": true, "defaultContent": "" },
{ "data": "ReferenceId", "name": "ReferenceId", "autoWidth": true, "defaultContent": "" },
{ "data": "CreatedDate", "name": "CreatedDate", "autoWidth": true, "defaultContent": "" },
{ "data": "UploadDate", "name": "UploadDate", "autoWidth": true, "defaultContent": "" },
{ "data": "Environment", "name": "Environment", "autoWidth": true, "defaultContent": "" },
{
"render": function(data, type, full, meta) {
data = full.H1RecordCount + full.D1RecordCount + full.C1RecordCount;
return data;
},
"name": "Count"
},
{
"render": function(data, type, full, meta) {
if (full.AzureFileUrl != null) {
data =
`<a href="/JobActivity/getManifest?azureFileUrl=${full.AzureFileUrl
}&azureFileName=${full.AzureFileName}">
<i class="far fa-arrow-alt-circle-down text-primary" title="Download Manifest"></a>`;
return data;
} else {
return null;
}
},
"name": "AzureFileUrl"
}
],
// From StackOverflow http://stackoverflow.com/a/33377633/1988326 - hides pagination if only 1 page
"preDrawCallback":
function(settings) {
var api = new $.fn.dataTable.Api(settings);
var pagination = $(this)
.closest('.dataTables_wrapper')
.find('.dataTables_paginate');
pagination.toggle(api.page.info().pages > 1);
},
});
$('#companyId').on('change',
function() {
table.search(this.text).draw();
});
});
The relevant link code is...
data = `<a href="/shippingServicesFileDetail/detail?id=${full.Id
}&returnTitle=Job Activity
List&companyId=${companyId}&siteId=${siteId}&agingDays=${
aging}">
I want to add a parameter to this link that represents the current page of the Datatable so that I can pass it back in the breadcrumb link on the detail page and have the datatable go to the correct page.
So I need a way to get the current page from within the
var table = $("#ssflist").DataTable({
function itself so I can pass that value in the link to the detail page.
Is there a property or method from within the Datatable function that will get me the current page value?

Function to get row data works only in responsive mode in Datatables

When I click on the image in Reponsive mode, it will return the row data in console. But in normal view I get Undefined error.
var table = $('.dataTable').DataTable({
"responsive": true,
"columnDefs": [{
"targets": 4,
"data": null,
"render": function (data, type, full, meta) {
if (type === 'display') {
data = "<a href='#' width='30px' class='editMe' data='" + full[0] + "'><img src='/images/edit.png' width='30px' /></a>";
}
return data;
}
} ,
{
"targets": 0,
"visible": false,
"searchable": false
}]
});
$('.dataTable').on('click', '.editMe', function () {
console.log(table.row(this).data());
});
Use the code below instead:
$('.dataTable').on('click', '.editMe', function () {
var $row = $(this).closest('tr');
if($row.hasClass('child')){ $row = $row.prev(); }
console.log(table.row($row).data());
});
See this example for code and demonstration.

Add Empty Row(For Insert) in jquery Datatable (Not Editor) in bottom after data

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.

dataTable page length change issue

I am using dataTable 1.10. Everything works well but I got following situation. I think that dataTable not support this behaviour.
By default I set the page length be 10, then I click Next page, table display items from 11 to 20. NOW I change the page length to 25, table display item from 11 to 35. This is not the thing I suppose to have. Whenever I change the page length, I wish to display from 1st item.
Is it possible to handle the Page Length change event in dataTable and customize that function?
Thank for reading. Hope to receive help from you.
var tableHdr = '<table cellpadding="0" cellspacing="0" border="0" class="display" id="alertsList">'
+ '<thead><tr>'
+ '<th>Level</th><th>Monitor Name</th><th>Alert Message</th><th>Raised At</th><th>Action</th>'
+ '</tr></thead></table>';
$('#overview_content').html( tableHdr );
//global variable
oTable = $('#alertsList').dataTable( {
"pagingType": "full_numbers",
"bJQueryUI": true,
"aaData": alertsData,
"bAutoWidth": false,
"aaSorting" : [[3, "desc"]],
"aoColumns": [
{ "sTitle": "Level", "mData":"alert_level", "sWidth":"10%" },
{ "sTitle": "Monitor Name", "mData":"monitor_name", "sWidth":"20%" },
{ "sTitle": "Alert Message", "mData":"alert_message", "sWidth":"30%" },
{ "sTitle": "Raised At", "mData":"triggered_datetime", "sWidth":"20%"},
{ "sTitle": "Action", "mData":"id", "bSortable":false, "bSearchable":false, "sWidth":"20%"}
],
"columnDefs": [
{
"targets": 1,
"data":"monitor_name",
"render": function ( data, type, full, meta ) {
return escapeHTML(data);
}
},
{
"targets": 2,
"data":"alert_message",
"render": function ( data, type, full, meta ) {
if (data == null || typeof data == 'undefined')
{
return "";
}
var description = data.length > 30? data.substr(0,30) + '...': data;
return escapeHTML(description);
}
},
{
"targets": 4,
"render": function ( data, type, full, meta ) {
return ("<span style='cursor:pointer' id='dismiss_alert_" + full.id + "' class='dismiss'>Dismiss</span> | " +
"<span style='cursor:pointer' id='delete_alert_" + full.id + "' class='delete'>Delete</span> | " +
"<span style='cursor:pointer' id='details_alert_" + full.id + "' class='details'>Details</span>");
}
} ]
} );
Try this, I found it from datatable forum.
var t = $('#table-id').dataTable();
$('#length li').click(function () {
redrawWithNewCount(t, this.id);
});
function redrawWithNewCount(t, row_count) {
//Lifted more or less right out of the DataTables source
var oSettings = t.fnSettings();
oSettings._iDisplayLength = parseInt(row_count, 10);
t._fnCalculateEnd(oSettings);
/* If we have space to show extra rows (backing up from the end point - then do so */
if (oSettings.fnDisplayEnd() == oSettings.fnRecordsDisplay()) {
oSettings._iDisplayStart = oSettings.fnDisplayEnd() - oSettings._iDisplayLength;
if (oSettings._iDisplayStart < 0) {
oSettings._iDisplayStart = 0;
}
}
if (oSettings._iDisplayLength == -1) {
oSettings._iDisplayStart = 0;
}
t.fnDraw(oSettings);
return t;
}

Categories