I want to use JsArray with the Webix component DataTable. But I have one problem. When I use JsArray format I can’t update the data in the Webix datagrid. Unfortunately, I can see only the beginning of its data. Check the sample to understand the issue:
var array1 = [ [1,"Marie","Oslo"],[2,"John","Los Angeles"],[3,"Kate","London"] ];
var array2 = [ [4,"Martin","Manchester"],[5,"Joana","Lisbon"],[6,"Ronaldo","Barcelona"],[7,"Matthew","Portland"] ];
webix.ui({
view:"button",
label:"test new data",
click: function() {
new_data()
}
});
webix.ui({
view:"datatable",
id: "mytable",
columns:[
{id:"data0", header:"ID" },
{id:"data1", header:"Name" },
{id:"data2", header:"City" }
],
datatype: "jsarray",
data: array1
});
function new_data () {
var mytable = $$("mytable");
mytable.parse(array2);
}
After pressing the button “test new data”, 4 new empty lines appear in the table.
To solve this issue, you should specify data format in the parse command
mytable.parse(array2, "jsarray");
The component will expect the json data, by default.
I hope that it'll help you)
Related
I am using plugin jQuery datatables and load my data which I have loaded in DOM at the bottom of page and initiates plugin in this way:
var myData = [
{
"id": 1,
"first_name": "John",
"last_name": "Doe"
}
];
$('#table').dataTable({
data: myData
columns: [
{ data: 'id' },
{ data: 'first_name' },
{ data: 'last_name' }
]
});
Now. after performing some action I want to get new data using ajax (but not ajax option build in datatables - don't get me wrong!) and update the table with these data. How can i do that using datatables API? The documentation is very confusing and I can not find a solution. Any help will be very much appreciated. Thanks.
SOLUTION: (Notice: this solution is for datatables version 1.10.4 (at the moment) not legacy version).
CLARIFICATION Per the API documentation (1.10.15), the API can be accessed three ways:
The modern definition of DataTables (upper camel case):
var datatable = $( selector ).DataTable();
The legacy definition of DataTables (lower camel case):
var datatable = $( selector ).dataTable().api();
Using the new syntax.
var datatable = new $.fn.dataTable.Api( selector );
Then load the data like so:
$.get('myUrl', function(newDataArray) {
datatable.clear();
datatable.rows.add(newDataArray);
datatable.draw();
});
Use draw(false) to stay on the same page after the data update.
API references:
https://datatables.net/reference/api/clear()
https://datatables.net/reference/api/rows.add()
https://datatables.net/reference/api/draw()
You can use:
$('#table').dataTable().fnClearTable();
$('#table').dataTable().fnAddData(myData2);
Jsfiddle
Update. And yes current documentation is not so good but if you are okay using older versions you can refer legacy documentation.
You need to destroy old data-table instance and then re-initialize data-table
First Check if data-table instance exist by using $.fn.dataTable.isDataTable
if exist then destroy it and then create new instance like this
if ($.fn.dataTable.isDataTable('#dataTableExample')) {
$('#dataTableExample').DataTable().destroy();
}
$('#dataTableExample').DataTable({
responsive: true,
destroy: true
});
Here is solution for legacy datatable 1.9.4
var myData = [
{
"id": 1,
"first_name": "Andy",
"last_name": "Anderson"
}
];
var myData2 = [
{
"id": 2,
"first_name": "Bob",
"last_name": "Benson"
}
];
$('#table').dataTable({
// data: myData,
aoColumns: [
{ mData: 'id' },
{ mData: 'first_name' },
{ mData: 'last_name' }
]
});
$('#table').dataTable().fnClearTable();
$('#table').dataTable().fnAddData(myData2);
In my case, I am not using the built in ajax api to feed Json to the table (this is due to some formatting that was rather difficult to implement inside the datatable's render callback).
My solution was to create the variable in the outer scope of the onload functions and the function that handles the data refresh (var table = null, for example).
Then I instantiate my table in the on load method
$(function () {
//.... some code here
table = $("#detailReportTable").DataTable();
.... more code here
});
and finally, in the function that handles the refresh, i invoke the clear() and destroy() method, fetch the data into the html table, and re-instantiate the datatable, as such:
function getOrderDetail() {
table.clear();
table.destroy();
...
$.ajax({
//.....api call here
});
....
table = $("#detailReportTable").DataTable();
}
I hope someone finds this useful!
I wrote an angular js table directive which has a different search field for each row.
$scope.standardColumns = [
DTColumnBuilder.newColumn('toto'),
DTColumnBuilder.newColumn('tata'),
DTColumnBuilder.newColumn('titi'),
];
var standardOptions = DTOptionsBuilder.newOptions();
standardOptions.withFnServerData(function (sSource, aoData, fnCallback) {
fnCallback({
'draw': 1,
'recordsTotal': 3,
'recordsFiltered': 3,
'data': [
{"toto":"John", "tata":"Anna", "titi":"Peter"},
{"toto":"John", "tata":"Anna", "titi":"Peter"},
{"toto":"John", "tata":"Anna", "titi":"Peter"}
]
});
});
You may see it here;
http://plnkr.co/edit/dTboNQ2sTW81Tq0lPXJe?p=preview
The problem is when each time I press the "update" button which updates the datatable, a new filter row is inserted.
What might be the reason of this? Do you think it could be a bug?
I've got a query tool I've been working on, which has an angular form that is filled out, and then when it's submitted it uses AJAX which returns JSON, which is then rendered into ui-grid, that JSON response looks like
{
"success": true,
"message": "",
"columns": ["first_name", "last_name", "company", "employed"]
"results": [
{first_name: "John", last_name: "Smith", company: "Abc Inc", employed: true},
{first_name: "Johnny", last_name: "Rocket", company: "Abc Inc", employed: true}]
}
I'm working on both the PHP and angular so I have full control over this JSON response if need be. I'm running into an issue when my JSON response from a first AJAX call is rendered, and then I run another, seperate AJAX call on the same page and get a new data set: this new data set does not render any of the columns that were not in the original data set. This is hugely problematic as the table is essentially cleared when none of the columns are the same, and I often need to load completely different data into ui-grid in this single page app.
When the JSON is recieved I simply bind the jsonResult.results to the old $scope.myData variable that ui-grid is bound to.
I've made a plunker isolating this issue. A dataset with a "punk" column is loaded, and then clicking "swap data" will try to load a dataset with "employee" column instead of "punk". I've so far looked into directives that will refresh or reload when the $scope.myData variable changes using $watch, and looked at finding something like $scope.columnDefs to let ui-grid know. Relatively new to angular and javascript so directives are still a bit over my head.
I have updated your plunker slightly:
$scope.swapData = function() {
if ($scope.gridOpts.data === data1) {
$scope.gridOpts.columnDefs = [
{ name:'firstName' },
{ name:'lastName' },
{ name:'company' },
{ name:'employee' }
];
$scope.gridOpts.data = data2;
//punk column changes to employee
}
else {
$scope.gridOpts.columnDefs = [
{ name:'firstName' },
{ name:'lastName' },
{ name:'company' },
{ name:'punk' }
];
$scope.gridOpts.data = data1;
//employee column changes to punk
}
};
http://plnkr.co/edit/OFt86knctJxcbtf2MwYI?p=preview
Since you have the columns in your json, it should be fairly easy to do.
One additional piece that I figured out with the help of Kevin Sage's answer and the plunker example... If you are using the backward-compatible "field" attribute the swapping does not work properly when there are field name overlaps between the two sets of column definitions. The column headers and the column widths are not rendered properly in this case. Using the "name" attribute of the column definition corrects this.
$scope.swapData = function() {
if ($scope.gridOpts.data === data1) {
$scope.gridOpts.columnDefs = [
{ field:'firstName' },
{ field:'lastName' },
{ field:'company' },
{ field:'employee' }
];
$scope.gridOpts.data = data2;
//punk column changes to employee
}
else {
$scope.gridOpts.columnDefs = [
{ field:'firstName' },
{ field:'lastName' },
{ field:'company' },
{ field:'punk' }
];
$scope.gridOpts.data = data1;
//employee column changes to punk
}
};
Example here: Plunker
My solution:
$http.get('url').success(function(res) {
// clear data
gridOptions.data.length = 0;
// update data in next digest
$timeout(function() {
gridOptions.data = res;
});
});
How can I add the following records (from the alert) into the Ext.data.ArrayStore? The commented out code (in newStore assignment) shows what data is set in the store originally and seems to work. The code in the loop shows what I've tried that did not work.
var newStore = new Ext.data.ArrayStore({
fields: [
'id',
'value'
]
//data: [[1, 'x'], [2, 'y']]
});
//alert(records.toSource());
Ext.each(records, function(rec) {
alert(rec.get('id') + ' ... ' + rec.get('value'));
//newStore.data.add(rec);
//Ext.apply(newStore, rec);
});
The .add() expect a record object. If your objects in the Ext.each() are in the format
{
id:"~~",
value:"~~"
}
simply calling newStore.add(rec); will work just fine.
If they are not you will need to build a psudo record by doing something like this:
Ext.each(records,function(rec){
newStore.add({id:rec.id,value:rec.value});
}
Here is a fiddle of a working example
http://jsfiddle.net/7a86L/
var arrayData = [
['Jay Garcia', 'MD'],
['Aaron Baker', 'VA'],
['Susan Smith', 'DC'],
['Mary Stein', 'DE'],
['Bryan Shanley', 'NJ'],
['Nyri Selgado', 'CA']
];
var store = Ext.create('Ext.data.ArrayStore', {
data : arrayData,
fields : ['personName', 'state']
});
console.log(store.first().data)
I'm working with a UI that has a (YUI2) JSON DataSource that's being used to populate a DataTable. What I would like to do is, when a value in the table gets updated, perform a simple animation on the cell whose value changed.
Here are some relevant snippets of code:
var columns = [
{key: 'foo'},
{key: 'bar'},
{key: 'baz'}
];
var dataSource = new YAHOO.util.DataSource('/someUrl');
dataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
dataSource.connXhrMode = 'queueRequests';
dataSource.responseSchema = {
resultsList: 'results',
fields: [
{key: 'foo'},
{key: 'bar'},
{key: 'baz'}
]
};
var dataTable = new YAHOO.widget.DataTable('container', columns, dataSource);
var callback = function() {
success: dataTable.onDataReturnReplaceRows,
failure: function() {
// error handling code
},
scope: dataTable
};
dataSource.setInterval(1000, null, callback);
And here's what I'd like to do with it:
dataTable.subscribe('cellUpdateEvent', function(record, column, oldData) {
var td = dataTable.getTdEl({record: record, column: column});
YAHOO.util.Dom.setStyle(td, 'backgroundColor', '#ffff00');
var animation = new YAHOO.util.ColorAnim(td, {
backgroundColor: {
to: '#ffffff';
}
});
animation.animate();
};
However, it doesn't seem like using cellUpdateEvent works. Does a cell that's updated as a result of the setInterval callback even fire a cellUpdateEvent?
It may be that I don't fully understand what's going on under the hood with DataTable. Perhaps the whole table is being redrawn every time the data is queried, so it doesn't know or care about changes to individual cells?. Is the solution to write my own specific function to replace onDataReturnReplaceRows? Could someone enlighten me on how I might go about accomplishing this?
Edit:
After digging through datatable-debug.js, it looks like onDataReturnReplaceRows won't fire the cellUpdateEvent. It calls reset() on the RecordSet that's backing the DataTable, which deletes all of the rows; it then re-populates the table with fresh data. I tried changing it to use onDataReturnUpdateRows, but that doesn't seem to work either.
Edit2:
To achieve the control that I wanted, I ended up writing my own <ul>-based data list that made a bit more sense for the problem I was trying to solve. Jenny's answer below should help solve this for most others, so I've accepted it as the solution.
cellUpdateEvent only fires in response to a call to updateCell(). What you want is to subscribe to the cellFormatEvent. There were a couple other issues in your code, so this should work:
dataTable.subscribe('cellFormatEvent', function(o) {
YAHOO.util.Dom.setStyle(o.el, 'backgroundColor', '#ffff00');
var animation = new YAHOO.util.ColorAnim(o.el, {
backgroundColor: {
to: '#ffffff'
}
});
animation.animate();
});
var callback = {
success: dataTable.onDataReturnReplaceRows,
failure: function() {
// error handling code
},
scope: dataTable
};
dataSource.setInterval(1000, null, callback);
dataTable.subscribe('cellFormatEvent',
function(o) {
YAHOO.util.Dom.setStyle(o.el, 'backgroundColor', '#ffff00');
var animation = new YAHOO.util.ColorAnim(o.el, {
backgroundColor: {
to: '#ffffff'
}
});
animation.animate();
});
var callback = {
success: dataTable.onDataReturnReplaceRows,
failure: function() {
// error handling code
},
scope: dataTable
};
dataSource.setInterval(1000, null, callback);
This example will not work beceause you added an interval and this is not the right solution. Because the function will be called each time.