I try to use Backgrid.js. I have some grid (I just take server-mode example).
This library successfully built a grid for me. But I want map some cells to their equivalent. For example, I have "region_id" column. I want map region_id -> region_name. To complete this task, I subscribed to the event backgrid:rendered.
var grid = new Backgrid.Grid({
/////
collection: issues
});
grid.on('backgrid:rendered', function(g) {
$('tr').each(function (i, row) {
var $row = $(row);
console.log("Q");
});
});
But I get a fail. There is no iterating over rows of my table. But these rows exist in table. What is the problem?
Verify that both of the following is true:
you make a call to grid.render() method
issues variable refers to non-empty collection at the time of rendering
Unfortunately Backgrid fires the rendered event before the header, footer and the table itself are actually on the screen.
So when your event gets triggered there are no rows in DOM yet.
I solved my problem by calling my code after the
grid.render().$el
statement. After this table should be in DOM. At least header row was and that was all I needed.
I am stuck with old version of Backgrid 0.2.6. So bare in mind that my answer is from that perspective.
Related
I am using nested data trees in Tabulator.js and if I use the option dataTreeStartExpanded:true all nested rows will be expanded. I want only one be expanded on load/render? Is that possible?
Here is working jsFiddle to play around.
I found that there is a div with class tabulator-data-tree-control-expand or tabulator-data-tree-control-collapse. Changing the name in dev tools does nothing.
Currently it looks like
But I want to be like that after the web page loads
Maybe I can somehow click the + to expand. Tabulator has a listener there
But I do not know how to call it for that particular +.
oh, I found it in documentation.
.. a function that will be passed in a row component and the level of that row in the table (starting at 0), it should return a boolean value to indicate the rows expansion state:
var table = new Tabulator("#example-table", {
dataTree:true,
dataTreeStartExpanded:function(row, level){
return row.getData().driver; //expand rows where the "driver" data field is true;
},
});
and then in data you have to use new property driver:true
For reference, I am using DataTable.js version 1.10.21 and DataTables Select version 1.3.1
I have created a DataTable with a "Status" column that can be updated. This column also has a filter on it. The filter works perfectly after initial load of the table but after a cell in the status column has been changed, the filter doesn't seem to be seeing the updated data but, instead, still filters on the old data.
This is the js that is being used to update a particular cell in the status column:
NOTE: We've simplified the example to eliminate code that isn't an issue.
var row = document.getElementById("user-id-" + userId);
statusColumn = row.children[4];
statusColumn.innerText = "inactive";
setTimeout(function(){
$('.dataTable').DataTable().reload();
},2000);
I have attempted to use the reload(), draw(), and re-initializing the entire table using dataTable(). None of functions allows the table to filter correctly with the new value. The filter does work but it filters based on the old value that no longer exists in the table.
Below are two screenshots as a visual example.
1st screenshot: Me looking at newly loaded table and me filtering on the status "active.
I am then going to change Aaron McClendon (first row) to "inactive".
2nd screenshot: Me searching on the status "active" again. Aaron should no longer show up since he is now "inactive" but as you can see he does show in the "active" status filter yet his status has been changed to "inactive".
Filtering to other statuses and coming back does not change the results and the only way to begin filtering correctly on the updated data is by reloading the page.
Newly loaded table while filtering on the active status
After updating Aaron McClendon and filtering on the active status
You need to set the data of the cell using the api: https://datatables.net/reference/api/cell().data()
It's difficult to give a detailed answer since you didn't post any of the html markup or enough of your javascript, but based on what you provided, it's probably something like this:
var table = $('.dataTable').DataTable();
var row = document.getElementById("user-id-" + userId);
var statusColumn = row.children[4];
var cell = table.cell( statusColumn );
cell.data( "inactive" ).draw();
I've tried with no success to implement x-editable in bootstrap datatables, the reason being when i update an element from x editable, the datatable fails to recognize those changes.. i've tried updating the table, destroying it, hidden tags, but the main problem seems to be that the datatables fails to recognize any change after the initialization..
I add the rows via button click, when they get to the table, i run .editable on those elements. they become editable but the sorting and search of the datatables doesnt work..
Can anyone help me?
The problem is that for performance reasons, Datatables caches the table into memory so actually the DOM table is different from the in-memory table. And when you modify the DOM, it doesn't change the table in-memory.
Therefore, Datatables created a function helper : invalidate() that you can apply on a row http://datatables.net/reference/api/row%28%29.invalidate%28%29 (there is a multiple rows version too).
Or you can still use the function data() which is less CPU consuming (recommended).
I would do something like this :
$('.xeditable').on('save', function(e, params) {
var $tr = $(e.target).closest('tr');
var newValue = params.newValue;
//If you didn't save the datatable into a var table, you need to call this line :
//var table = $('#example').DataTable();
table.row(tr).data(newValue);
//Or table.row(tr).invalidate(); which should read from the DOM directly
});
I have three Tabs and in each tab, I have a Grid.
The data for each Grid is coming from a database, so I am using rowRenderer to populate the Grids. The following code is common for all three Grids:
<grid id="myGrid1" width="950px" sizedByContent="true" rowRenderer="com.example.renderer.MyRowRenderer">
The rows are constructed from Doublebox objects. The data is populated successfully.
The Problem:
I need to handle multiple-cell editing on the client side. The editing is done via mouse-clicking on a particular cell and entering a value.
As example let's say that the user edits first cell on the first row and the value should be
propagated to all other cells on the same row and in all three Grids (so also the two Grids which the user currently does not see, because they are in tabpanes).
I am using jQuery to do this value propagation and it works OK.
I am passing the jQuery as follows:
doublebox.setWidgetListener(Events.ON_CHANGING, jQuerySelectors);
doublebox.setWidgetListener(Events.ON_CHANGE, jQuerySelectors);
This makes it possible to change the value in 1 cell and the change is instantly (visually) seen in all other cells filtered by jQuery selectors.
The problem is that the value is visually distributed to all the cells, but when I try to save the Grid data back to the database, the background values are the old ones.
I am assuming that ZK-Grid component is not aware that jQuery changed all the cell values. Nevertheless if I manually click on a cell that already has the NEW value (enter/leave/change focus) when I save the grid the NEW value is correct in that particular cell. Maybe that's a hint how can I resolve this.
Code of how I extract the Grid values:
Grid tGrid = (Grid) event.getTarget().getFellow("myGrid1");
ListModel model = tGrid.getModel();
MyCustomRow tRow = (MyCustomRow)model.getElementAt(i);
The model for my Grid is a List of MyCustomRow:
myGrid1.setModel(new ListModelList(List<MyCustomRow> populatedList));
I have a couple of assumptions, but whatever I have tried, hasn't worked. I have in mind that jQuery events and ZK-Events are different and probably isolated in different contexts. (Although I have tried to fire events from jQuery and so on..)
Do you have any suggestions? As a whole is my approach correct or there's another way to do this? Thanks for your time in advance!
Your problem is exactly what you are expecting.
Zk has it's own event system and do not care about your jq,
cos it's jq and zk don't observ the DOM.
The ways to solve your problem.
Use the "ZK-Way":
Simply listen at server-side and chage things there.
I am not sure if not selected Tabs
are updateable, but I am sure you could update the Grid
components on the select event of the Tab.
Fire an zk-event your self:
All you need to know, is written in the zk doc.
Basically, you collect your data at client side, send
an Event to the server via zAu.send() extract the
data from the json object at serverside and update your Grids
I would prefer the first one, cos it's less work and there should not be
a notable difference in traffic.
I post the solution we came up with:
This is the javascript attached to each Doublebox in the Z-Grid
//getting the value of the clicked cell
var currVal = jq(this).val();
//getting the next cell (on the right of the clicked cell)
objCells = jq(this).parents('td').next().find('.z-doublebox');
// if there's a next cell (returned array has length) - set the value and
// fire ZK onChange Event
if (objCells.length) {
zk.Widget.$(jq(objCells).attr('id')).setValue(currVal);
zk.Widget.$(jq(objCells).attr('id')).fireOnChange();
} else { //otherwise we assume this is the last cell of the current tab
//So we get the current row, because we want to edit the cells in the same row in the next tabs
var currRow = jq(this).parents('tr').prevAll().length;
//finding the next cell, on the same row in the hidden tab and applying the same logic
objCellsHiddenTabs = jq(this).parents('.z-tabpanel').next().find('.z-row:eq(' + currRow + ')').find('.z-doublebox');
if (objCellsHiddenTabs.length) {
zk.Widget.$(jq(objCellsHiddenTabs).attr('id')).setValue(currVal);
zk.Widget.$(jq(objCellsHiddenTabs).attr('id')).fireOnChange();
}
}
The java code in the RowRenderer class looks something like this:
...
if (someBean != null) {
binder.bindBean("tBean", someBean);
Doublebox box = new Doublebox();
setDefaultStyle(box);
row.appendChild(box);
binder.addBinding(box, "value", "tBean.someSetter");
...
private void setDefaultStyle(Doublebox box) {
box.setFormat("#.00");
box.setConstraint("no negative,no empty");
box.setWidth("50px");
String customJS = ""; //the JS above
//this is used to visually see that you're editing multiple cells at once
String customJSNoFireOnChange = "jq(this).parents('td').nextAll().find('.z-doublebox').val(jq(this).val());";
box.setWidgetListener(Events.ON_CHANGING, customJSNoFireOnChange);
box.setWidgetListener(Events.ON_CHANGE, customJS);
}
What is interesting to notice is that ZK optimizes this fireOnChange Events and send only 1 ajax request to the server containing the updates to the necessary cells.
How can you add rows to a JQuery DataTable without redrawing the entire table?
The behavior I would like is for it to find the correct location (based on the sort) to insert the row into the table while maintaining scroll position of the table and pagination if any.
I was facing the same problem. The solution i found for this were a new function with the name
fnStandingRedraw http://datatables.net/plug-ins/api/fnStandingRedraw.
I added the above code to be able to use this function,
$.fn.dataTableExt.oApi.fnStandingRedraw = function (oSettings) {
if (oSettings.oFeatures.bServerSide === false) {
var before = oSettings._iDisplayStart;
oSettings.oApi._fnReDraw(oSettings);
// iDisplayStart has been reset to zero - so lets change it back
oSettings._iDisplayStart = before;
oSettings.oApi._fnCalculateEnd(oSettings);
}
// draw the 'current' page
oSettings.oApi._fnDraw(oSettings);
};
After that i execute the following commands,
theTable.fnAddData([reply], false);
theTable.fnStandingRedraw();
where,
theTable: is the datatable variable (var theTable = $('#example').dataTable();).
reply: is the information i add to a row of mine datatable. More on http://datatables.net/plug-ins/api/fnStandingRedraw.
The first command adds a row on the table without redrawing it. After this, the new row will not being displayed on the table.
The second command redraws the table, so the new raw will appear, but retain the current pagination settings.
This worked fine for me.
Use dataTable().fnAddData()
http://datatables.net/ref#fnAddData
Example:
http://www.datatables.net/release-datatables/examples/api/add_row.html