DataTables get data from render row parameter - javascript

I'm using DataTables pluging for Jquery, this is what I'm trying to do:
$('#familiars').DataTable({
processing: true,
serverSide: true,
ajax: "/familiars/list/",
columns: [
{ data: 'id' },
{ data: 'name' },
{ data: 'lastname' },
{ data: 'age' },
{ data: 'country' },
{ data: 'address' },
{ data: 'id', render : function (data, type, row){
btn='<a class="btn btn-success" href="#" data-toggle="modal" data-target="#modal-edit" onclick="setRow( \'' +row+ '\' )"/><i class="fa fa-edit"></i> Edit</a>';
return btn;
}
},
],
});
function setRow(row){
console.log(JSON.stringify(row));
console.log(row);
console.log(row.id);
console.log(row.name);
}
Pass the row parameter through the function to get all the data from the row and use it to a edit form modal but in the function setRow I only get object Object in all that's trys
If I use for example row.name or data in the onclick="setRow( \'' +row+ '\' )"/ get the info but I want get all in the row parameter or another way to get all the row info to the function.
Thanks for the help!

Related

Is there another way to pass an object to a function?

I have a datatable which is requesting data from an API. I am getting an object called full which has all the variables from the database. I can access integers without a problem and pass them from a function upon a button click but a string is bringing an error saying Uncaught SyntaxError: missing ) after argument
<script>
$(document).ready(function () {
$("#datatable").DataTable({
"processing": true,
"serverSide": true,
"filter": true,
"ajax": {
"url": '#TempData["api"]api/Versioning/Review',
headers: {
'Authorization': 'Bearer #HttpContextAccessor.HttpContext.Session.GetString("token")'
},
"type": "GET",
},
"columnDefs": [{
"targets": [0],
"visible": false,
"searchable": false
}],
"columns": [
{ "data": "name", "name": "Name", "autoWidth": true },
{ "data": "name", "name": "Name", "autoWidth": true },
{
data: "created_at",
"render": function (value) {
if (value === null) return "";
return moment(value).format('DD/MM/YYYY');
}
},
{
"render": function (data, type, full, meta) {
return '<button onclick="changes('+full.changes+')" class="btn btn-info"><i class="fas fa-info-circle"></i> Changes</button>';
}
},
{
"render": function (data, type, full, meta) {
return "<button id='remove' onclick='approve("+full+")' class='btn btn-success'><i class='fas fa-check-circle'></i> Accept Version</button>";
}
},
{
"render": function (data, type, full, meta) {
return "<button id='deny' onclick='deny(" + full.id + ")' class='btn btn-danger'><i class='fas fa-minus-circle'></i> " + full.changes + "</button>";
}
},
]
});
});
<script/>
Above i am requesting the data and i cant received the full.changes on my function and i cant even log it. But when am passing in an ID its working and i can log it. I also tried passing in the full object full and then accessing it in my function like full.changes but still its not working. Below is my function
<script>
function changes(changes) {
console.log(changes)
}
</script>
Basically what i want is to log the variable called changes which is in the full object but so far no success. Anyone know how i can pass it?
You should produce quotes around a string literal in your HTML. They are missing.
So replace this:
return '<button onclick="changes('+full.changes+')" class="btn btn-info"><i class="fas fa-info-circle"></i> Changes</button>';
With
return '<button onclick="changes(\''+full.changes+'\')" class="btn btn-info"><i class="fas fa-info-circle"></i> Changes</button>';
Do similar things (with the appropriate quote and escaping) in the other cases.

Edit DataTables source data, using form inside pop-up window

I have a datatable that fetches records from database with ajax. I want to add the edit tooltip like jquery-datatables-editor extension to datatables but for free. Is there any plugin to do this? if not, can any one help me to do this manually?
This is my JavaScript code:
$('#table_id').DataTable({
"serverSide": true,
"processing": true,
"ajax": function (data, callback, settings) {
$.ajax({
url: '/some url',
type: 'GET',
data: data,
success: function (data) {
console.log(data)
}
});
},
"columns": [{
"title": "edit",
"data": null,
"className": "center",
"defaultContent": ' Edit / Delete '
}, {
"title": "name",
"data": "name"
}, {
"title": "id",
"data": "id"
},
]
});
Since your question (and posted code sample) are mostly concerned with front-end part of editable rows feature I will focus on that primarily as backend logic is pretty much straightforward (update/insert data into storage upon AJAX-request receipt).
In order to implement that feature following logic I may suggest:
append (by means of createdRow option) some anchor (row().index() or source object id property, etc) to your source data within some <tr> attribute (e.g. rowindex), so you will know later on which entry to modify server-side:
$('table').DataTable({
...
createdRow: (tr, _, rowIndex) => $(tr).attr('rowindex', rowIndex)
})
append some anchor attribute (e.g. data-src) to your editor pop-up (I'll use bootstrap-4 modal for that purpose) <input> nodes to link those input fields to corresponding source object properties:
<div><label>PropertyX:</label><input data-src="propertyX"></input></div>
upon clicking edit button, grab corresponding row data, populate editor pop-up <input> fields with that data, pass anchor to edited row (rowindex attribute value) over to pop-up attribute:
//for table id 'example' handle clicking
//edit button having class 'edit'
$('#example').on('click', '.edit', function () {
//get clicked row invoking row() API method
//against DataTables object assigned to dataTable
const rowClicked = dataTable.row($(this).closest('tr'));
//populate edit form with row data by corresponding
//rowClicked property based on 'data-src' attribute
$.each($('#editform input'), function () {
$(this).val(rowClicked.data()[$(this).attr('data-src')]);
});
//set modal attribute rowindex to corresponding row index
$('#editform').attr('rowindex', rowClicked.index());
//open up edit form modal
$('#editform').modal('toggle');
});
upon completing row data editing, store <input> values into object:
const modifiedData = {};
$.each($('#editform input'), function(){
Object.assign(modifiedData, {[$(this).attr('data-src')]:$(this).val()});
});
POST data (along with corresponding rowindex) to the server and reload (ajax.reload()) up-to-date datatable upon success:
$.ajax({
url: '/editrow',
method: 'POST',
data: {id: $('#editform').attr('rowindex'), ...modifiedData},
success: () => {
$('#editform').modal('hide');
dataTable.ajax.reload();
}
});
Complete live demo of that method you might examine in your browser's DevTools by the following link with some bonus in form of row delete button.
Both HTML and jQuery code sample might look as follows (not executable as there's no supporting backend):
$(document).ready(() => {
//data table initialization
const dataTable = $('#example').DataTable({
ajax: {
url: '/getdata',
type: 'GET',
dataSrc: ''
},
dom: 't',
//use <tr> attribute 'rowindex' to anchor to source data row index
createdRow: (tr, _, rowIndex) => $(tr).attr('rowindex', rowIndex),
columns: [
{data: 'name', title: 'Name'},
//append 'Edit'/'Delete' buttons to the rightmost edge of the cell
{data: 'title', title: 'Title', render: (cellData, _, __, meta) => cellData+'<i class="delete fa fa-trash"></i><i class="edit fa fa-pencil"></i></button>'}
],
});
//delete button handler
$('#example').on('click', '.delete', function() {
//extract the index of the row to delete
//from 'rowindex' attribute
const rowIndex = $(this)
.closest('tr')
.attr('rowindex');
//do AJAX-call to the backend
$.ajax({
url: '/deleterow',
method: 'DELETE',
data: {id: rowIndex},
//re-draw datatable with up to date data
success: () => dataTable.ajax.reload()
});
});
//edit button handler (open up edit form modal)
$('#example').on('click', '.edit', function(){
//get clicked row
const rowClicked = dataTable.row($(this).closest('tr'));
//populate edit form with row data by corresponding
//rowClicked property based on 'data-src' attribute
$.each($('#editform input'), function(){
$(this).val(rowClicked.data()[$(this).attr('data-src')]);
});
//set modal attribute rowindex to corresponding row index
$('#editform').attr('rowindex', rowClicked.index());
//open up edit form modal
$('#editform').modal('toggle');
});
//submit edits handler
$('#editform').on('click', '#submitedits', function(){
//grab modified data into object
const modifiedData = {};
$.each($('#editform input'), function(){
Object.assign(modifiedData, {[$(this).attr('data-src')]:$(this).val()});
});
//send modified data to the backend
$.ajax({
url: '/editrow',
method: 'POST',
data: {id: $('#editform').attr('rowindex'), ...modifiedData},
success: () => {
//close the modal
$('#editform').modal('hide');
//re-draw datatable
dataTable.ajax.reload();
}
});
});
});
<!doctype html>
<html>
<head>
<script type="application/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="application/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="https://use.fontawesome.com/937a319e2f.js"></script>
<script type="application/javascript" src="/main.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="/main.css">
</head>
<body>
<!-- Table -->
<table id="example"></table>
<!-- Modal -->
<div class="modal fade" id="editform" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Row details</h5>
</div>
<div class="modal-body">
<form>
<div class="form-group"><label>Name:</label><input data-src="name" class="form-control"></input></div>
<div class="form-group"><label>Title:</label><input data-src="title" class="form-control"></input></div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-outline-dark" id="submitedits">Save changes</button>
</div>
</div>
</div>
</div>
</body>
</html>
If you mean JQUERY DATATABLE then you can insert input fields (that would still retain the cell data) for every column within your table row as you desire and set the borders of the input field to not display, with css.
EXAMPLE TABLE
<style>
.no-input-border {
border: 'none' !important; background: 'none' !important;
}
</style>
<table id="dynamic_table">
<thead>
<tr>
<th>Name</th>
<th>State</th>
<th>Address</th>
<th>Active</th>
<th>Action</th> <!-- This column would hold your buttons -->
</tr>
</thead>
<tbody>
</tbody>
</table>
EXAMPLE DATATABLE INITIALIZATION
var table = $('#dynamic_table').DataTable({
"order":[[ 0, 'asc' ]], // order by first column
"processing": true,
'paging': true,
'searching': true,
'retrieve': true,
'serverSide': true,
'ajax': {
'url': "your-ajax-url",
'type': 'POST'
},
'columns': [ //every **name:** value must be present in your json
{ data: null, name: 'name'},
{ data: null, name: 'state' },
{ data: null, name: 'address' },
{ data: null, name: 'active' },
{ data: null, name: 'id' } // column that holds your buttons
],
"columnDefs": [
{
"targets": 0, // column that inserts an input field
"data": 'name',
"orderable": false,
"createdCell": function (td, cellData, rowData, row, col){
return '<input type="text" class="no-input-border" name="name" value="'+cellData+'" />'
}
},
{
"targets": 1, // column that inserts an input field
"data": 'state',
"orderable": false,
"createdCell": function (td, cellData, rowData, row, col){
return '<input type="text" class="no-input-border" name="state" value="'+cellData+'" />'
}
},
{
"targets": 2, // column that inserts an input field
"data": 'address',
"orderable": false,
"createdCell": function (td, cellData, rowData, row, col){
return '<input type="text" class="no-input-border" name="state" value="'+cellData+'" />'
}
},
{
"targets": 3, // column that inserts an input field
"data": 'active',
"orderable": false,
"createdCell": function (td, cellData, rowData, row, col){
return '<input type="text" class="no-input-border" name="active" value="'+cellData+'" />'
}
},
{
"targets": 4, // column that holds your buttons
"data": 'id',
"orderable": false,
"createdCell": function (td, cellData, rowData, row, col){
return '<button class="edit_row">Edit<button>'
}
}
],
'responsive': true,
'initComplete': function(settings, json) {
//Run a function when table first initializes
},
'drawCallback': function( settings ) {
//Run a function anytime table reloads when paginating
}
});
EXAMPLE DATATABLE ROW EDIT FUNCTION
$('#dynamic_table tbody').on('click', '.edit_row', function () {
var row = table.row( $(this).parents('tr') ); // row that was clicked
var d = row.data(); // data of the row button that was clicked .eg. console.log(d.name)
var index = row.index();
var json = { // json to be sent
id: d.id,
name: table.cell(index,0).nodes().to$().find('input').val(),
state: table.cell(index,1).nodes().to$().find('input').val(),
address: table.cell(index,2).nodes().to$().find('input').val(),
active: table.cell(index,3).nodes().to$().find('input').val()
}
/*Your Ajax Function Here*/
});
RELOAD DATATABLE FUNCTION
table.ajax.reload( function ( json ) {
//Run function after table reloads
});
You can create a custom button in datatable. You can go to this documentation to know how it works. Now in the action you can call some function inside it when the user click it the button will call the function in javascript and do what you want inside it.
Here's example code.
$('#table_id').DataTable({
"serverSide": true,
"processing": true,
"ajax": function (data, callback, settings) {
$.ajax({
url: '/some url',
type: 'GET',
data: data,
success: function (data) {
console.log(data)
}
});
},
buttons: [
{ text: 'Add', name: 'btnAdd', action: function ( e, dt, node, config ) {
$.fn.addfunction();
}},
{ extend: 'selected', text: 'Edit', name: 'btnEdit', action: function ( e, dt, node, config ) {
$.fn.editfunction();
}},
{ extend: 'selected', text: 'Delete', name: 'btnDelete', action: function ( e, dt, node, config ) {
$.fn.deletefunction();
}},
],
"columns": [{
"title": "edit",
"data": null,
"className": "center",
"defaultContent": ' Edit / Delete '
}, {
"title": "name",
"data": "name"
}, {
"title": "id",
"data": "id"
},
]
});
$.fn.addfunction = function(){
//Your code here
}
$.fn.editfunction = function(){
//Your code here
}
$.fn.deletefunction = function(){
//Your code here
}
I added the idea of this document from datatables that create custom button and create and call function in jquery
There's also other way by using and giving id for the button. here's the example:
$('#table_id').DataTable({
"serverSide": true,
"processing": true,
"ajax": function (data, callback, settings) {
$.ajax({
url: '/some url',
type: 'GET',
data: data,
success: function (data) {
console.log(data)
}
});
},
buttons: [
{ text: 'Add', name: 'btnAdd',
attr:{
id: 'btnAdd'
}},
{ extend: 'selected', text: 'Edit', name: 'btnEdit',
attr:{
id: 'btnEdit'
}},
{ extend: 'selected', text: 'Delete', name: 'btnDelete',
attr:{
id: 'btnDelete'
}},
],
"columns": [{
"title": "edit",
"data": null,
"className": "center",
"defaultContent": ' Edit / Delete '
}, {
"title": "name",
"data": "name"
}, {
"title": "id",
"data": "id"
},
]
});
$(document).on('click', '#btnAdd', function(e)
{
e.preventDefault();
e.stopPropagation();
//your code here
});
$(document).on('click', '#btnEdit', function(e)
{
e.preventDefault();
e.stopPropagation();
//your code here
});
$(document).on('click', '#btnDelete', function(e)
{
e.preventDefault();
e.stopPropagation();
//your code here
});
Sorry for many Edit Hope it helps!

JQuery - how to add a button to an column from the table

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

Send jquery datatable column value to Javascript Function (Asp.Net MVC)

I am binding data to jquery datatable in asp.net mvc, i have an anchor tag in one of the columns of the grid where i am accessing / reading row data and sending that data to a javascript function. The problem which i am facing is, i am able read and send row values to the function which are numbers for example ProductID="1" or CategoryID="3" , but if i try to send ProductName="Chai" to the javscript function i get an error in the console, and if i remove the parameter "ProductName" everything works fine and the javascript function also gets triggered.
Following the console error:
"Index:1 Uncaught ReferenceError: Chai is not defined
at HTMLAnchorElement.onclick (Index:1)"
Following is my Code:
var BindDataTable = function (response) {
$("#tbProduct").DataTable({
"aaData": response,
"aoColumns": [
{ "mData": "ProductID" },
{ "mData": "ProductName" },
{ "mData": "SupplierID" },
{ "mData": "SupplierName" },
{ "mData": "SupplierCountry" },
{ "mData": "CategoryID" },
{ "mData": "CategoryName" },
{ "mData": "QuantityPerUnit" },
{ "mData": "UnitPrice" },
{
"render": function (data, type, full, meta) {
return '<i class="glyphicon glyphicon-pencil"></i>'
}
}
],
"columnDefs": [
{
"targets": [2],
"visible": false,
"searchable": false
},
{
"targets": [5],
"visible": false,
"searchable": false
}
],
"aaSorting": []
});
}
var EditProduct = function (ProductID, SuppID, CatID,PrdName) {
var url = "/Product/EditProduct?ProductID=" + ProductID + "&SuppID=" + SuppID + "&CatID=" + CatID;
$("#myModalBodyDiv1").load(url, function () {
$("#myModal1").modal("show");
})
}
Error:
My suggestion is that instead of playing around with that much string concatenations, what you can do is pass single object to your function and then use the required fields which needs to be passed as ajax call:
"render": function (data, type, full, meta) {
return '<i class="glyphicon glyphicon-pencil"></i>'
}
and in your js function use it :
var EditProduct = function (product) {
var url = "/Product/EditProduct?ProductID=" + product.ProductID+ "&SuppID=" + product.SupplierID + "&CatID=" + productCategoryID + "&ProdName=" + product.Prooductname ;
You can use the following approach in for passing string arguments to a JavaScript function:
<a onclick="javaScriptFunction(#p.ID, '#p.FileName');">#p.FileName</a>
function javaScriptFunction(id, fileName) {
...
}

reload datatable by ajax and json

I'm using datatable plugin and want to refresh table by ajax. I've read here to make my ajax return shows in table but it doesn't work. Here is my html code:
<button type="button" onclick="rld()">test</button>
<table id="sample_1">
<thead>
<tr>
<th> 1 </th>
<th> 2 </th>
<th> 3 </th>
</tr>
</thead>
</table>
My java function:
function rld(){
var table = $('#sample_1').DataTable( {
ajax: '<?php echo site_url('admin/test'); ?>',
deferRender: true,
columns: [
{ data: '1' },
{ data: '2' },
{ data: '3' }
],
rowId: 'extn',
select: true,
dom: 'Bfrtip',
buttons: [
{
text: 'Reload table',
action: function () {
table.ajax.reload();
}
}
]
} );
}
I can't get what the problem is. there in no alerts but in the console i get TypeError: f is undefined
and TypeError: c is undefined
Which i don't know why cause my json return is correct (checked in [JSONLint][3]).
Thanks in advance.
Thank you all for your attention :)
Found that i didn't call where the data goes when returned as json and the json field's name isn't equal to the column data field name. So make this adjustment:
function reload_table(){
var table = $('#sample_1').DataTable();
table.destroy();
var table = $('#sample_1').DataTable( {
"processing": true,
"dataType": 'json',
ajax: '<?php echo site_url('admin/relaod_table'); ?>',
deferRender: true,
columns: [
{ data: 'user_firstname' },
{ data: 'user_lastname' },
{ data: 'user_status' },
{ data: 'user_created_date' },
],
dom: 'Bfrtip',
buttons: [
{
text: 'Reload table',
action: function () {
table.ajax.reload();
}
}
]
} );
}

Categories