I have datatable Like this
oInnerTable = $("#url_table_" + rotator_id).DataTable({
"processing": true,
"serverSide": true,
rowReorder: {
dataSrc: [1]
},
"ajax":{
url :"actions/data_url_response.php",
type: "post",
data: function ( d ) {
var url_status = $('.url_status').val();
d.rotator_id = rotator_id;
d.url_status = url_status;
}
},
autoWidth: false,
columnDefs: [
{ "visible": false, "targets": 0 },
{ orderable: true, className: 'reorder', targets: 0 },
{
"targets":[0, 7],
"orderable":false,
},
{
targets: 0,
render: function (data, type, row) {
return '<div class="form-check"><input type="checkbox" class="form-check-input position-static select_ids" value="'+row[0]+'"></div>';
}
},
],
dom: '<"datatable-scroll"t><"datatable-footer"ip>',
language: {
search: '<span>Filter:</span> _INPUT_',
searchPlaceholder: 'Type to search...',
lengthMenu: '<span>Show:</span> _MENU_',
paginate: { 'first': 'First', 'last': 'Last', 'next': $('html').attr('dir') == 'rtl' ? '←' : '→', 'previous': $('html').attr('dir') == 'rtl' ? '→' : '←' }
}
});
And Update function is like below
var positionArray = [];
oInnerTable.on( 'row-reorder', function ( e, diff, edit ) {
for ( var i=0, ien=diff.length ; i<ien ; i++ ) {
var rowData = oInnerTable.row( diff[i].node ).data();
positionArray.push({
myid:rowData[0],
mypositiion: diff[i].newData
});
}
if (positionArray.length>0) {
$.post("/link-to-script.php", {
positionArray: positionArray
}, function(data, status) {
positionArray = [];
})
} ;
} );
Since I have three rows in table, everytime when I change position, its calling ajax three time and sometime its even more time, Its not possible that its fire only one time and I can send position data to server with single ajax call?
Thanks!
Related
I am trying to fetch data from an API of WordPress.
Here is my code:
column.data().unique().sort().each(function (d,j) {
var practiceArea = d.practice_area;
var jsonPacticeArea = JSON.stringify(practiceArea);
if (jsonPacticeArea !== undefined) {
var res = $.map(jsonPacticeArea.split("|"), $.trim);
for (var i = 0; i < res.length; i++) {
var str = res[i];
str = str.replace(/"/gi, '').trim();
if (arrayPracticeArea.indexOf(str) === -1) {
arrayPracticeArea.push(str);
}
}
}
});
the "column" is the variable that is getting data through an API, and as far as I do console.log(column. data().unique().sort()), that's returning complete data as you can see in the screenshot and I want to fetch data is marked in red rectangle and store those values in an array, but as soon as I try to add "each" function to fetch the data and store it in an array (in my case its arrayPracticeArea) its returning undefined values.
Can anyone please help me out? I am just not much experienced with Javascript API.
Here is my AJAX code:
var tableAttorney = $('#table_affliate_attorney').DataTable({
destroy: true,
searching: true,
bLengthChange: false,
scrollX: true,
scrollY: 440,
autoWidth: false,
"language": {
"emptyTable": "We are sorry but there are no Affiliate Attorneys within a 150 mile radius of your requested search"
},
ajax: {
type: 'get',
url: "/wp-admin/admin-ajax.php",
dataType: 'json',
cache: false,
data: {
'action': 'get_attorney_ajax',
'center_lat': center_lat,
'center_long': center_long,
'state': state,
'city': city,
'zip': zip
}
},
columns: [
{"data": "title"},
{"data": "city"},
{"data": "state"},
{"data": "zip"},
{"data": "distance"},
{
"data": "phone",
className: 'datatablePhone',
render: function (data) {
return '' + data + '';
}
},
{
"data": "email",
className: 'px190EM',
render: function (data) {
return '' + data + '';
}
},
{
className: 'js-practice-area',
"data": "practice_area"
},
{
"targets": -1,
"data": 'email',
render: function (data) {
return "<a class='contact-lawyer' href='#' data-toggle='modal' data-target='#exampleModal' data-whatever='#mdo' data-email='"+data+"'>Contact</a>";
}
},
],
columnDefs: [
{"width": "150px", "targets": [0]},
{"width": "130px", "targets": [5]}
],
So I am trying to fetch data from columns->data that has value practice_area
I want to create and show number sort ascending data in datatables like in this picture
index number
and I don't have sorted data number in database and my json data
this is my code:
$(document).ready(function() {
$('#dataya').DataTable({
lengthChange: false,
ajax: {
url: "http://localhost/jdih_webservice/api/xxxx",
dataSrc: ""
},
columns: [
{ data: "id_dokumen"},
{ data: "judul"},
{ data: "subjek"}
],
select: true
});
$('#search').click(function(){
var start_date = $('#start_date').val();
var end_date = $('#end_date').val();
var myTable = $('#dataya').DataTable({
"paging": true,
"lengthChange": true,
"searching": true,
"ordering": true,
"info": true,
"bDestroy": true,
"autoWidth": true,
"data": [],
"columns": [{
"title": "ID",
"data": "id_dokumen"
}, {
"title": "Judul",
"data": "judul"
}, {
"title": "Subjek",
"data": "subjek"
}],
"order": [[ 1, 'asc' ]]
});
if(start_date != '' && end_date !='')
{
var startDate = new Date(start_date);
var tglmulai = startDate.getFullYear();
var endDate = new Date(end_date);
var tglselesai = endDate.getFullYear();
let url = 'http://localhost/jdih_webservice/api/xxxx';
fetch(url)
.then(res => res.json())
.then((out) => {
var resultProductData = out.filter(function(a) {
var createdAt = new Date(a.tgltetap);
var tgldata = createdAt.getFullYear();
if( tgldata >= tglmulai && tgldata <= tglselesai ) return a;
});
myTable.clear();
$.each(resultProductData, function (index, value) {
myTable.row.add(value);
});
myTable.draw();
})
.catch(err => { throw err });
}
});
});
Anyone could help? , so appreciate thanks
and maybe if you not busy could you create/build in jsfiddle
This code is from this DataTables thread and should do what you want. It's using an additional column for the indexes:
dataTable.on( 'order.dt search.dt', function () {
dataTable.column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {
cell.innerHTML = i+1;
} );
} ).draw();
So currently i have a datatable that displays alot of timesheets for alot of files, i need to create a function that will group all the data by their respected files, but all example that i have found do this in the initialization of the datatable but i need to do this with a custom created button and fail to find any examples or documentation on how to do it this way
The code will just create a table but i would like to have a button with a value "Group Items" then after the button is clicked it should group all by file
$('#data-table-timesheet').DataTable({
ajax: {
url: '#Url.Action("GetTimeSheets", "Home")',
data: function (d) {
d.from = $("#DateStart").data('datepicker').getFormattedDate('yyyy-MM-dd'),
d.to = $("#DateEnd").data('datepicker').getFormattedDate('yyyy-MM-dd'),
d.partyId = parseInt($("#UserId").val())
},
dataSrc: 'Data'
},
"footerCallback": function (row, data, start, end, display) {
var api = this.api(), data;
// Remove the formatting to get integer data for summation
var intVal = function (i) {
return typeof i === 'string' ?
i.replace(/[\$,]/g, '') * 1 :
typeof i === 'number' ?
i : 0;
};
// Total over all pages
total = api
.column(8, { page: 'current' })
.data()
.reduce(function (a, b) {
return intVal(a) + intVal(b);
}, 0);
// Total over this page
pageTotal = api
.column(7, { page: 'current' })
.data()
.reduce(function (a, b) {
return intVal(a) + intVal(b);
}, 0);
// Update footer
$(api.column(7).footer()).html(
'R' + parseInt(pageTotal).toFixed(2)
);
pageTotal = api
.column(8, { page: 'current' })
.data()
.reduce(function (a, b) {
return intVal(a) + intVal(b);
}, 0);
// Update footer
$(api.column(8).footer()).html(
'R' + parseInt(pageTotal).toFixed(2)
);
var uTotal = api
.cells(function (index, data, node) {
if (api.row(index).data().LastModified == null && api.row(index).data().timelogId != null) {
return true;
}
else {
return false;
}
}, 6, { page: 'current' })
.data()
.reduce(function (a, b) {
return intVal(a) + intVal(b);
}, 0);
var cTotal = api
.cells(function (index, data, node) {
if (api.row(index).data().LastModified != null && api.row(index).data().timelogId != null || api.row(index).data().timelogId == null && parseInt(api.row(index).data().rateTotal) > 0) {
return true;
}
else {
return false;
}
}, 6, { page: 'current' })
.data()
.reduce(function (a, b) {
return intVal(a) + intVal(b);
}, 0);
$(api.column(6).footer()).html(
"C(" + parseInt(cTotal).toFixed(0).toString().secondsToHHMMSS() + ")" + "<br/> U(" + parseInt(uTotal).toFixed(0).toString().secondsToHHMMSS() + ")"
);
},
"columns": [
{
"data": "isJoined",
"render": function (data, type, row) {
if (row.isJoined == 1) {
return '<i class="fa fa-fw f-s-10 m-r-5 fa-circle text-primary"></i>';
}
else {
return "";
}
}
},
{
"data": "StartDate",
"render": function (data, type, row) {
return moment(data).format("YYYY-MM-DD HH:mm").toString().trim();
}
},
{
"data": "EndDate",
"render": function (data, type, row) {
return moment(data).format("YYYY-MM-DD HH:mm");
}
},
{ "data": "fileRef" },
{ "data": "CategoryName" },
{ "data": "Notes" },
{
"data": "BillableMinutes",
"render": function (data, type, row) {
if (row.rateTotal > 0 ) {
return data.toString().secondsToHHMMSS();
}
else {
var x = (data / 60);
return x.toFixed(2);
}
}
},
{ "data": "rateTotal" },
{ "data": "disbursementTotal" }
],
"createdRow": function (row, data, dataIndex) {
if (data.LastModified == null && data.timelogId != null) {
$(row).addClass('redClass');
}
},
"deferRender": true,
autoWidth: false,
bAutoWidth: false,
dom: 'Bfrtip',
paging: false,
select: true,
responsive: true,
select: {
style: 'multi'
},
buttons: [
{ extend: 'copyHtml5', footer: true },
{ extend: 'excelHtml5', footer: true },
{ extend: 'csvHtml5', footer: true },
{ extend: 'pdfHtml5', footer: true }
],
columnDefs: [
{
targets: 5,
render: $.fn.dataTable.render.ellipsis(50, true, true)
},
{ "width": "5px", "targets": 0 },
{ "width": "135px", "targets": 1 },
{ "width": "135px", "targets": 2 },
{ "width": "1px", "targets": 3 },
{ "width": "1px", "targets": 4 },
{ "width": "400px", "targets": 5 },
{ "width": "2px", "targets": 6 },
{ "width": "1px", "targets": 7 },
{ "width": "1px", "targets": 8 }
]
});
The below listed code is how i do row grouping when the datatable is initialized, but i need to have this in a seperate button so when the user clicks the button it would only group then
"drawCallback": function (settings) {
var api = this.api();
var rows = api.rows({ page: 'current' }).nodes();
var last = null;
api.column(3, { page: 'current' }).data().each(function (group, i) {
if (last !== group) {
$(rows).eq(i).before(
'<tr class="group"><td colspan="5">' + group + '</td></tr>'
);
last = group;
}
});
},
So after a few more days of searching the internet i have not found a solution, but instead i created a global variable of type bool, so when the datatable is drawn it looks in the drawcall back function to see if the global variable is set to true or not, and depending on the condition it will either group or not, so i draw the table everytime after the user has clicked the button that he/she would like to group
"drawCallback": function (settings) {
if(groupBy == true){
var api = this.api();
var rows = api.rows({ page: 'current' }).nodes();
var last = null;
api.column(3, { page: 'current' }).data().each(function (group, i) {
if (last !== group) {
$(rows).eq(i).before(
'<tr class="group"><td colspan="5">' + group + '</td></tr>'
);
last = group;
}
}
});
},
I am using data tables. Currently, it is working as expected, hower I would like to have the Add and Remove Buttons have some sort of count. For example AddButton_0
How would I do this using Data Tables?
var url = "/ClientSetup/GetCatalogueContracts";
var contractsTable = $('#catalogueContractsTable').DataTable({
sAjaxSource: url,
columns: [
{ "data": "ID" },
{ "data": "Selected"},
{ "data": "Name"},
{ "data": "ContractType"},
{ "data": "StartDate"},
{ "data": "TerminationDate"},
{ "button": "Action" }
],
serverSide: true,
sDom: 't<"dt-panelfooter clearfix"ip>',
pageLength: pageSize,
bSort: false,
bLengthChange: false,
bSearch: true,
paging: true,
searching: true,
order: [[2, "asc"]],
language: {
emptyTable: "No contracts found.",
zeroRecords: "No contracts found.",
info: "_START_ to _END_ of _TOTAL_",
paginate: {
first: "First",
previous: "Previous",
next: "Next",
last: "Last"
}
},
columnDefs: [
{
targets: [0],
visible: false
},
{
targets: [1],
visible: false
},
{
targets: [2]
},
{
targets: [3],
sClass: "hidden-xs hidden-sm contractType"
},
{
targets: [4],
sClass: "hidden-xs fromDate"
},
{
targets: [5],
sClass: "hidden-xs terminationDate"
},
{
data: null,
targets: [6],
sClass: "updateTableRow text-center",
render: function ( data, type, full, meta )
{
var id = data["ID"];
return `<button class=\"btn btn-success br2 btn-xs fs12 table-btn button-selector-${id}\" id=\"AddContractBtn\">Add</button>`;
}
}
],
drawCallback: function( settings ) {
disableInvalidContracts();
},
autoWidth: false
});
// make sure already selected rows cannot be added again.
var excludeIds = getExcludeIds();
$.each(excludeIds, function() {
var button = $("#AddContractBtn.button-selector-" + this);
button.addClass("disabled");
button.prop('disabled', true);
});
}
#* Adding and Removing Data from both Tables *#
contractsTable.on('click', '#AddContractBtn', function () {
var $row = $(this).closest("tr");
#*Track Contract IDs that have been removed from the unselected table*#
var value = $('#exclude-ids').val();
var ids = getExcludeIds();
ids.push($row.attr('id'));
$('#exclude-ids').val(JSON.stringify(ids));
var addRow = contractsTable.row($row);
var data = addRow.data();
data.Selected = true;
selectedContractsTable.row.add(addRow.data()).draw( false );
setSelectedInputForContract('true', data.ID);
disableInvalidContracts();
});
selectedContractsTable.on('click', '#RemoveContractBtn', function () {
var $row = $(this).closest('tr');
var addRow = selectedContractsTable.row($row);
var data = addRow.data();
data.Selected = false;
addRow.data(data);
addRow.remove().draw();
#* Remove the Contract ID from the exclide ids hidden input*#
var value = $('#exclude-ids').val();
var ids = getExcludeIds();
ids = ids.filter(i => i !== $row.attr('id'));
$('#exclude-ids').val(JSON.stringify(ids));
setSelectedInputForContract('false', data.ID);
disableInvalidContracts();
});
I am looking for a way that I can add a Count for each of the buttons for example `AddButton_0 I am unsure if there is an option to use a count on DataTables. Or whether I could use JQuery?
Try this : you can have global variable and increment it for each access of button creation function. Click handler for add and remove button can be created with start with attribute selector in jquery.
See below code
var count = 0;
var url = "/ClientSetup/GetCatalogueContracts";
var contractsTable = $('#catalogueContractsTable').DataTable({
sAjaxSource: url,
columns: [
{ "data": "ID" },
{ "data": "Selected"},
{ "data": "Name"},
{ "data": "ContractType"},
{ "data": "StartDate"},
{ "data": "TerminationDate"},
{ "button": "Action" }
],
serverSide: true,
sDom: 't<"dt-panelfooter clearfix"ip>',
pageLength: pageSize,
bSort: false,
bLengthChange: false,
bSearch: true,
paging: true,
searching: true,
order: [[2, "asc"]],
language: {
emptyTable: "No contracts found.",
zeroRecords: "No contracts found.",
info: "_START_ to _END_ of _TOTAL_",
paginate: {
first: "First",
previous: "Previous",
next: "Next",
last: "Last"
}
},
columnDefs: [
{
targets: [0],
visible: false
},
{
targets: [1],
visible: false
},
{
targets: [2]
},
{
targets: [3],
sClass: "hidden-xs hidden-sm contractType"
},
{
targets: [4],
sClass: "hidden-xs fromDate"
},
{
targets: [5],
sClass: "hidden-xs terminationDate"
},
{
data: null,
targets: [6],
sClass: "updateTableRow text-center",
render: function ( data, type, full, meta )
{
var button = `<button class=\"btn btn-success br2 btn-xs fs12 table-btn button-selector-${id}\" id=\"AddContractBtn' + count + '\">Add</button>`;
count++; // increment count
var id = data["ID"];
return button;
}
}
],
drawCallback: function( settings ) {
disableInvalidContracts();
},
autoWidth: false
});
// make sure already selected rows cannot be added again.
var excludeIds = getExcludeIds();
$.each(excludeIds, function() {
var button = $("#AddContractBtn.button-selector-" + this);
button.addClass("disabled");
button.prop('disabled', true);
});
}
#* Adding and Removing Data from both Tables *#
contractsTable.on('click', 'button[id^=AddContractBtn]', function () {
var $row = $(this).closest("tr");
#*Track Contract IDs that have been removed from the unselected table*#
var value = $('#exclude-ids').val();
var ids = getExcludeIds();
ids.push($row.attr('id'));
$('#exclude-ids').val(JSON.stringify(ids));
var addRow = contractsTable.row($row);
var data = addRow.data();
data.Selected = true;
selectedContractsTable.row.add(addRow.data()).draw( false );
setSelectedInputForContract('true', data.ID);
disableInvalidContracts();
});
selectedContractsTable.on('click', 'button[id^=RemoveContractBtn]', function () {
var $row = $(this).closest('tr');
var addRow = selectedContractsTable.row($row);
var data = addRow.data();
data.Selected = false;
addRow.data(data);
addRow.remove().draw();
#* Remove the Contract ID from the exclide ids hidden input*#
var value = $('#exclude-ids').val();
var ids = getExcludeIds();
ids = ids.filter(i => i !== $row.attr('id'));
$('#exclude-ids').val(JSON.stringify(ids));
setSelectedInputForContract('false', data.ID);
disableInvalidContracts();
});
I am using handsontable with the select2 editor but I cannot seem to make dynamic options work with the dropdown menu, i.e. the options set at the the time of the handsontable initialisation are the only options that ever seem to show.
I have tried using a global variable as the source of the options and updating that at various points in my code and also using a function to return the same variable but neither attempt seems to work.
e.g.
var hot;
var data = [];
function customDropdownRenderer(instance, td, row, col, prop, value, cellProperties) {
if (instance.getCell(row, col)) {
$(instance.getCell(row,col)).addClass('select2dropdown');
}
var selectedId;
var colOptions = cellProperties.select2Options.data;
if (colOptions != undefined) {
for (var index = 0; index < colOptions.length; index++) {
if (parseInt(value) === colOptions[index].id) {
selectedId = colOptions[index].id;
value = colOptions[index].text;
}
}
Handsontable.TextCell.renderer.apply(this, arguments);
}
}
var requiredText = /([^\s])/;
$(document).ready(function(){
var
$container = $("#example1"),
$parent = $container.parent(),
autosaveNotification;
hot = new Handsontable($container[0], {
columnSorting: true,
stretchH: 'all',
startRows: 8,
startCols: 5,
rowHeaders: true,
colHeaders: ['Description', 'Cost', 'Remarks'],
columns: [
{ data: 'description' },
{
data: 'cost',
editor: 'select2',
renderer: customDropdownRenderer,
select2Options: { data: getData(), dropdownAutoWidth: true }
},
{ data: 'remarks' },
],
minSpareCols: 0,
minSpareRows: 1,
contextMenu: true,
data: []
});
data = [{id:'fixed',text:'Fixed'},{id:'variable',text:'Variable'}];
});
function getData() {
return data;
}
http://jsfiddle.net/zfmdu4wt/27/
You have defined data multiple times and it is causing contention.
The following changes will fix it:
Define the following immediately after the .ready() function:
var source = [{id:'fixed',text:'Fixed'},{id:'variable',text:'Variable'}];
and update the select2Options to the following:
select2Options : { data: source, dropdownAutoWidth: true }
I managed to get it working by re-using some code I had used to solve the same problem with the xeditable plugin.
Here's the updated code:
var hot;
var data = [];
function customDropdownRenderer(instance, td, row, col, prop, value, cellProperties) {
if (instance.getCell(row, col)) {
$(instance.getCell(row,col)).addClass('select2dropdown');
}
var selectedId;
var colOptions = cellProperties.select2Options.data;
if (colOptions != undefined) {
for (var index = 0; index < colOptions.length; index++) {
if (parseInt(value) === colOptions[index].id) {
selectedId = colOptions[index].id;
value = colOptions[index].text;
}
}
Handsontable.TextCell.renderer.apply(this, arguments);
}
}
var requiredText = /([^\s])/;
$(document).ready(function(){
var
$container = $("#example1"),
$parent = $container.parent(),
autosaveNotification;
hot = new Handsontable($container[0], {
columnSorting: true,
stretchH: 'all',
startRows: 8,
startCols: 5,
rowHeaders: true,
colHeaders: ['Description', 'Cost', 'Remarks'],
columns: [
{ data: 'description' },
{
data: 'cost',
editor: 'select2',
renderer: customDropdownRenderer,
// select2Options: { data: getData(), dropdownAutoWidth: true }
select2Options: { data: getSource(), dropdownAutoWidth: true, width: 'resolve', initSelection: getInitSel(false), query: getQuery }
},
{ data: 'remarks' },
],
minSpareCols: 0,
minSpareRows: 1,
contextMenu: true,
data: []
});
data = [{id:'fixed',text:'Fixed'},{id:'variable',text:'Variable'}];
});
/*
function getData() {
return data;
}
*/
// New Code
function getSource() {
return data;
};
function getQuery(options) {
options.callback({ results : getSource() });
};
function getInitSel(multiple) {
return function(el, cb) {
var t, toSet = [], sc = getSource();
el[0].value.split(',').forEach(function(a) {
for (var i = 0; i < sc.length; i++) {
if (sc[i].id == Number(a.trim())) {
t = sc[i];
}
}
// or, if you are using underscore.js
// t = _.findWhere(sc, { id : Number(a.trim()) });
if(t) toSet.push(t);
});
cb(multiple ? toSet : (toSet.length ? toSet[0] : null));
};
};
and a fiddle for demonstration - http://jsfiddle.net/zfmdu4wt/38/