How can I extract a selected row's data on Datatables - javascript

I have initialised a simple Datatable:
//initialise table
var dataTable = $('#example').DataTable({
searching: false,
responsive: true
});
//hide unnecessary columns
dataTable.columns(1).visible(false);
dataTable.columns(2).visible(false);
dataTable.columns(3).visible(false);
dataTable.columns(4).visible(false);
dataTable.columns(5).visible(false);
dataTable.columns(6).visible(false);
dataTable.columns(7).visible(false);
dataTable.columns(8).visible(false);
It can contain any number of records but I would like to take the values from all of the columns (only 1 is displayed to the user) and insert them into input fields (which may or may not be visible). I have successfully been able to select the rows using:
$('#example tbody').on( 'click', 'tr', function () {
if ( $(this).hasClass('selected') ) {
$(this).removeClass('selected');
}
else {
dataTable.$('tr.selected').removeClass('selected');
$(this).addClass('selected');
}
});
I have been looking into the Datatables API, row(), cells() etc and whilst I can view the data() method I simply can't see how to extract data from EACH cell on the row into the input text fields on the same webpage. I have also looked at fnGetSelectedData but I didn't get far as it always returned undefined via the console.
To explain the use case, it's essentially an Address Lookup. Each column in the table represents part of the address, I want to take the cells from the selected row and insert it into the form as a users selected address.
Any help is appreciated

SOLUTION
Use the code below to get data for the selected row:
var data = $('#example').DataTable().row('.selected').data();
Then you can populate your input fields as shown below:
$('#name').val(data[0]);
$('#email').val(data[1]);
See this jsFiddle for demonstration.
NOTES
You can simplify your initialization code:
var dataTable = $('#example').DataTable({
searching: false,
responsive: true
columnDefs: [
{
targets: [1,2,3,4,5,6,7,8],
visible: false
}
]
});

To get an object with the values use:
yourTableVariable.rows({ selected: true }).data();
Then you can do something like this to get specific value(example id):
yourTableVariable.rows({ selected: true }).data()[0].id;

Related

jquery kendo grid I need to get selected rows dataitems array even i paginate pagination serverside true

I am using jquery kendo grid Kendo UI v2019.2.514
serverPaging: true,
serverSorting: true,
serverFiltering: true,
pageSize: 15
Example given below but here there is no server side pagination
https://dojo.telerik.com/UHUKahIM
I need dataItmes of selected rows in on change event or some other event
Ex:- i selected 2 rows in page:1 and page :2 selected 3 rows so totally 5 rows, i need these selected 5 rows dataItems array in array variable.
Please help me on this
I tried like below
function onChange(e) {
var rows = e.sender.select();
rows.each(function(e) {
var grid = $("#grid").data("kendoGrid");
var dataItem = grid.dataItem(this);
console.log(dataItem);
})
};
but this is not working for my expectation, this is working only the current page i need all the pages selected records as a array
The DOJO example you posted shows how to get the selected ids between pages, using this.selectedKeyNames(). Use that method to get an array of dataItems from the dataSource:
function onChange(arg) {
let selectedIds = this.selectedKeyNames(),
dataItems = this.dataSource.data().toJSON().filter(dataItem => {
return selectedIds.indexOf(dataItem.ProductID.toString()) > -1;
});
console.log(dataItems);
}
Updated DOJO
Note: The property ProductId used in the code above must be the same set in the schema.model.id parameter:
schema: {
model: {
id: "ProductID"
}
}

Datatables.js with java servlet and per row submit button

I am creating a page where I'm using DataTables.js to display information and the plan is to have a submit button on each row that submits a form with the row information.
At first I used a jstl loop to generate the table which worked but this ran into some issue with having a tag in the loop of the table to submit each row.
So now, in the servlet, I have a List that is passed from the controller and to the servlet and is the converted to a Json string using Gson. In the console, when navigating to the page, I can confirm that the the string has the correct data since I printed it out in the console.
Now my question is how do I utilize this attribute, that I do set using req.setAttribute("allX", allX) to pass it to the JSP.
I have a script tag at the bottom of the JSP to populate the table which is
<script>
$(document).ready(function () {
var allx = ${allX}
$('#allTable').DataTable({
"data" : allx
});
});
</script>
Above in the jsp I have a tag with the id allTable.
What I really need help with is correctly displaying the data in the table from the Json string and then adding a submit button to each row that submits the information in the row back to the servlet, which at this point and will probably only ever be one data point per row. I'm okay with handling the data in the servlet and processing it for use elsewhere, its just this table data, I having a huge issue with.
Not sure, if I understood your question correctly, but I assume you have no issue in collecting the data and composing the response to the client, but having issues with displaying the data in the datatables on the client side.
You would want to send an array of objects, so datatables can display it properly. Each element in that array would be an object, describing a complete row. Here is an example:
// You can use array of objects. Each object will be a row in the table.
// Compose it on the server or client side and give to DataTables for processing.
// Your objects can have many keys. You can tell DataTables which to use. In this
// example, I use allX.id and allX.type, while ignoring allX.color.
var allX = [
{ id: '0', type: 'pencil', color: 'blue' },
{ id: '1', type: 'pen', color: 'orange' },
{ id: '2', type: 'marker', color: 'black' }
];
var table = $('#allTable').DataTable({
data: allX, // allX here is our array, which contains the data to display in the table
columns: [{
data: 'id', // object key to look for value
title: 'ID' // give a title to your column
},
{
data: 'type', // our second column description
title: 'Type'
},
{
width: '30%', // our buttons column
orderable: false // we will describe it further in 'columnDefs'
},
],
"columnDefs": [{
"targets": -1, // -1 = last column
"data": null, // no data for this column, instead we will show default content, described in 'defaultContent'
"defaultContent": "<button id='submit-btn'>Submit</button> <button id='delete-btn'>Delete</button>"
}],
});
// catch a button click event
$('#allTable').on('click', 'button', function() {
// create an object from a row data
var rowData = table.row($(this).parents('tr')).data();
// fire a function, based on the button id that was clicked
if (this.id === 'submit-btn') {
submitData(rowData);
} else if (this.id === 'delete-btn') {
deleteData(rowData);
}
});
function submitData(data) {
// Process your row data and submit here.
// e.g. data === { id: '1', type: 'pen', color: 'orange' }
// Even though your table shows only selected columns, the row data
// will still contain the complete object.
// I would recommend against sending a complete object. In your case,
// with a single data point, perhaps it is fine though. However,
// always send bare minimum. For example, if you want to delete an
// entry on the server side, just send the id of the entry and let
// the server locate it and delete it by id. It doesn't need all other
// fields.
}
function deleteData(data) {
// Just an example how you can have various buttons on each row.
}

Assigning selected rows as other grid datasource

I am working on setting up a scenario as following:
1) User is shown existing results on first grid
2) User can select multiple results and click an 'Edit' button which will extract the selected items from the first grid
3)Second grid will be populated with the rows the user has selected from the first grid and will allow them to make edits to the content
4)Pressing save will update the results and show the first grid with the rows updated
So far using drips and drabs of various forum threads (here and here), I have managed to accomplish the first two steps.
$("#editButton").kendoButton({
click: function () {
// extract selected results from the grid and send along with transition
var gridResults = $("#resultGrid").data("kendoGrid"); // sourceGrid
var gridConfig = $("#resultConfigGrid").data("kendoGrid"); // destinationGrid
gridResults.select().each(function () {
var dataItem = gridResults.dataItem($(this));
gridConfig.dataSource.add(dataItem);
});
gridConfig.refresh();
transitionToConfigGrid();
}
});
dataItem returns what i am expecting to see with regards to the selected item(s) - attached dataItem.png. I can see the gridConfig populating but with blank rows (gridBlankRows.png).
gridConfig setup:
$(document).ready(function () {
// build the custom column schema based on the number of lots - this can vary
var columnSchema = [];
columnSchema.push({ title: 'Date Time'});
for(var i = 0; i < $("#maxNumLots").data("value"); ++i)
{
columnSchema.push({
title: 'Lot ' + i,
columns: [{
title: 'Count'
}, {
title: 'Mean'
}, {
title: 'SD'
}]
});
}
columnSchema.push({ title: 'Comment'});
columnSchema.push({ title: 'Review Comment' });
// build the datasource with CU operations
var configDataSource = new kendo.data.DataSource({
transport: {
create: function(options) {},
update: function(options) {}
}
});
$("#resultConfigGrid").kendoGrid({
columns: columnSchema,
editable: true
});
});
I have run out of useful reference material to identify what I am doing wrong / what could be outstanding here. Any help/guidance would be greatly appreciated.
Furthermore, I will also need functionality to 'Add New' results. If possible I would like to use the same grid (with a blank datasource) in order to accomplish this. The user can then add rows to the second grid and save with similar functionality to the update functionality. So if there is any way to factor this into the response, I would appreciate it.
The following example...
http://dojo.telerik.com/EkiVO
...is a modified version of...
http://docs.telerik.com/kendo-ui/framework/datasource/crud#examples
A couple of notes:
it matters if you are adding plain objects to the second Grid's dataSource (gridConfig.dataSource.add(dataItem).toJSON();), or Kendo UI Model objects (gridConfig.dataSource.add(dataItem);). In the first case, you will need to pass back the updated values from Grid2 to Grid1, otherwise this will occur automatically;
there is no need to refresh() the second Grid after adding, removing or changing its data items
both Grid dataSources must be configured for CRUD operations, you can follow the CRUD documentation
the Grid does not persist its selection across rebinds, so if you want to preserve the selection in the first Grid after some values have been changed, use the approach described at Persist Row Selection

How to make DataTables show only subset of columns then allowing others to appear by toggling

I have the following JS
$(document).ready(function() {
var table = $('#example').DataTable( {
"scrollY": "200px",
"paging": false
} );
$('a.toggle-vis').on( 'click', function (e) {
e.preventDefault();
// Get the column API object
var column = table.column( $(this).attr('data-column') );
// Toggle the visibility
column.visible( ! column.visible() );
} );
} );
JSFiddle or DataTablesExample
Which produce the following table that allows user to toggle the six columns by clicking on the link next to Toggle column.
What I want to do then is to make the table to show only Name and Position column as default and hide the rest of columns. Only when the user toggle their preferred other columns then they will appear. How can this be achieved?
In reality I have ~50 columns to show. Currently it overflow the page.
Not sure what's the best way to display such case.
With ColVis
You need to use ColVis extension for Datatables.
Most likely you would want to hide some columns initially, you can do that using the code below.
var oTable = $('#example').DataTable({
"dom": 'C<"clear">lfrtip',
"columnDefs" : [
{ "targets": [4,5], "visible": false }
]
});
See this JSFiddle for demonstration.
Also ColVis extension allows you to group columns and toggle group visibility instead of individual columns which could be helpful if you have 50 fields.
If you have that many fields, I would also consider showing extra details or responsive extension along with ColVis, you may be able to integrate these together.
Without ColVis
It can also be done without ColVis using the code below:
HTML
<p>Toggle: Start date | Salary</p>
<table id="example" class="display" cellspacing="0" width="100%">
<!-- skipped -->
</table>
JavaScript
var oTable = $('#example').DataTable({
"dom": 'lfrtip',
"columnDefs" : [
{ "targets": [4,5], "visible": false }
]
});
$('a.column-toggle').on('click', function(e){
var column = oTable.column($(this).data('id'));
column.visible(!column.visible());
e.preventDefault();
});
See this JSFiddle for demonstration.
You could show the remaining information in the child table
see: https://www.datatables.net/examples/api/row_details.html

Hiding Columns in the Columns of the Column menu option based on condition

I am using Kendo Column Menu option for kendo grid.I want that while hiding/showing the columns through the third option i.e Column I want to hide the Menus if the title of that column is blank.
Here I want to Hide the RefValue4 and RefValue5 since it corresponding values are coming null from the database.so there is no need of showing these.
I am doing this way:
if (grid.dataSource.data()[0].RefName4==null) {
grid.hideColumn(18);
}
but not able to achieve the result.
Is enough checking the content of the first row of the grid (as you propose in your code sample(? If so, you can define a dataBound handler that hides columns as:
dataBound : function (e) {
// Get reference to the grid
var grid = e.sender;
// Get reference to received data
var data = e.sender.dataSource.data();
// Check that we actually received any data
if (data.length > 0) {
// Iterate on columns hiding those that in the first row have no data
$.each(grid.options.columns, function (idx, elem) {
if (!data[0][elem.field]) {
grid.hideColumn(idx);
}
});
}
}
This runs anytime that you receive data from the server but as I said, only checks for the content of the first but you can easily modify for checking all. What this does not implement is hiding the column title from the menu.
See a running example here: http://jsfiddle.net/OnaBai/XNcmt/67/
EDIT: If you need that columns with no data are not displayed but also do not show up in the menu, you need to configure columns in the grid without those columns. You can do it in runtime once the data is received doing something like:
// Fetch data from the DataSource
ds.fetch(function (d) {
// By default, no column in the grid
var columns = [];
// List of available column definitions
var definitions = [
{ field: "Id", hidden: true },
{ field: "FirstName", title: "First Name" },
{ field: "LastName", title: "Last Name" },
{ field: "City" },
{ field: "Position" }
];
// For each column in the definition check if there is data
$.each(definitions, function(idx, elem) {
if(d.items[0][elem.field]) {
// If there is data then copy the definition to columns
columns.push(elem);
}
});
// Use received data plus the columns definition computed
$("#grid").kendoGrid({
dataSource: d.items,
editable : false,
pageable : true,
columnMenu: true,
columns : columns
}).data("kendoGrid");
});
Where ds is the DataSource definition.
See it here : http://jsfiddle.net/OnaBai/XNcmt/69/

Categories

Resources