DataTables - Getting the database ID of the current row via click event - javascript

I am trying to get the database ID of the current row while clicking a button.
I have seen a few examples relating to this aspect and have tried many but it seems that they mostly relate to the legacy table tools extension whereas I am making use of the Editor.
Using the idSrc option from the Editor manual I recieve a server side response in JSON that contains the databases id/primary key value:
{
"data":[
{
"id":"1",
"name":"Test Name",
}
],
"options":[],
"files":[]
}
Now I am trying to get that value by clicking a button that is attached to row via the API function: row().id()
Within the example for this function it provides a clear example of how the rows id value (now the database id?) can be obtained:
var table = $('#myTable').DataTable();
$('#myTable').on( 'click', 'tr', function () {
var id = table.row( this ).id();
alert( 'Clicked row id '+id );
});
So I have implemented this as follows:
var editor;
$(document).ready(function() {
editor = new $.fn.dataTable.Editor( {
ajax: "/names.php",
table: "#example",
idSrc: "id",
fields: [ {
label: "Name:",
name: "name"
} ]
});
var table = $('#example').DataTable( {
dom: "Bfrtip",
ajax: "/names.php",
columns: [
{ data: "name" }
]
});
$('#example').on( 'click', 'tr', function () {
var id = table.row( this ).id();
alert( 'Clicked row id ' + id );
});
});
The problem here though is that when I click on the row (tr) it prompts as follows: Clicked row id undefined
Why am I getting back an undefined value when it should be sending back the row id?

When instances your DataTable, you must indicate the id field rowId, which should be indicated as the name of your columns
var table = $('#example').DataTable( {
dom: "Bfrtip",
ajax: "/names.php",
columns: [
{ data : "id" },//id is the name of your data
{ data: "name" }
],
rowId: 'id' //Here assign the id to your table
});
Result: https://jsfiddle.net/cmedina/7kfmyw6x/17/

As #CMedina pointed out, rowId stipulates which value in the JSON data is used as each rows id attribute.
Here is the code used to get the rows ID value which is prefixed with row_:
$('#example').on( 'click', 'tr', function () {
// Get the rows id value
var id = table.row( this ).id();
// Filter for only numbers
id = id.replace(/\D/g, '');
// Transform to numeric value
id = parseInt(id, 10);
// So instead of returning the actual id which is row_1
// We get back just the primary key which is 1
alert( 'Clicked row id '+id );
});

Related

jQuery get all rows using table.rows().data().each with pagination

I can't find a solution online for this. I have my code like this
$('.validation-summary-table').dataTable({ paging: true, ordering: false });
const conflictsArray = pushConflictDatas('#conflict .validation-summary-table tbody tr.odd');
function pushConflictDatas(dataTableTr) {
let radioButtonsConflicts = new Array();
$(dataTableTr).each(function() {
const currentRow = $(this).closest("tr"); // CSV row
const nextRow = currentRow.next(); // DB row
let currentRowObj = {
Name: currentRow.find('td:eq(0)').text().trim(),
isChecked: currentRow.find('td:eq(1) input[type="radio"]').is(':checked')
}
let nextRowObj = {
Name: nextRow.find('td:eq(0)').text().trim(),
isChecked: nextRow.find('td:eq(1) input[type="radio"]').is(':checked')
}
radioButtonsConflicts.push([currentRowObj, nextRowObj]);
});
return radioButtonsConflicts;
}
This worked fine until I found out it wasn't getting all table rows on the next pages when I click a button, only the current page and nothing else. I need to get all the rows and push them to an array for my ajax request. So I found this code from their docs:
var table = $(conflictTable).DataTable();
table.rows('.odd').data().each(function (value, index) {
console.log('index: ', index)
console.log('value: ', value)
} );
However this only selects <tr> on the current page, just like what the old function does. If I move to the next page, it will "append" it. If I remove the selector .odd, it would get all the rows from all paginated pages, but I'm writing a code that targets the next row and I want to only select rows with a specific class name before I do such. How do I do this?
You can use the following code to get all table data:
let table_data = table.rows({ search: 'applied'}).data();

DataTables - Sorting not working after content update

I'm using DataTables (version 1.10.18) and I'm updating rows and its content via jQuery.
My table is initalized with this code:
$(".summary").append(tableContent);
var otable = $('.summary').DataTable({
initComplete: function () {
this.api().columns([0, 1, 2, 3]).every(function () {
var column = this;
var select = $('<select><option value=""></option></select>')
.appendTo($(column.footer()).empty())
.on('change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
column
.search(val ? '^' + val + '$' : '', true, false)
.draw();
});
column.data().unique().sort().each(function (d, j) {
select.append('<option value="' + d + '">' + d + '</option>')
});
});
},
"pageLength": records_per_page,
"language": {
"url": "//cdn.datatables.net/plug-ins/1.10.16/i18n/Italian.json"
},
"order": [[0, 'desc']],
"ordering": true,
"scrollX": true,
"scrollY":"50vh",
"searching":false,
"info":false,
"paging": false
});
Then I've an input field that searches in a SharePoint list (via Rest API). So I make an AJAX call, I get the response from SharePoint web service and I prepare HTML code with new data (some data returned from web services needs to be modified). Finally I update the table content using this code:
var otable = $('.summary).DataTable();
otable.clear().draw();
$(".dataTables_scrollBody>.summary").append(newContent);
otable.rows().invalidate().draw();
newContent is something like:
newContent = "<tbody><tr><td>content</td><td>content</td></tr></tbody>";
Content is updating correctly and sorting arrows are visible in the table header, they are also changing their own active status (desc or asc) but content is not sorted.
I've tried a lot of solutions found online but no one is working for me. In the content update section I'm also adding rows using .append() method.
Is there a way to fix this?
i would suggest, instead of appending the row, you should use the https://datatables.net/reference/api/row.add() add method which is exposed by datatable api. This will automatically apply all the initial settings to new added row.

Setting id attribute to datatables 1.10.11 <tr>

I am using datatables 1.10.11.
As per the documentation, i can set the rowId using following syntax:
$('#myTable').DataTable( {
rowId: 'staffId'
} );
I am not creating datatable using Ajax.
I have two text boxes and "Add" button on left hand side and one datatable on right hand side. When i click on "Add", a new row is added to datatable. I hope that makes sense.
I need unique id attribute for each row for my use. I have tried doing so but no success at all.
According to documentation, this feature is available since DataTables 1.10.8
Did anyone solved this problem? Any help will be appreciated.
Thanks.
For add ID to tr element you con use rowId and especify the column that contain your id.
$('#myTable').DataTable(
{
columns: [
{data:"staffId"},//Remember specified the column
{data:"position"},
{data:"office"},
{data:"age"},
{data:"date"},
{data:"salary"}
],
rowId: 'staffId' //Reference to column data
});
For your button add, you should create the object and add to Table using row.add and draw for show in your table, for example:
$("#btnAdd").on("click",function(){
var rowID = $("#rowId").val();//Get value of TextBox
var new_object = {
staffId: rowID, //New rowId
position: 'Developer',
office: "Peru",
age: 25,
date: "2016/03/25",
salary: "$ 58.200"
};
myTable.row.add(
new_object
).draw();
});
Result: https://jsfiddle.net/cmedina/7kfmyw6x/65/

updated value in grid is not shown at java spring controller

I have a enhanced grid, i want to edit the grid contents and once clicked on Update link, i have to pass newly typed values to the java spring controller where i have logic to save updated values in database. But issue is after i type the value in enhanced grid i need to click somewhere in the grid or make focus on other field so that newly typed value is passed to the spring controller. If i type the new value and the cell is in edit mode and directly click on UPDATE link present in column4 of grid, the old value is passed to the spring controller. Please suggest what changes to be made so that once the mouse is out of the focus of the cell, the newly typed value should save in store and that value should be sent to spring controller when UPDATE link is clicked on column4 of grid.
Please find the fiddle : http://jsfiddle.net/740L0y43/7/
enhanced grid code:
require(['dojo/_base/lang', 'dojox/grid/EnhancedGrid', 'dojo/data/ItemFileWriteStore', 'dijit/form/Button', 'dojo/dom', 'dojo/aspect', 'dojo/domReady!'],
function (lang, EnhancedGrid, ItemFileWriteStore, Button, dom, aspect) {
/*set up data store*/
var data = {
identifier: "id",
items: [{
id : 1,
col2 : "aa",
col3 : "bb",
col4 : "cC"
}]
};
var store = new ItemFileWriteStore({
data: data
});
/*set up layout*/
var layout = [
[{
'name': 'Column 1',singleClickEdit:'true', editable:'true',
'field': 'id',
'width': '100px'
}, {
'name': 'Column 2',singleClickEdit:'true', editable:'true',
'field': 'col2',
'width': '100px'
}, {
'name': 'Column 3',singleClickEdit:'true', editable:'true',
'field': 'col3',
'width': '200px'
}, {
'name': 'Column 4',formatter: updateDetails,
'field': 'col4',
'width': '150px'
}]
];
/*create a new grid*/
var grid = new EnhancedGrid({
id: 'grid',
store: store,
structure: layout,
sortInfo: -1,
});
/*append the new grid to the div*/
grid.placeAt("gridDiv");
/*Call startup() to render the grid*/
grid.startup();
aspect.after(grid, 'renderRow', grid.sort);
var id = 2;
var button = new Button({
onClick: function () {
console.log(arguments);
store.newItem({
id: id,
col2: "col2-" + id,
col3: "col3-" + id,
col4: "col4-" + id
});
id++;
}
}, "addRow");
});
var updateDetails = function(value, rowIndex) {
var col2 = this.grid.getItem(rowIndex).col2;
alert("col2 updated value : " + col2);
return "<a href=\"<%=request.getContextPath()%>/updateInfo.htm?col2="+col2 +"\">" + "UPDATE";
};
spring controller code:
#RequestMapping(value = "/updateInfo", method = RequestMethod.GET)
public ModelAndView updateInfo(HttpServletRequest request,
HttpServletResponse response, #ModelAttribute MyDTO myDto,
#RequestParam("col2") String col2, #RequestParam("col2") String col2){
System.out.println("col2 value: " + col2);
System.out.println("col3 value: " + col3);
//when i type some value in COlumn2/Column3 of enhanced grid and column is still in edit mode then on click of UPDATE , new value is not passed to spring controller, its passing the old value.
...
...
//logic to save in DB
}
This line:
return "<a href=\"<%=request.getContextPath()%>/updateInfo.htm?col2="+col2 +"\">" + "UPDATE";
is returning an anchor with the href as "/contextPath/updateInfo.html?col2=aa". That renders it and that's it; that URL is never changing. Then, when you click on UPDATE, it sends what was in there when the page was rendered, not what the current value in your table is.
If you want to have the current value be sent, you should have your href be "#" and have an onclick="updateValue(1)" like this:
UPDATE
where 1 is the row number.
Then, in your update value function, you'd send an ajax request to update the value. Since you're using dojo, check this out: http://dojotoolkit.org/documentation/tutorials/1.8/ajax/
Here's what your function might look like (some pseudo code, some comments to describe behavior):
function updateValue(rowNum){
//var row = data.items.getRow(rowNum); or something like this
//Call ajax here and send the new row values
}
After messing with dojo for about an hour, and struggling with dojo's scoping and how to call a function that has access to the data grid and/or it's data store (sorry..I had 0 experience with dojo before this question)...here's your easy way out, OP:
http://jsfiddle.net/hm8gpz6o/
The important parts:
EnhancedGrid was NOT re-rendering the formatter generated cell when your data store was updated. This seems like a problem with dojo's EnhancedGrid.
I added the following (onApplyCellEdit will fire when a cell is updated):
/*create a new grid*/
var grid = new EnhancedGrid({
id: 'grid',
store: store,
structure: layout,
sortInfo: -1,
onApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){
refreshGrid();
}
});
And finally, refreshGrid() will force a re-render of the whole grid. I hate that I have to do this:
function refreshGrid(){
grid.startup();
}
Please see the fiddle for the full working example.

dynamically generating checkbox list from json

I'm dynamically generating a list of checkboxes based on the contents of json data:
Format of tempfairway:
[{"FairWay":"A"},{"FairWay":"B"}, {"FairWay":"C"}, {"FairWay":"D"}]
var topics = tempfairway;
var topicContainer = $('ul#fairway_list');
$.each(topics, function (iteration, item) { topicContainer.append(
$(document.createElement("li")).append(
$(document.createElement("input")).attr({
id: 'topicFilter-' + item,
name: item,
value: item,
type: 'checkbox',
checked: true
})
//onclick
.click(function (event) {
var cbox = $(this)[0];
alert(cbox.value);
})
).append(
$(document.createElement('label')).attr({
'for': 'topicFilter' + '-' + item
}).text(item)
)
)
});
The checkboxes generate fine with the correct number but i'm getting [object Object] instead of the name of the fairway.
Any ideas on how to fix this?
Couple of more questions to add to this:
-What if i wanted to display ONLY unique values in tempfairway?
-.Click is set to get the value of that single checkbox, what if i want to iterate through all the checkboxes and get the value of all the ones that were selected in the case that the user unselected any of them?
In the line:
> $.each(topics, function (iteration, item) {
item is an object like {"FairWay":"A"}, so where you have:
> .text(item)
you probably want:
.text(item.FairWay)
and similarly for other uses of item. Or you could store the value in a variable and use that:
var fairwayName = item.FairWay;
...
.text(fairwayName);

Categories

Resources