I'm currently working on the Angular UI grid. The edit functionality is implemented and it works fine except one case when I push or remove any row to/from a grid at first after that I receive an incorrect rowEntity object during row editing. I believe it is easy to get a reason of "issue" who has valuable experience.
Let's say a grid contains two rows initially. Then I add a row to the top with: $scope.gridOptions.data.unshift(//here is an object);
Thus, there are already 3 rows in the grid. If I try to edit the third row, I'll get an rowEntity object with data from the current second row instead of the third.
onRegisterApi: function(gridApi) {
$scope.gridApi = gridApi;
$scope.gridApi.rowEdit.on.saveRow($scope, function (rowEntity) {
//the rowEntity object is incorrect here if any row was either added or removed before the row that is under edit action now
}
}
What am I doing wrong? What do I misunderstand or don't know? I could resolve it if it would be possible to pass a rendered index row in on.saveRow().
Reloaded DOM of the grid to get correct sequence of rowEntities.
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
I am showing a grid in a loop. Each time in the loop I am setting the datasource to a new table which is represented in an array but the grid doesn't change. The columns from the previous table are shown and the new table columns are never shown. The crazy thing is the data is updated ONLY if the columns on table1 also exist in table 2 or 3.
How can I get the grid to update the once the datasource is changed?
ChangeGrid(file){
this.fileData = file;
}
<kendo-grid [kendoGridBinding]=fileData [height]='200' [pageSize]="10" [pageable]="true" [sortable]="true" [filterable]="false" [groupable]="false">
</kendo-grid>
You are basically replacing your variable which has the reference of KendoGridBinding and you are replacing it with your new array, so binding is removed from your variable and is replaced by your array.
To show the changes sophisticatedly, you have to write your custom binding directive, follow the steps: http://www.telerik.com/kendo-angular-ui/components/grid/data-operations/data-binding/automatic-operations/
The shortcut: You can push or pop the array items, it will retain the binding which is present in your variable
ChangeGrid(file){
this.fileData.push(file[0]);
}
This is a problem I had with jQuery Datatables that I really don't know why it is happening in the first place!
I have multiple select elements which all filters the original data set. I do the filtering logic on the select change event.
This my Datatables init (using state saving, from the documentation) :
var table = $('#orders-listing').DataTable({
bStateSave: true,
bFilter:true,
paging: true,
bPaginate:true,
language: { url: /* Language File URL */ },
fnStateSave: function(oSettings, oData){
localStorage.setItem('DataTables_'+window.location.pathname, JSON.stringify(oData));
},
fnStateLoad: function(oSettings){
return JSON.parse(localStorage.getItem('DataTables_'+window.location.pathname));
}
});
And this is my filtering logic on the select change event:
$('.filter-select').on('change', function() {
$.fn.dataTable.ext.afnFiltering.push(
function(settings, data, dataIndex) {
// Some logic, return a boolean, wether we keep the row being processed or not.
}
);
table.draw();
$.fn.dataTable.ext.afnFiltering.pop();
});
Now, the filtering works fine. The rows, pagination links, everything changes accordingly.
But, once I click on the 2nd link on the pagination links, the original dataset returns.
Example: I had 200 rows in the first place, after filtering, it was reduced to 150 (So 50 rows were filtered, and removed from the original dataset), then once I click on the second link on the pagination, the original dataset returns, with the first 200 rows.
What am I missing here ? What is causing the original dataset to return when paginating ?
Any help is greatly appreciated. Thanks.
You're doing $.fn.dataTable.ext.afnFiltering.pop() immediately after drawing the table with draw() which removes your custom filter and it will no longer be applied if table is sorted, page is changed, etc.
Try adding $.fn.dataTable.ext.afnFiltering.pop() before $.fn.dataTable.ext.afnFiltering.push() to remove previous custom filter only on filter change but before adding a new filter.
I am using custom combo box for filtering the data in the grid. When i change the data in the grid
the filter is not getting refreshed with new data. I used grid.refreshFilters();. Still i face this issue.
Thanks
According to their docs:
Grid will not preserve row changes (adding , deleting), which was done when grid was in filtered state. After resetting back to not-filtered state, grid will restore deleted rows and remove newly created ones. To work around this issue you can use next order of actions:
unfilter grid
add|delete row
reset filter back
grid.filterBy(0, ''); // unfilter
grid._f_rowsBuffer = null; // clear cache
// Change grid data by adding / deleting rows here
grid.filterByAll(); // reset filters back
Are you loading data with parse? I used event onXLE to refresh filters after data are loaded.
grid.attachEvent('onXLE', function (grid_obj, count) {
grid_obj.refreshFilters();
});
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.