Add / Remove row(s) in ag-grid - angularjs

How to add or remove a row in ag-grid,
i try this, but not work
$scope.gridOptions.rowData.push(data);
and with this
scope.gridOptions.api.forEachNode( function(node) {
var data = node.data;
updatedNodes.push(vehicle);
});
$scope.gridOptions.api.refreshRows(updatedNodes);
Thanks

This is what worked for me with the ag-grid community version 22.1.1:
add new row
const row = //someNewRowDataHere
this.gridOptions.rowData.push(row)
this.gridApi.setRowData(this.gridOptions.rowData)
remove
const selectedRow = this.gridApi.getFocusedCell()
const id = this.gridOptions.rowData[selectedRow.rowIndex].i
this.gridOptions.rowData.splice(selectedRow.rowIndex, 1)
this.gridApi.setRowData(this.gridOptions.rowData)

The current version of ag-grid now supports this:
https://www.ag-grid.com/javascript-grid-insert-remove/
The grid does feature change detection but if you want/need to force a refresh, you can pick one of the refresh methods:
https://www.ag-grid.com/javascript-grid-refresh/

Since this answer is a bit old, just noting another update to the grid has emphasized the use of what the grid calls "transactions" for all grid CRUD operations:
https://www.ag-grid.com/javascript-grid-data-update/#gsc.tab=0

I personally like this approach
Add row
$( '#newRow' ).on( 'click', function() {
gridOptions.api.applyTransaction({ add: gridOptions.rowData });
} );
Remove row (ex. clicking on a bin-icon)
Works with rowDragManaged enabled
// remove row
$( document ).on( 'click', '#myGridFees .fa-trash-alt', function(e) {
$.fn.agGridRemoveRowByBinClick(gridFeeOptions, $(this));
});
/**
*
* #param agGridOption
* #param $this
*/
$.fn.agGridRemoveRowByBinClick = function(agGridOption, $this) {
let id = $this.closest('.ag-row').attr( 'row-id' );
agGridOption.api.applyTransaction({ remove: [ agGridOption.api.getRowNode(id).data ] });
}

Related

ExtJS 7 - Column filter issue with locked column

I encountered this bug where the column filter is incorrect if the grid has a locked column
Here's the fiddle: sencha fillde
Steps to reproduce:
(Do not apply any filter)
Open the "Email" column menu
Open "Name" column menu (this is the locked column)
Open "Phone" column menu (notice that the filter menu is incorrect, it is showing the filter for "Email" column).
For grid that has no 'locked' columns the filter menu is working fine, thanks for anyone who can help!
Okay, this one was a bit tricky. It turns out that for a locked grid, the Ext.grid.filters.Filters:onMenuCreate gets hit twice... one for each side of the grid's menu that shows. The problem is that in the onMenuCreate, the framework doesn't account for the 2 menus. It only cares about the last menu that gets created and destroys the previous menu's listeners. In onMenuBeforeShow, the framework does account for each side of the grid, so I extended this idea into an override. I would encourage you to create a Sencha Support ticket for this, and if you don't have access, let me know, so I can submit one. Fiddle here.
Ext.override(Ext.grid.filters.Filters, {
onMenuCreate: function (headerCt, menu) {
var me = this;
// TODO: OLD BAD CODE... this would destroy the first menu's listeners
// if (me.headerMenuListeners) {
// Ext.destroy(me.headerMenuListeners);
// me.headerMenuListeners = null;
// }
// me.headerMenuListeners = menu.on({
// beforeshow: me.onMenuBeforeShow,
// destroyable: true,
// scope: me
// });
// Just like in the onMenuBeforeShow, we need to create a hash of our menus
// and their listeners... if we don't, we remove the 1st menu's listeners
// when the 2nd menu is created
if (!me.headerMenuListeners) {
me.headerMenuListeners = {};
}
var parentTableId = headerCt.ownerCt.id;
var menuListener = me.headerMenuListeners[parentTableId];
if (menuListener) {
Ext.destroy(menuListener);
me.headerMenuListeners[parentTableId] = null;
}
me.headerMenuListeners[parentTableId] = menu.on({
beforeshow: me.onMenuBeforeShow,
destroyable: true,
scope: me
});
},
destroy: function () {
var me = this,
filterMenuItem = me.filterMenuItem,
item;
// TODO: ADDING THIS AND REMOVING FROM THE Ext.destroy on the next line
var headerMenuListeners = this.headerMenuListeners;
Ext.destroy(me.headerCtListeners, me.gridListeners);
me.bindStore(null);
me.sep = Ext.destroy(me.sep);
for (item in filterMenuItem) {
filterMenuItem[item].destroy();
}
// TODO: ADDING THIS AND REMOVING FROM THE Ext.destroy on the next line
for (item in headerMenuListeners) {
headerMenuListeners[item].destroy();
}
this.callParent();
}
});

ExtJS -- add tooltip to grid column header

I am using ExtJS 5. I have a dynamic grid meaning the column configurations, store fields, data etc are all coming from the backend.
Before I reconfigure the grid with the columns, I try to add a tooltip to the header using the data-qtip attribute but this does not work.
Here is the fiddle:
https://fiddle.sencha.com/#fiddle/1fr8
Snippet:
var cols = data_1.metaData.columns;
for(var i=0;i<cols.length;i++){
cols[i].header = "<font data-qtip='"+cols[i].header+"'>"+cols[i].header+"</font>";
}
grid.reconfigure(null, cols);
store.getProxy().data =data_1.data;
store.loadPage(1)
grid.getView().refresh();
Thanks!
Please don't overcomplicate things, the gridcolumn has a tooltip configuration which should work.
for(var i=0;i<cols.length;i++){
cols[i].tooltip = cols[i].header;
}
It doesn't work in your case, because the QuickTipManager has to be initialized first in Ext.onReady:
Ext.onReady(function(){
Ext.tip.QuickTipManager.init();
var store = ...
Please note that the header config in gridcolumn has been deprecated in favor of the text config.
You can also override initRenderData to set this application-wide. For example to always use the column text as a tooltip:
/**
* If a tooltip has not been set for a column header
* then always default to the column name
**/
Ext.override(Ext.grid.column.Column, {
initRenderData: function () {
var me = this;
if (Ext.isEmpty(me.tooltip)) {
me.tooltip = me.text;
}
return me.callParent(arguments);
}
});

Angular JS UI-Grid Delete Row

I'm new to ui-grid and I'm trying to implement a table in AngularJS as shown in the picture below. I'm trying to select a row and delete it using a delete button on that particular row. The ui-grid documentation requires us to use the gridApi but I can't find sufficient documentation for the same.
Please see a working example of how to delete a row here.
http://plnkr.co/edit/6TiFC6plEMJMD4U6QmyS?p=preview
The key is to use indexOf(row.entity) and not relying on row.index as it doesn't dynamically get updated.
$scope.deleteRow = function(row) {
var index = $scope.gridOptions.data.indexOf(row.entity);
$scope.gridOptions.data.splice(index, 1);
};
Generic approach
function deleteRow(row,grid) {
var i = grid.options.data.indexOf(row.entity);
grid.options.data.splice(i, 1);
}
You can use #Blousie solution as far as you adapt it to the newer API: https://github.com/angular-ui/ng-grid/blob/master/3.0_UPGRADE.md
Now "grid.appScope.edit(row.entity)" gives you access to your scope's "edit" function.
Something like this:
var removeTemplate = '<button class="btn btn-danger" ng-click="grid.appScope.removeRow(row)"><i class="glyphicon glyphicon-remove"></i></button>';
$scope.removeRow = function(row) {
var index = $scope.<yourDataModelProperty>.indexOf(row.entity);
if (index !== -1) {
$scope.<yourDataModelProperty>.splice(index, 1);
}
};
We need to use the $scope.grid.appScope. It is available in all templates. Besides that, you need to send the row object from the template, so that you can delete the row from the grid data.
jsfiddle: http://jsfiddle.net/3ryLqa9e/4/
cellTemplate:'<button class="btn primary" ng-click="grid.appScope.Delete(row)">Delete Me</button>'
$scope.Delete = function(row) {
var index = $scope.gridOptions.data.indexOf(row.entity);
$scope.gridOptions.data.splice(index, 1);
};
The other solutions provided here didn't worked for me(May be because of my latest different version of ui-grid). So removing element from the scope array worked for me. This should even work with other versions of ui-grid because grid must be updated when the data changes. (Thanks to Angular!!!)
I am using lodash to remove element from array and here is sample code:
$scope.deleteRow = function(row){
_.remove($scope.gridData, {
id: row.id
});
};
Just remove the row you want to delete from ui-grids data source model using splice.
For example
$scope.myGridOptions.data.splice(<YOUR ROW INDEX HERE>, 1);

how to reload gird data after add new data in to the store

I have two grids; I call them child and parent grid. When I add a new row(data) into the parent grid, I want to reload the parent grid. I was trying to edit it using the afteredit function in the code. If I uncomment out line number 2 in the alert, that works fine. But with out the alert, the newly added row is hidden. I don't understand what's going wrong in my code. Please can anyone tell me what to do after I add the new row in to my grid and how to reload the grid immediately?
this my afteredit function
afteredit : function (roweditor, changes, record, rowIndex)
{ //alert('alert me');
if (!roweditor.initialized) {
roweditor.initFields();
}
var fields = roweditor.items.items;
// Disable key fields if its not a new row
Ext.each(fields, function (field, i) {
field.setReadOnly(false);
field.removeClass('x-item-disabled');
});
this.grid.getSelectionModel().selectRow(0);
this.grid.getView().refresh();
},
xt.ux.grid.woerp =
{
configRowEditor:
{
saveText: "Save",
cancelText: "Cancel",
commitChangesText: WOERP.constants.gridCommitChanges,
errorText: 'Errors',
listeners:
{
beforeedit: WOERP.grid.handler.beforeedit,
validateedit: WOERP.grid.handler.validateedit,
canceledit: WOERP.grid.handler.canceledit,
afteredit: WOERP.grid.handler.afteredit,
aftershow: WOERP.grid.handler.aftershow,
move: WOERP.grid.handler.resize,
hide: function (p)
{
var mainBody = this.grid.getView().mainBody;
if (typeof mainBody != 'undefined')
{
var lastRow = Ext.fly(this.grid.getView().getRow(this.grid.getStore().getCount() - 1));
if (lastRow != null)
{
mainBody.setHeight(lastRow.getBottom() - mainBody.getTop(),
{
callback: function ()
{
mainBody.setHeight('auto');
}
});
}
}
},
afterlayout: WOERP.grid.handler.resize
}
},
AFAIK RowEditor is a plugin for GridPanel which changes underlying data which comes from store. Usually updates are also made by store. If you want to know when data is saved, you should attach event handler to store. Example:
grid.getStore().on('save', function(){ [...] });
Finally i found solution. When i add reload function in to the afteredit method that will be hide newly added row. So Grid reload After commit data in to that data grid store work well for me. Anyway thanks lot all the people who try to help
this my code look like
record.commit();
grid.getView().refresh();
I think there exist a Save button after editing grid.
So in the handler of Save you can catch the event
or using
Ext.getCmp('your_saveButtonId').on('click', function(component, e) {
// Here they will be checking for modified records and sending them to backend to save.
// So here also you can catch save event
}

ExtJs Gridpanel store refresh

I am binding ExtJs Gridpanel from database and add "Delete" button below my gridpanel. By using the delete button handler, I have deleted selected record on gridpanel. But, after deleting, the grid does not refresh (it is deleted from database but shows on grid because of no refresh).
How can I refresh grid after delete handler ?
Try refreshing the view:
Ext.getCmp('yourGridId').getView().refresh();
reload the ds to refresh grid.
ds.reload();
grid.store = store;
store.load({ params: { start: 0, limit: 20} });
grid.getView().refresh();
I had a similiar problem. All I needed to do was type store.load(); in the delete handler. There was no need to subsequently type grid.getView().refresh();.
Instead of all this you can also type store.remove(record) in the delete handler; - this ensures that the deleted record no longer shows on the grid.
try this grid.getView().refresh();
It's better to use store.remove than model.destroy.
Click handler for that button may looks like this:
destroy: function(button) {
var grid = button.up('grid');
var store = grid.getStore();
var selected = grid.getSelectionModel().getSelection();
if (selected && selected.length==1) {
store.remove(selected);
}
}
grid.getStore().reload({
callback: function(){
grid.getView().refresh();
}
});
Combination of Dasha's and MMT solutions:
Ext.getCmp('yourGridId').getView().ds.reload();
Another approach in 3.4 (don't know if this is proper Ext): You can have a delete handler like this, assuming every row has a 'delete' button.
handler: function(grid, rowIndex, colIndex) {
var rec = grid.getStore().getAt(rowIndex);
var id = rec.get('id');
// some DELETE/GET ajax callback here...
// pass in 'id' var or some key
// inside success
grid.getStore().removeAt(rowIndex);
}
Refresh Grid Store
Ext.getCmp('GridId').getStore().reload();
This will reload the grid store and get new data.

Resources