How to show data without (key value) pair in jquery datatable? - javascript

I have data set of array:
[
{0:0, 1:"test-1", 2:1, 3:"data-1"},
{0:1, 1:"test-2", 2:2, 3:"data-2"},
{0:2, 1:"test-3", 2:3, 3:"data-3"},
];
How can I display data in a jQuery Datatable? I am not able to populate with this type of dataset.
Thank you for your time.

Datatable provide many ways how to generate table from dynamic source of data.
Example your data is from javascript, please refer documentation and example from this link:
https://datatables.net/examples/data_sources/js_array.html
And from your sample basic data, we can generate some basic table below:
var dataSet = [
{0:0, 1:"test-1", 2:1, 3:"data-1"},
{0:1, 1:"test-2", 2:2, 3:"data-2"},
{0:2, 1:"test-3", 2:3, 3:"data-3"},
];
$(document).ready(function() {
$('#example').DataTable( {
data: dataSet,
columns: [
{ title: "Index" },
{ title: "Test Name" },
{ title: "Sample No" },
{ title: "Data" },
]
} );
} );
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<link href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" rel="stylesheet" />
<table id="example" class="display" width="100%"></table>

Related

Append element to Datatable header

What I'd like to do is add a radio button next to the Search Bar on my datatable to allow searching by just one column, Store Number.
I was referred to drawCallback but I don't believe this does what I expect it to do. All the answers I find seem to be appending elements to rows/cols in the datatable, but not the header itself.
The selector for this header is #store-table_wrapper.
$('#store-table').DataTable({
"columnDefs": [{
"targets": [7, 8],
"visible": false,
"drawCallback": function() {
$('<input type="radio" name="store-number-filter-selector" />').appendTo('#store-table_wrapper');
}
}]
});
I believe, getting your radio button displayed you're half-way through, the really challenging part is to disable default search bar, since you're unlikely to override its default behavior (to search through the entire table).
However, you may use your own, custom searchbar, like on the following DEMO:
//define source data
const srcData = [
{id: 1, name: 'apple', category: 'fruit'},
{id: 2, name: 'raspberry', category: 'berry'},
{id: 3, name: 'carrot', category: 'vegie'}
];
//define dataTable object
const dataTable = $('#mytable').DataTable({
sDom: 't',
data: srcData,
columns: [
{data: 'id', title: 'id'},
{data: 'name', title: 'name'},
{data: 'category', title: 'category'}
],
//modify header nodes, by appending radios
initComplete: function() {
const table = this.api();
[1,2].forEach(column => table.column(column).header().innerHTML += `<input type="radio" name="searchflag" value="${column}" class="searchflag"></input>`);
}
});
//prevent sorting change upon radio click
$('input.searchflag').on('click', function(event) {
//clear search upon choosing the other radio
$('#searchfield').val('');
dataTable.search('').columns().search('').draw();
event.stopPropagation();
});
//searchbar keyup callback
$('#searchfield').on('keyup', function() {
//grab checked radio button value or search the entire table by default
let targetColumn = null;
targetColumn = $('input.searchflag:checked').val();
if(!targetColumn){
dataTable.search($(this).val()).draw();
}
else {
dataTable.column(targetColumn).search($(this).val()).draw();
}
})
input.searchflag {
float: left;
}
<!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 type="text/javascript" src="demo.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
</head>
<body>
<input id="searchfield"></input>
<table id="mytable"></table>
</body>
</html>

How to display a confirmation Modal with columns data on button click using Datatables

Having the DataTable below, I would like to display a dynamic popup or modal whenever a button is clicked which will serve as a confirmation modal.
The modal should contain data coming from the columns in the respected row in which the button was clicked.
#section scripts
{
<script>
$(document).ready(function() {
var table = $('#visitorsTable').DataTable({
"ajax": {
...
},
"columns": [
{ "data": "FirstName" },
{ "data": "LastName" },
{ "data": "Email" },
{ "data": "PhoneNumber" },
{ "data": "WifiCode" },
],
columnDefs: [
{
targets: [4],
render: function(wifiCode, b, data, d) {
if (wifiCode) {
var content = '<span>' + wifiCode + '</span>';
if (data.Email && data.PhoneNumber) {
content +=
'<button type="button" class="btnResendByMail>Email</button>'
return content;
}
}
}
]
});
$(document).on('click',
'.btnResendByMail',
function() {
$.ajax({
....
});
});
});
</script>
}
I've seen on DataTables site the "responsive" plugin.
However, on their example the modal is triggered always by clicking on the first column, and they display all the data of the row, not specific columns.
Any idea ?
...if I got your question properly, I believe, that's what you're trying to achieve:
srcData = [
{name: 'Albert', lastname: 'Einstein', email: 'emc2#gmail.com', code: 'XOIUE#WL'},
{name: 'Nikola', lastname: 'Tesla', email: 'firebolt#hotmail.com', code: 'OUWelks'},
{name: 'Rudolf', lastname: 'Hertz', email: 'radiohead#yahoo.com', code: 'joi23.xs'},
{name: 'James', lastname: 'Maxwell', email: 'magneto#gmail.com', code: 'Moiu23s'},
];
var dataTable = $('#mytable').DataTable({
sDom: 't',
data: srcData,
columns: [
{title: 'Name', data: 'name'},
{title: 'Lastname', data: 'lastname'},
{title: 'e-mail', data: 'email'},
{
title: 'Wi-Fi code',
data: 'code',
render: (data) => data+'<button style="float:right">e-mail</button>'
}
]
});
$('#mytable').on('click', 'button', event => {
let rowData = dataTable.row($(event.target).closest('tr')).data();
alert(`Are you sure you wanna send wi-fi code "${rowData.code}" to that sneaky bastard ${rowData.name} on his e-mail (${rowData.email})?`);
});
<!doctype html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
</head>
<body>
<table id="mytable"></table>
</body>
</html>

Kendo UI Grid handling missing values in column templates

I use Kendo UI Grid for displaying array data with objects having some fields missing. Here is js code:
var arr = [{b: "b1"}, {a: "a2", b: "b2"}];
$("#grid").kendoGrid({
dataSource: arr,
columns: [
{
title: "The A column",
field: 'a'
}, {
title: "The B column",
template: '<i>#=b#</i>'
}]
});
In this example the grid works well and displays missing "a" value in first row as empty cell.
When working with column template:
$("#grid").kendoGrid({
dataSource: arr,
columns: [
{
title: "The A column",
template: '<b>#=a#</b>'
}, {
title: "The B column",
template: '<i>#=b#</i>'
}]
});
It displays an error in console: Uncaught ReferenceError: a is not defined.
Even replacing template with:
template: '<b>#=a || ""#</b>'
expression instead does not help, so I have to manually set the missing values to empty string before constructing the table. Is there way to avoid this?
Instead of:
template: '<b>#=a || ""#</b>'
You should use:
template: '<b>#=data.a || ""#</b>'
Where data is predefined by KendoUI and is equal to the row data. Otherwise JavaScript doesn't know that a should be part of the data and thinks that it is a variable per-se throwing the error.
You can see it running in the following snippet
$(document).ready(function() {
var arr = [{b: "b1"}, {a: "a2", b: "b2"}];
$("#grid").kendoGrid({
dataSource: arr,
columns: [
{
title: "The A column",
template: '<b>#= data.a || ""#</b>'
}, {
title: "The B column",
template: '<i>#=b#</i>'
}]
});
});
<link rel="stylesheet" href="http://cdn.kendostatic.com/2015.1.429/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2015.1.429/styles/kendo.default.min.css">
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://cdn.kendostatic.com/2015.1.429/js/kendo.all.min.js"></script>
<div id="grid"></div>

Getting most basic Backgrid.js example working

I am trying to get the most basic example of backgrid.js to work. In other words, an example where i can drop the source folder into my xampp/htdocs folder and run without having to do anything else.
I have tried many ways to get the code to run but i cannot get anything to show up.
Here is the html page i made to try to see an example working.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="bootstrap/css/bootstrap.css"/>
<link rel="stylesheet" href="lib/backgrid.css"/>
<script src="jquery-1.10.2.min.js"></script>
<script src="underscore-min.js"></script>
<script src="backbone-min.js"></script>
<script src="lib/backgrid.js"></script>
</head>
<body>
<div id="grid">
<script type="text/javascript">
var Territory = Backbone.Model.extend({});
var Territories = Backbone.Collection.extend({
model: Territory,
url: "territories.json"
});
var territories = new Territories();
var columns = [{
name: "id", // The key of the model attribute
label: "ID", // The name to display in the header
editable: false, // By default every cell in a column is editable, but *ID* shouldn't be
// Defines a cell type, and ID is displayed as an integer without the ',' separating 1000s.
cell: Backgrid.IntegerCell.extend({
orderSeparator: ''
})
}, {
name: "name",
label: "Name",
// The cell type can be a reference of a Backgrid.Cell subclass, any Backgrid.Cell subclass instances like *id* above, or a string
cell: "string" // This is converted to "StringCell" and a corresponding class in the Backgrid package namespace is looked up
}, {
name: "pop",
label: "Population",
cell: "integer" // An integer cell is a number cell that displays humanized integers
}, {
name: "percentage",
label: "% of World Population",
cell: "number" // A cell type for floating point value, defaults to have a precision 2 decimal numbers
}, {
name: "date",
label: "Date",
cell: "date"
}, {
name: "url",
label: "URL",
cell: "uri" // Renders the value in an HTML anchor element
}];
// Initialize a new Grid instance
var grid = new Backgrid.Grid({
columns: columns,
collection: territories
});
// Render the grid and attach the root to your HTML document
$("#example-1-result").append(grid.render().el);
// Fetch some countries from the url
territories.fetch({reset: true});
</script>
</div>
</body>
</html>
Thanks for your time!
You seem to be adding the grid to non-existing element:
$("#example-1-result").append(grid.render().el);
Use $("#grid") instead and you should see the result.

Change js object to knockout js view model with nested observable arrays

I get a specific JSON from a server and want to be able to add/edit/delete items in nested arrays (variant lists, variants and columns) but I can't figure out how to do that with knockout.js.
I know that I need to change the properties in that JSON object to observables and I do it with the mapping plugin like shown under "Binding" and all values has been bind correctly - but if I change a value in an input field, the model/view is not updated automatically.
Why? Am I missing something?
So are nested arrays supported native by knockout.js without the need to write own code? How can I get this JSON to a full working knockout.js view model?
I use the current available versions (knockout: v2.1.0, mapping plugin: v2.3.2).
JSON
{
"VariantList": [
{
"ColumnCount": 1,
"Variants": [
{
"Title": "One column 100%",
"Columns": [
"100 %"
]
}
]
},
{
"ColumnCount": 2,
"Variants": [
{
"Title": "Two columns 50%/50%",
"Columns": [
"50%",
"50%"
]
},
{
"Title": "Two columns 75%/25%",
"Columns": [
"75%",
"25%"
]
}
]
}
]
}
HTML
<div data-bind="foreach: VariantList">
<h2 data-bind="text: ColumnCount"></h2>
<div data-bind="foreach: Variants">
<h3 data-bind="text: Title"></h3>
<table style="width:500px">
<tr>
<!-- ko foreach: Columns -->
<th><input data-bind="value: $data"/></th>
<!-- /ko -->
</tr>
<tr>
<!-- ko foreach: Columns -->
<td data-bind="style: {width:$data}, text:$data"></td>
<!-- /ko -->
</tr>
</table>
</div>
</div>
Binding
var viewModel;
$(function(){
viewModel = ko.mapping.fromJS(myJson);
ko.applyBindings(viewModel);
});
The issue is that the mapping plugin does not turn primitive values in an array into observables, by default. Even it it did, by the time that you bind $data against your input, you would have the unwrapped value of it rather than the observable.
The easiest way to make this work is to structure your data something like:
var data = {
"VariantList": [
{
"ColumnCount": 1,
"Variants": [
{
"Title": "One column 100%",
"Columns": [
{ value: "100 %" }
]
}
]
},
{
"ColumnCount": 2,
"Variants": [
{
"Title": "Two columns 50%/50%",
"Columns": [
{ value: "50%" },
{ value: "50%" }
]
},
{
"Title": "Two columns 75%/25%",
"Columns": [
{ value: "75%" },
{ value: "25%" }
]
}
]
}
]
};
Then you would bind against value in your loop on Columns. Here is a sample: http://jsfiddle.net/rniemeyer/MCnMX/
If you are not able to pull your data in this structure, then you can consider using the mapping options, to turn it into a structure like this. Here is a sample: http://jsfiddle.net/rniemeyer/sH3r2/
var mappingOptions = {
Columns: {
create: function(options) {
return { value: ko.observable(options.data) };
}
}
};
var viewModel = ko.mapping.fromJS(data, mappingOptions);
If you need to send your JSON back to the server in the same format that you received it, then there are a few options. I kind of like to do it like this: http://www.knockmeout.net/2011/04/controlling-how-object-is-converted-to.html. Here is a sample with your data: http://jsfiddle.net/rniemeyer/Eed2R/
var Value = function(val) {
this.value = ko.observable(val);
};
Value.prototype.toJSON = function() {
return ko.utils.unwrapObservable(this.value);
};
var mappingOptions = {
Columns: {
create: function(options) {
return new Value(options.data);
}
}
};
var viewModel = ko.mapping.fromJS(data, mappingOptions);

Categories