How could I add custom row focus class in ag-grid - ag-grid

I want to control row focus process. I need to show confirm dialog on row focus change in my table.
I tried to do this with rowClassRules property, but as I understood that functionality apply classes when table rendering, after that row classes stop changing
rowClassRules = {
'custom-row-focus': (params) => {
return params.data.id === this.currentSelectedItem.id
}
}
currentSelectedItem set's when I click on the row

Found an answer in docs
https://www.ag-grid.com/javascript-grid-row-styles/#refresh-of-styles
If you refresh a row, or a cell is updated due to editing, the rowStyle, rowClass and rowClassRules are all applied again.
So, when I'm clicking to the row I should make something like that:
onClicked($event: RowClickedEvent) {
$event.node.setData({...$event.data});
}

Related

Ag-grid cell renderer doesn't update its rowIndex in real time?

I'm wondering how I can complete my cell renderer. The renderer adds a new row when clicking an icon, and removes it when clicked again. The problem is the invididual cell renderers row indexes do not change unless I hard refresh the entire grid (which then disables the state of the dropdown itself)
How can I complete this?
const insertIndex = params.rowIndex + 1;
this.eventListener = () => {
if (!this.eButton.classList.contains('open')) {
gridOptions.api.applyTransaction({add:[{step: this.dropdownValue, dropdownRow: true}], addIndex: insertIndex });
} else {
let rowData = [];
gridOptions.api.forEachNode(function (node) {
rowData.push(node);
});
let insertedRow = rowData[insertIndex];
gridOptions.api.applyTransaction({remove:[insertedRow.data]});
}
this.eButton.classList.toggle('open');
};
this.eButton.addEventListener('click', this.eventListener);
}
option 1: Hard refresh the grid, but I lose the 'open' status of the dropdown icon. How can i carry state over after a hard refresh?
option 2: Find a way that params.rowIndex is updated after applyTransaction.
Ive tried using the default rowGroup feature, however it hides all columns by default and I havent found a way to make it work the way I need.
The solution im after is a simple 'open/close' toggle for a single row underneath without affecting the other rows

Updating cell value from callback in ag grid

I need to update the value of one of the cells in a row in ag-grid as soon as the onCellEditingStopped callback is called (this happens when a user exits any other cell on that row).
I have this code which is based on the single cell update example at Ag grid single cell update
onCellEditingStopped: {function(event) {
event.node.setDataValue("cell_to_update","a new value");
}
}
which should update the cell with field "cell_to_update" but it doesnt.
I am wondering if that is because I am calling it from this specific callback?
One way is by forcing the refresh, like
onCellEditingStopped: {function(event) {
event.node.setDataValue("cell_to_update","a new value");
event.api.refreshCells({force:true});
}
}

ag-grid programmatically selecting row does not highlight

Using Angular 4 (typescript), I have some code like below using ag-grid 12.0.2. All I'm trying to do is load my grid and automatically (programmatically) select the first row.
:
this.gridOptions = ....
suppressCellSelection = true;
rowSelection = 'single'
:
loadRowData() {
this.rowData = [];
// build the row data array...
this.gridOptions.api.setRowData(this.rowData);
let node = this.gridOptions.api.getRowNode(...);
// console logging here shows node holds the intended row
node.setSelected(true);
// console logging here shows node.selected == true
// None of these succeeded in highlighting the first row
this.gridOptions.api.redrawRows({ rowNodes: [node] });
this.gridOptions.api.redrawRows();
this.gridOptions.api.refreshCells({ rowNodes: [node], force: true });
First node is selected but the row refuses to highlight in the grid. Otherwise, row selection by mouse works just fine. This code pattern is identical to the sample code here: https://www.ag-grid.com/javascript-grid-refresh/#gsc.tab=0 but it does not work.
Sorry I am not allowed to post the actual code.
The onGridReady means the grid is ready but the data is not.
Use the onFirstDataRendered method:
<ag-grid-angular (firstDataRendered)="onFirstDataRendered($event)">
</ag-grid-angular>
onFirstDataRendered(params) {
this.gridApi.getDisplayedRowAtIndex(0).setSelected(true);
}
This will automatically select the top row in the grid.
I had a similar issue, and came to the conclusion that onGridReady() was called before the rows were loaded. Just because the grid is ready doesn't mean your rows are ready.(I'm using ag-grid community version 19) The solution is to setup your api event handlers after your data has loaded. For demonstration purposes, I'll use a simple setTimeout(), to ensure some duration of time has passed before I interact with the grid. In real life you'll want to use some callback that gets fired when your data is loaded.
My requirement was that the handler resizes the grid on window resize (not relevant to you), and that clicking or navigating to a cell highlights the entire row (relevant to you), and I also noticed that the row associated with the selected cell was not being highlighted.
setUpGridHandlers({api}){
setTimeout(()=>{
api.sizeColumnsToFit();
window.addEventListener("resize", function() {
setTimeout(function() {
api.sizeColumnsToFit();
});
});
api.addEventListener('cellFocused',({rowIndex})=>api.getDisplayedRowAtIndex(rowIndex).setSelected(true));
},5000);
}
Since you want to select the first row on page load, you can do onething in constructor. But your gridApi, should be initialized in OnGridReady($event) method
this.gridApi.forEachNode((node) => {
if (node.rowIndex === 0) {
node.setSelected(true);
}
It's setSelected(true) that does this.
We were using MasterDetail feature, its a nested grid and on expanding a row we needed to change the selection to expanded one.
Expanding a row was handled in
detailCellRendererParams: {
getDetailRowData: loadNestedData,
detailGridOptions: #nestedDetailGridOptionsFor('child'),
}
and withing loadNesteddata, we get params using we can select expanded row as
params.node.parent.setSelected(true)
Hope this helps.

GWT CellTable keep focus on selected row

When I select a row in a CellTable which contains several columns, the whole row gets colored in yellow. It does not depend on which area of the row I click (which column of the row).
What I try to do is to keep the selected row colored in yellow as long as no other row of this very table is selected. At the moment, as soon as I click somewhere else in the browser, the row gets back its original color.
I tried to use a selection model, but this changed nothing. Do you have any advise or is this simply not possible, since the focus is managed by the browser? The behavior is the same in the Google showcase for the CellTable...
The selection model actually does what you want to do: it paints a row blue and the row does not change color if you click elsewhere in the page. (Only when another row is selected)
There are 2 selection models:
One that lets you select only one row, and another one that lets you select multiple rows.
MultiSelectionModel<Row> selectionModel = new MultiSelectionModel<Row>();
table.setSelectionModel(selectionModel);
SingleSelectionModel<Row> selectionModel = new SingleSelectionModel<Row>();
table.setSelectionModel(selectionModel);
The solution of user905374 did actually work. I mentioned in my first post that I already tried the solution with a selectionModel and that it did not work. This was partially true. It does work, but only if the table does NOT contain a CheckboxCell.
Following a working and the not working example. I think this might be a bug, but I am not sure if I miss something.
final CellTable<LicenceDto> licenseTable = new CellTable<LicenceDto>();
final SingleSelectionModel<LicenceDto> selectionModel = new SingleSelectionModel<LicenceDto>();
licenseTable.setSelectionModel(selectionModel);
//--- If I add this column, the selection does work.
Column<LicenceDto, String> workingColumn = new Column<LicenceDto, String>(new TextCell()) {
#Override
public String getValue(LicenceDto object) {
return "Works";
}
};
workingColumn.setFieldUpdater(new FieldUpdater<LicenceDto, String>() {
#Override
public void update(int index, LicenceDto object, String value) {
;
}
});
licenseTable.addColumn(workingColumn);
//--- If I add this column, the selection does NOT work anymore.
Column<LicenceDto, Boolean> notWorkingColumn = new Column<LicenceDto, Boolean>(new CheckboxCell(true, true)) {
#Override
public Boolean getValue(LicenceDto object) {
return object.getEnabled();
}
};
notWorkingColumn.setFieldUpdater(new FieldUpdater<LicenceDto, Boolean>() {
#Override
public void update(int index, LicenceDto object, Boolean value) {
presenter.enableLicense(object, value);
}
});
licenseTable.addColumn(notWorkingColumn);
You can even combine multiple cells and add them to the table (e.g. LinkActionCell etc). As long as there is no CheckboxCell, the blue selection with the SingleSelectionModel does work like a charm. Does anyone see what I do wrong with this CheckboxCell or is there a bug?
UPDATE
It was simply a usage error of me. The problem was that I set handlesSelection to true (second parameter of the CheckboxCell constructor) even thought I don't handle anything. Setting it to false solves the problem.
Bottomline: Use a selection model (e.g. SingleSelectionModel) and do not set the handlesSelection parameter to true of the CheckboxCell constructor to true, if you don't handle the selection by yourself.
You should observe the Showcase demo again. This time use the checkbox on the left most column i.e the first column. On selection the row turns blue indicating the row selection is made. This is when you have SelectionModel set up. Click on the page anywhere outside the CellTable/DataGrid the selection is not changed.
Now, instead of choosing the row via checkbox from first column, you click on a row in any other column. The row turns yellow. Click on the page anywhere outside the CellTable/DataGrid the focus/yellow is lost.
"colored in yellow" indicates row is under focus and being edited and not selected.
Note - you can force row selection by using click events per cell.
Try something like this:
CellTable table;
YourDataObject object = new YourDataObject(...);
SingleSelectionModel<YourDataObject> selectionModel =
new SingleSelectionModel<YourDataObject>();
table.setSelectionModel(selectionModel);
...
table.setSelected(object, true);
Use MultiSelectionModel if you wish more than one line to be highlighted.
Store the selected row's index. When user selects row, change row's style to some "selected-style" appropriate for your case (defined in your css file) and remove selected style from the previously selected row. Also don't forget to update selected row's index.
If you provide some code from the original version I help you out with some code with pleasure.

How to do single row expansion with CellTable?

I'm trying to use the new GWT CellTable widget but my table needs to support one row expansion, i.e. there is a zippy on the left of a row and when it's clicked, the row should expand to provide more detail information and this row should span across all columns. Is it possible to achieve this with the CellTable? How do I add a row that spans all columns between other rows dynamically?
Any help will be appreciated!
GWT 2.5 will add a CellTableBuilder with the exact goal of allowing this kind of things.
You can find a live example at http://showcase2.jlabanca-testing.appspot.com/#!CwCustomDataGrid (click on the "show friends" cells)
Can you not make the additional row invisible using getRowElement(int row) and using DOM methods to set display 'none' when rendered and as blank when the button, to show it, is hit.
I am working on the solution too and my plan for now is to use CSS classes + manual styles manipulation to make it look as I need. Not sure if I be able to merry it with GWT though: http://jsfiddle.net/7WFcF/
I took a different approach to solve this same problem.
The basic concept is using dom elements to add and remove rows based on an event. The following code is an abstract extension of CellTable. You'll want to call this method from your event that gets fired from the click to expand a row.
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NodeList;
public abstract class ActionCellTable<T> extends CellTable<T> {
protected abstract void addActionsColumn();
Integer previousSelectedRow = null;
public void displayRowDetail(int selectedRow, Element e){
//Get the tbody of the Cell Table
//Assumption that we want the first (only?) tbody.
Element tbody = this.getElement().getElementsByTagName("tbody").getItem(0);
//Get all the trs in the body
NodeList<Element> trs = tbody.getElementsByTagName("tr");
//remove previously selected view, if there was one
if(previousSelectedRow!=null){
trs.getItem(previousSelectedRow+1).removeFromParent();
//If the current is further down the list then the current your index will be one off.
if(selectedRow>previousSelectedRow)selectedRow--;
}
if(previousSelectedRow==null || selectedRow != previousSelectedRow){// if the are equal we don't want to do anything else
Element td = Document.get().createTDElement();
td.setAttribute("colspan", Integer.toString(trs.getItem(selectedRow).getChildNodes().getLength()));
td.appendChild(e);
Element tr = Document.get().createTRElement();
tr.appendChild(td);
tbody.insertAfter(tr, trs.getItem(selectedRow));
previousSelectedRow=selectedRow;
} else {
previousSelectedRow=null;
}
}
}
previousSelectedRow is used to track which item is "expanded", this could probably be achieved using classes or IDs. If needed I can elaborate more on the CellTable, events, views, and activities.