Javafx TableView cell/model change/updated event - tableview

I have a javafx TableView displaying data grabbed from a server and put into a model.. The model data will be updated every few seconds, new rows might be added or a particular model data may be modified..
Let's say I have a column called "Priority", user clicks on the priority header to sort the table based on priority to see LOW MEDIUM HIGH priorities. When a new row is added, the row is inserted correctly based on the sort.
Here's the problem, when an existing row's data is modified, for example, I use a button to change the priority of the first row.
btn.setOnAction(new EventHandler<ActionEvent>(){
#Override
Public void handle(ActionEvent event){
data.get(0).setPriority("HIGH");
}
});
the table doesn't reflect the change immediately, nor was the table sorted. I was only able to see the modified priority when I double clicked on the cell to edit or when I resort the table..
So here's my question:
Why doesn't my table reflect the changes immediately after it's data has been changed?
PS: I did set the table items using
table.setItems(data);
Is there a way for me to be notified when the data is modified, because if so I may be able to trigger some sort of refresh for my table to reflect those changes.. but I can't do that if I don't know when the data is modified

the table doesn't reflect the change immediately, nor was the table sorted. I was only able to see the modified priority when I double clicked on the cell to edit or when I resort the table..
Its because you are not refreshing the tableview after updating row on button click. Also you have to set sort order for tableview
btn.setOnAction(new EventHandler<ActionEvent>(){
#Override
Public void handle(ActionEvent event){
data.get(0).setPriority("HIGH");
priorityColumn.setSortType(TableColumn.SortType.ASCENDING);
tableview.refresh();
tableview.getSortOrder().clear();
tableview.getSortOrder().addAll(priorityColumn);
}
});
Is there a way for me to be notified when the data is modified, because if so I may be able to trigger some sort of refresh for my table to reflect those changes.. but I can't do that if I don't know when the data is modified
For this please refer to James_D answer in this post

Related

AngularSlickGrid problems when change the columndefinition

I'm developing an app using the amazing angularslickgrid.
Till now, i haven't got any problem, buy I found out an strange behaviour on it.
In the ngOnInit I wrote the following code:
ngOnInit(){
this.defineGridHeaders();
this.defineGridOptions();
this.obtainData();
}
Till this moment everything works well and the grid load correctly the data including the RowSelection column.
The problem is when I try to change the columndefinition, and perfrom a reset() like this:
this.defineGridHeaders();
this.angularGrid.gridService.resetGrid();
The new colums have been loaded correctly but i lose the rowSelection column.. :(
I've tried to include the defineGridOptions() function in the middle of the defineGridHeaders() and resetGrid() but the result is the same.
In the this.defineGridHeaders() I just perfom the following:
this.columnDefinitions = [];
[...FIELDS CREATION...]
const col = {
id,
name,
field,
sortable,
filterable,
type,
editor,
formatter,
filter,
outputType,
params,
minWidth: minwidth,
width: width,
header: header,
excludeFromExport,
excludeFromGridMenu,
excludeFromQuery,
excludeFromHeaderMenu
};
this.columnDefinitions.push(col);
Could someone help me on this?
Many Thanks!
Please note that I'm the author of Angular-Slickgrid and you opened an issue with the same question on GitHub, I'll simply reply with the same answer here
a reset is a reset, so it won't keep that. But I added the Row Selection in the Grid State not that long ago, so you could get it from there (just check the Grid State/Presets - Wiki. Dynamically adding a new column can be seen in this Example 3, you should look at the code on how to make it show up correctly (you can't just add it, you need to manually trigger a dirty change call, look at the example code for that)
Also to add a bit more to this, SlickGrid Row Selection is by row index, it's not by row data. Meaning that if your data changes when you refresh or something and you keep the row selection it will not synched anymore... all that to say, just remember, it's a row index, so pay attention when you want to keep or want to reapply a row selection.
If it's just to row selection that you lose, just save it before adding a column and put back the selection after adding the column. It's simple, get the row selection (with getSelectedRows) before you change the column definitions, add your new column and then put back the selection (with setSelectedRows).

Display multiple new rows in Kendo Grid

I am doing an inline add using Kendo Grid, but on the server side I am actually creating multiple records. The DataSourceRequest sends back all the newly created rows, but only one is added to the grid. The other added records may not show up in the grid at all until the grid is forced to query for the data again.
Is there a way for me to add multiple rows at once?
If not, is there a way to re-query the data and put all newly added models at the top?
In my controller function that creates the new records, I am returning the following. "models" contains all of the newly created records:
return this.Json(models.ToDataSourceResult(request, this.ModelState), JsonRequestBehavior.AllowGet);
I also have a similar issue when updating a row since the server may actually update multiple rows. Since "models" contains multiple models, the first one in the list may or may not be the actual model selected to be updated, so sometimes a different edited model will replace the model that was selected to be updated in the grid.
Thanks,
Rob
I ended up using the kendo grid datasource insert method to add any records returned by my controller that were not already in the grid. I did this in the RequestEnd event for the datasource.
In order for this to work for inline adds, I needed to make sure the first model in the list returned by the controller was always the model being added by the grid. For some reason the initial model being added does not have an ID until the dataBinding event is reached which occurs after the RequestEnd event. So on adds, I simply ignore the first model in the results because it is already in the grid.
Also, when editing rows that are manually inserted into the datasource and then cancelling the edit, the grid removes them from the datasource. I had to block this using the preventDefault() function in the DataBinding event when a "remove" action was encountered directly after editing a row that I manually inserted into the datasource.

Can't select the first row in a slickgrid after changing its data

I have a single slickgrid that uses a dataview with the row selection model. I frequently assign a completely different array to the dataview, switching the data in this grid.
I use this function to swap datasets in the grid:
function setData(dataArray, uniqueIdFieldName) {
dataView.beginUpdate();
dataView.setItems(dataArray, uniqueIdFieldName)
dataView.endUpdate();
grid.resizeCanvas();
grid.invalidate();
}
The first time I use this function (to load the initial data into an empty grid), everything works great. Every time after that, it loads the data fine but has a selection bug. I can't select the first row in the grid. However, if I select a row other than the first, the bug seems to correct itself and I can then select the first row again. When I change the data again with my function, I once again can't select the first row.
Anyone know why this is happening?
I found the problem and solution. The problem is slickgrid is keeping all the data about the active cell/row even after you completely change it's data with setItems(). The internal variable activeCell is still set to an index value, even though no cells are selected anymore. The solution is to call grid.resetActiveCell() before changing the data. So the working code looks like this:
function setData(dataArray, uniqueIdFieldName) {
grid.resetActiveCell(); //THIS LINE ADDED
dataView.beginUpdate();
dataView.setItems(dataArray, uniqueIdFieldName)
dataView.endUpdate();
grid.resizeCanvas();
grid.invalidate();
}
It seems to me that this is a bug in slickGrid. The setItems() function should reset the selection variables internally before changing the rows, since obviously the current selection is going to be null and void after resetting the items and not doing so leaves the entire selection model in a faulty state.

Is there a way to force a single row refresh with SlickGrid?

I have the amazing SlickGrid configured to access data asynchronously and post user changes back to the server asynchronously. In general terms, the server may modify a few fields of a row based on the user's changes. As such, after the row is updated I would like SlickGrid to refresh only that row without changing the rest of the view.
Does anyone know how to do this?
In my case, the field that changes on the server is a timestamp associated with the record that is updated by a database trigger. If the timestamp is out of date, the user has an old copy of data, and if they submit changes, they may overwrite a new copy. Since I can't find a way to trigger a refresh, the user cannot modify their own changes without refreshing the browser window (forcing a complete refresh).
You should be able to do this using grid.invalidateRow() and grid.render(). SlickGrid will re-render the affceted rows (assuming they are displayed in the currently visible viewport) without refreshing the entire page.
// Mark row 42 as changed and re-render the display
grid.invalidateRow(42);
grid.render();
For an example check out SlickGrid Example 14. (Click the Start Simulation button to see it in action)
function updateSlickgrid() {
dataView.setItems(tableName);
grid.invalidate();
}
Note : tableName could be the array or id etc.
I prefer storing all the slickgrid data in the array ex tableName = [];
Keep using the above function when it comes to displaying the data in slickgrid

Fire "afteredit" after edit the entire row in ExtJS grid?

I have an ExtJS editor grid which has some columns inside. I want to modify data on a record and auto save data to DB. But I just need save data after I complete editing all cells at the current row. I've used the event "afteredit" but it fired the event right after one cell was changed.
How can I keep that event not to fire until I've completed modifying all cells? Or could you please suggest another way to do this, not use the "afteredit" event?
Thank you so much.
You might take a look at Ext.ux.grid.RowEditor. It has an afteredit event that fires when the row is done being edited.
You can find the working example at http://dev.sencha.com/deploy/dev/examples/grid/row-editor.html
Here is my question back: Do you edit all the cells in a row? A better solution would be to use a "save" button to send the updated data back to the server and save it into DB.
Now, if you insist that all cells at a row will be modified, you can do the following:
In afteredit event handler:
Get the record being edited (you can get it by event.record)
Check if all the fields have been modified in the record. This can be done by inspecting the public property modified.
If all the fields are modified, proceed with sending the updated record to server for saving into DB.
When edit event has been fired, you should check modified config to check whether all of grid columns have been modified or not. After modifying, you can send them to your back end.
I think in your case it would be easier to have a button that you click to save the grid. you could access all the modified records by calling grid.store.getModifiedRecords() and send that to your backend service and do a mass update instead of updating a single row at a time.
You could use the rowdeselect event on the selection model (assuming that you use a Ext.grid.RowSelectionModel. Inside the event handler you can check if the record has been modified and react accordingly.
var grid = // your grid
grid.getSelectionModel().on("rowdeselect", function(selModel, rowIndex, record) {
if (record.dirty) {
// record has been modified
}
});

Resources