Slickgrid render() not keeping current cell edit active - editor

I have the event below on my dataview to handle when values are changed in code. The problem is that when this fires the call to render() causes any existing editor to be committed. I don't want that to happen. Or at least I want to start editing the cell that was actively being edited before render() was called. Any ideas on how to keep editor from committing or reopen it?
dataView.onRowsChanged.subscribe(function (e, args) {
grid.invalidateRows(args.rows);
grid.render();
dataView.syncGridSelection(grid, true);
});

figured it out. Changed my code to this and it just updates the cell and not the grid (the _.each is the same as a for loop, it's underscore js)
dataView.onRowsChanged.subscribe(function (e, args) {
_.each(args.rows, function (row) {
grid.updateRow(row);
})
dataView.syncGridSelection(grid, true);
});
additionally if you are using the enableAddRow=true in the gridOptions then you will need to do this when a row is added so it will add the row and reenable the editor.
dataView.onRowCountChanged.subscribe(function (e, args) {
//store the active cell and editor
var activeCell = grid.getActiveCell();
var activeEditor = grid.getCellEditor();
grid.render();
grid.updateRowCount();
//make the active cell editable
if (activeEditor) {
grid.setActiveCell(activeCell.row, activeCell.cell);
grid.editActiveCell();
}
dataView.syncGridSelection(grid, true);
});

Related

Vaadin addComponentColumn only works in last row

this.grid = new Grid<>(Person.class);
this.grid.setItems(personList);
this.grid.setSelectionMode(SelectionMode.MULTI);
this.grid.removeAllColumns();
this.grid.setColumns("firstname");
this.editButton = new Button(null, ImageIcons.EDIT.create());
this.editButton.getStyle().set("color", "#000000");
this.grid.addComponentColumn(person -> this.editButton);
this.deleteButton = new Button(null, IronIcons.DELETE_FOREVER.create());
this.deleteButton.getStyle().set("color", "#000000");
this.grid.addComponentColumn(person -> this.deleteButton);
this.addComponentAsFirst(this.grid);
I have a personList with several entries. The grid shows all these entries with their first name. But it only shows the buttons in the last row. What is the problem?
You use the very same Button instance for each row. You should create a new Button within the componentRenderer, so each row will have its own Button.
Try it like this:
this.grid = new Grid<>(Person.class, false);
this.grid.setItems(personList);
this.grid.setSelectionMode(SelectionMode.MULTI);
this.grid.setColumns("firstname");
this.grid.addComponentColumn(person -> {
// edit: added click listener for inline-editing of the person. Editor must be configured for this to work. See https://vaadin.com/components/vaadin-grid/java-examples/grid-editor
// You don't have to use inline-editing if you don't want. you can also edit the item in a separate Layout with Input fields and a Binder.
Button editButton = new Button(ImageIcons.EDIT.create(), click -> {
this.grid.getEditor().editItem(person);
});
editButton.getStyle().set("color", "#000000");
return editButton;
});
this.grid.addComponentColumn(person -> {
// edit: added click listener for person removal
Button deleteButton = new Button(null, IronIcons.DELETE_FOREVER.create(), click -> {
this.personDao.remove(person);
// TODO: when using an in-memory dataprovider, fetch all items again from service/dao and set them with grid.setItems(this.personDao.findAll());
// but that is not necessary when using a callback dataprovider, which I belive OP is using
this.grid.getDataProvider().refresh();
});
deleteButton.getStyle().set("color", "#000000");
return deleteButton;
}
this.addComponentAsFirst(this.grid);
Edit: a minor thing but I still wanted to mention it - You do some unnecessary creation of columns, only to remove them all again later. Instead of this you could tell the grid not to create these columns in the first place, by passing false as second parameter of the Grid constructor.
this.grid = new Grid(Person.class, false);
// instead of
this.grid = new Grid(Person.class);
this.grid.removeAllColumns();

Can you Listen for ShowBottomSheet on Close?

Imagine creating a bottom sheet as follows:
final PersistenBottomSheetController bottomSheetController = showBottomSheet(...);
How do I execute logic upon closing that bottom sheet?
It is a bit unidiomatic for Flutter widgets:
bottomSheetController.closed returns a Future when closing the bottom sheet, which allows for this logic:
bottomSheetController.closed.then((value) {
// this callback will be executed on close
});
Works with await as well:
await bottomSheetController.closed;
// code below this call will get executed upon close
final PersistentBottomSheetController<dynamic> bottomSheetController = scaffoldKey.currentState!.showBottomSheet((context) {
return Container();
});
await bottomSheetController.closed.then((value) {
// the code for working on drawer close
});

ListGrid put focus in the FilterEditor

I have a ListGrid defined like this:
ListGrid lgrid = new ListGrid();
ListGridField first = new ListGridField("first",first");
ListGridField second = new ListGridField("second ",second ");
lgrid.setFields(first, second);
lgrid.setShowFilterEditor(true);
¿How can i put the keyboard focus in the first filter editor field after i call show() in the layout?
Thxs in advance.
Depending on what your use case is (which would be useful to provide a more focused answer), the solution you posted might not be what you really need, because if you scroll on your ListGrid, it could trigger a new data fetch (if there are more records to show), and move the cursor to the filter editor as a result (if your user is editing some records at that point, the cursor moving to the filter row is not what she would want to happen!!).
In such a case, you probably just want to call grid.focusInFilterEditor("fieldToFocus") after the listGrid.show() statement or in the ClickHandler of some button you use to fetch the data, etc.
Anyway, you don't need the Timer either. This works:
listGrid.addDataArrivedHandler(new DataArrivedHandler() {
#Override
public void onDataArrived(DataArrivedEvent event) {
grid.focusInFilterEditor("fieldToFocus");
}
});
I got the solution, its focusInFilterEditor, this is an example to set the focus after the data arrived to the grid:
// Put the focus on the first listGrid field when is loaded
listGrid.addDataArrivedHandler(new DataArrivedHandler() {
#Override
public void onDataArrived(DataArrivedEvent event) {
Timer t = new Timer() {
public void run() {
if(listGrid.getFilterEditorCriteria() == null){
listGrid.focusInFilterEditor("fieldToFocus");
}
}
};
t.schedule(600);
}
});

Using a Button remove item from sortable list

I have a sortable div containers, that each contain a button to delete itself. This button calls a function which removes the div container from the DOM. Everything looks fine, until I begin to drag and re-order the sortable items. Now the deleted element does not show in the GUI (which is expected), however doing a check of the sortable array, seems to suggest it's still there.
How can I get it so that this array is properly updated during the removal? or during the sorting. Any help would be appreciated.
Below is my javascript.
$(function() {
// Make Cron Jobs Sortable
$("#controlContainer").sortable({
items: "> div:not(#controlHeader), serialize",
create: function(event, ui) {
cronJobOrder = $(this).sortable("toArray",{attribute: "id"});
},
update: function(event, ui) {
cronJobOrder = $(this).sortable("toArray",{attribute: "id"});
}
});
});
Then my function
// the variable being passed in is the "Delete" button reference, that way it can find the div container it's in.
function deleteCronJob(cronJob) {
var confirmation = window.confirm("Are You Sure?");
if (confirmation) {
$(cronJob).parents(".cronJobElement:eq(0)").fadeOut("medium", function() {
// Remove Item from cronJobOrder array
cronJobOrder.splice(cronJobOrder.indexOf($(this).attr("id")),1);
// Remove CronJob from View
$(this).attr("id").remove();
});
} else {
return null;
}
}
I set up for you a simple fiddle. Alerting the sortable elements as array (and the updates after the remove button is clicked). Build your stuff around it.
http://jsfiddle.net/K3Kxg/
function sortableArrayAlert() {
sortableArray = $('li').toArray();
alert(sortableArray);
}
$(function(){
sortableArrayAlert();
$('ul').sortable();
$('a').click(function(e){
e.preventDefault();
$(this).parent().remove().then(sortableArrayAlert());
});
});

Wijmo grid - Prevent row selection when clicking on a specific column

I have a Wijmo Grid which allows row selection, whenever a user click on any column.
And I added a column to display a tooltip with additional info of the specific record.
The problem is when this column is clicked, Wijmo automatically selects the current row.
I've read the documentation, there is no event before selecting a row or clicking on a row. The selectionChanged event is not useful in this case, because it is fired after selecting a row.
I cannot add a tr click event handler and make e.preventDefault, because in this case the tooltip would not appear.
How could I prevent row selection, depending on the column clicked?
There is no native way to do this. What you could do is, handle the currentCellChanging event and set the 'selectionMode' option to none based on the clicked cell.
var isLoaded = false;
$("#gridview2").wijgrid({
loading: function (e, args) {
isLoaded = false;
},
loaded: function (e, args) {
isLoaded = true;
},
currentCellChanging: function (e, args) {
if (isLoaded) {
if (args.cellIndex == 5) {
$(this).wijgrid({ selectionMode: 'none' });
}
else {
$(this).wijgrid({ selectionMode: 'singleRow' });
}
}
}
});
use selectionMode="none" work fine
which not select anything by default

Resources