Handling filter event in ui-grid - angularjs

I am using angular ui-grid in my application to show data.
I have colmnDef set as follows.
$scope.grid =
data: 'userList'
enableColumnResizing: true
enableFiltering: true
enableRowSelection: true
enableRowHeaderSelection: false
enableSorting: true
minRowsToShow: 30
multiSelect: false
columnDefs: [
{
name: 'id'
field: 'id'
displayName: 'ID'
enableFiltering: false
maxWidth: 100
}
{ name: 'username', field: 'email' }
{ name: 'firstName', field: 'first_name' }
{ name: 'lastName', field: 'last_name' }
{ name: 'lastLoggedIn', field: 'last_sign_in_at', cellFilter: 'date : "medium"', enableFiltering: false }
{ name: 'locked', field: 'locked', displayName: 'Locked?', enableFiltering: false, maxWidth: 100 }
{
name: 'Impersonate',
cellTemplate: '<a class="small-button" ng-controller="AuthController" ng-click="impersonateUser({{row.entity.id}})">
<i class="fa fa-users"></i></a>',
enableFiltering: false,
enableSorting: false,
visible: $scope.hideImpersonate
}
{
name: 'Edit'
cellTemplate: '<i class="pencil-icon"></i>'
enableFiltering: false
enableSorting: false
width: 100
}
{
name: 'Delete'
cellTemplate: deleteCellTemplate1 + deleteCellTemplate2
enableFiltering: false
enableSorting: false
width: 100
}
]
onRegisterApi: (gridApi) -> $scope.gridApi = gridApi
I want to show message 'No Data Found' in the grid when user searches for a 'username' mentioned above which doesn't exist.
I tried following code, but it didn't work for me. I would like to know better approach towards this.
$scope.grid.$on('ngGridEventFilter', function(){
console.log('filter called');
});

Wow, seems like this should be a lot easier to accomplish... After a good bit of searching around, I found one way to determine the number of results is with the gridApi.grid.renderContainers.body.visibleRowCache object.
So I modified the filter example plunker on the ui-grid tutorial and incorporated a technique described in one of their github issue threads.
To accomplish it, you can transclude a conditional div into the ui-grid div, and show it when no results are found:
<div id="grid1" ui-grid="gridOptions" class="grid">
<div class="no-rows" ng-if="noFilteredResults">
<div class="msg">
<span>No Data Found</span>
</div>
</div>
</div>
In your controller you have to set a $watch on the gridApi.grid.renderContainers.body.visibleRowCache object:
$scope.noFilteredResults = false;
$scope.$watch(function() { return $scope.gridApi.grid.renderContainers.body.visibleRowCache.length; },
function(newVal, oldVal) {
if ( newVal === 0 ) {
$scope.noFilteredResults = true;
console.log('no rows!');
} else {
$scope.noFilteredResults = false;
}
});
If there's an easier way to get it done, it's not easy to find :) Hope that helps!

Related

populate Dropdownlist in ui grid dynamically

i have spent lots of hours finding a solution but no success every time i am finding a solution it ends up with static data not from any web API or database. i want dynamic data to be populated in drop down list in UI grid. i have read in one blog in which guy was saying for dynamic data we have to use editDropdownRowEntityOptionsArrayPath but i did not find any useful solution. any one can provide any useful information than i will be vary thankful. thanks in advance. this is what i have done.
$scope.listOptions = []; $scope.ddlist = [];
$http.get('http://localhost:26413/api/MenuVDN/GetVDNList')
.then(function (data) {
$scope.listOptions = data;
$scope.ddlist = $scope.listOptions.data.Table;
console.log($scope.ddlist);
})
$scope.gridOptions = {
enableColumnResizing: true,
enableSorting: true,
enableCellSelection: true,
canSelectRows: true,
// enableCellEdit: true,
columnDefs: [
{ field: 'NameEn', displayName: ' Menu Name', grouping: { groupPriority: 0 }, sort: { priority: 0, direction: 'asc' }, width: '25%' },
{ field: 'id', displayName: 'ID' },
{ field: 'language', displayName: 'VDN Language', grouping: { groupPriority: 1 }, sort: { priority: 1, direction: 'asc' } },
{ field: 'vdnname', displayName: 'VDN Name' },
{
field: 'vdnnum', displayName: 'VDN Number',
editableCellTemplate: 'ui-grid/dropdownEditor',
// editDropdownIdLabel: 'id',
editDropdownValueLabel: 'value',
// enableFocusedCellEdit: true,
enableCellEditOnFocus :true,
enableCellEdit: true,
editType: 'dropdown',
editDropdownRowEntityOptionsArrayPath : $scope.ddlist
// , cellEditableCondition: function( $scope ) { return true; }
}
]
};
plus i am getting response from webapi in json format like this.
{"Table":[{"id":2,"value":"AR-BOOKING-NEW (7101)"},
{"id":3,"value":"EN-BOOKIN-NEW (7102)"},
{"id":4,"value":"AR-BOOKING-CANCEL (7103)"},
{"id":5,"value":"EN-BOOKING-CANCEL (7104)"},
{"id":6,"value":"AR-BOOKING-MODIFY (7105)"}]}
$scope.columns = completedFiles.columns;
$scope.rows = completedFiles.rows;
//prepare custom column for ui-grid
var customColumns = [];
angular.forEach($scope.columns, function(column) {
customColumns.push({
field : column.fieldName,
displayName : column.displayName,
editable : column.editable,
dataType : column.dataType,
});
}
});
angular.forEach(customColumns, function(customColumn) {
customColumn['width'] = 200;
if (customColumn.dataType === 'dropDown') {
customColumn['cellTemplate'] = "<div class='ui-grid-cell-contents' id='col-description'><select class="form-control" data-ng-options="item in grid.appScope.arrayName track by item" ><option value="" selected hidden />/></select></div>";
customColumn['width'] = 180;
}
});
You can create custom template like above and after that just assign in $scope.gridOptions customColumns to columnDefs rather then defining the column definition there.

Updating cell data in ui-grid without page refresh

I have a table that I made using ui-grid. The table displays information about a list of news stories. In the final column, I am giving the user the ability to edit, delete, and/or make a news story.
Everything seems to be working fine with that - I am able to have a modal pop up, and after entering in the required information, I can see my data change on the server. If I refresh the page, I can also see my data change on the table. However, I would like the cell data to change without page refresh. It doesn't seem to be binding to my news data.
Here is the ui-grid:
$scope.news = getAdminNews.results;
/**
* ui-grid implementation
*/
$scope.gridOptions = {
data: 'news',
enableColumnResizing: true,
enableFiltering: true,
enableGridMenu: false,
enableColumnMenus: false,
paginationPageSizes: [25,50,75],
paginationPageSize: 25,
rowHeight: 75
};
$scope.gridOptions.columnDefs = [{
displayName: 'Title',
field: 'title.rendered',
filterCellFiltered: true,
sortCellFiltered: true,
width: '20%'
}, {
displayName: 'Body',
field: 'body',
width: '20%'
}, {
displayName: 'Created',
field: 'created',
type: 'date',
cellFilter: 'date:"yyyy-MM-dd"',
filterCellFiltered: true,
sortCellFiltered: true,
width: '20%',
sort: {
priority: 0
}
},
{
displayName: 'Actions',
displayName: 'Actions',
width: '20%',
enableSorting: false,
enableFiltering: false,
field: 'actions',
cellTemplate: 'table-cell-actions'
}
];
$scope.gridOptions.onRegisterApi = function(gridApi) {
$scope.gridApi = gridApi;
};
And one part of my controller which is working successfully:
$scope.newPost = function() {
ngDialog.openConfirm({
template: 'modalPostNew',
className: 'ngdialog-theme-default',
scope: $scope
}).then(function() {
var newPost = {
"id": 0,
"title": $scope.newPostForm.title
}
AdminNews.save(newPost);
toaster.pop('success', 'Updated', 'News item updated successfully.');
});
}
I needed to update my $scope.news data that ui-grid was populating the table with. Here is what my controller looks like now:
$scope.newPost = function() {
ngDialog.openConfirm({
template: 'modalPostNew',
className: 'ngdialog-theme-default',
scope: $scope
}).then(function() {
var newPost = {
"id": 0,
"title": $scope.newPostForm.title
}
AdminNews.save(newPost).$promise.then(function(response) {
var myObj = {
"id": response.data.id,
"title": {
"rendered": response.data.title
}
}
$scope.news.push(myObj);
});
toaster.pop('success', 'Updated', 'News item updated successfully.');
});
}

Force edit mode for individual rows ui grid 3.0

I have a need to have more than 1 cell editable at a time. I have an edit button per row from a columnDef I added. I would like the edit button to allow as many columns as I want editable based on a condition.
When I set a condition like below, this only checks if this condition is met when I double click the cell.
$scope.gridOptions.cellEditableCondition: function(scope){
scope.row.entity.name = "Jay"
}
Is there any way to invoke the grids 'Edit Mode' on an entire row for all cells that meet the condition?
If you Want to apply condition only on some columns of your grid below is the example:
columnDefs: [
// default
{ field: 'FileName', displayName: 'FileName', enableCellEdit: false, cellTooltip: true },
{ field: 'RootFilePath', displayName: 'RelativePath', cellTooltip: true, enableCellEdit: false },
{ name: 'File Properties', enableFiltering: false, cellTemplate: '<center><div>' + 'View' + '</div></center>' },
{ field: 'IsEditable', displayName: 'Editable/NonEditable', headerTooltip: true, enableCellEdit: false },
{ field: 'HttpPath', displayName: 'HttpPath', enableCellEdit: true, cellTooltip: true },
{ name: 'Generate HttpPath', cellTemplate: '<center><input type="checkbox" ng-model="row.entity.ToGenerateHttpPath", ng-checked="row.entity.ToGenerateHttpPath", ng-click="grid.appScope.generateHttpPath(row.entity.ToGenerateHttpPath,row.entity.HttpPath)"></center>', enableFiltering: false, headerTooltip: true, enableCellEdit: false },
{field: 'TopLevelSchemaComments', displayName: 'Top Level\n Comments', headerTooltip: true, enableFiltering: true, cellTooltip: true,
cellEditableCondition: function ($scope) {
// put your enable-edit code here, using values from $scope.row.entity and/or $scope.col.colDef as you desire
return $scope.row.entity.IsEditable; // in this example, we'll only allow editable rows to be edited
},
},
{ name: 'Remove', enableFiltering: false, cellTemplate: '<div><center><button ng-disabled ="!(row.entity.IsEditable)" class="fa fa-trash-o" ng-click="grid.appScope.Remove(row.entity.XsdSchemaID,row.entity.XbrlLinkbaseID)"></button></center></div>', enableCellEdit: false }, ]
if you want the enitre grid's all the column to follow the same condition then place the condition only in gridOptions before columnDefs. Below is the Example:
$scope.gridOptions1 = {
enableFiltering: true,
data: [],
showGridFooter: true,
enableGridMenu: true,
enableColumnResizing: true,
cellEditableCondition: function ($scope) {
// put your enable-edit code here, using values from $scope.row.entity and/or $scope.col.colDef as you desire
return $scope.row.entity.IsEditable; // in this example, we'll only allow editable rows to be edited
},
columnResize: true,
columnDefs: [
// default
{ field: 'FileName', displayName: 'FileName', cellTooltip: true },
{ field: 'RootFilePath', displayName: 'RelativePath', cellTooltip:true},
{ name: 'File Properties', enableFiltering: false, cellTemplate: '<center><div>' + 'View' + '</div></center>' },
{ field: 'IsEditable', displayName: 'Editable/NonEditable', headerTooltip: true},
{ field: 'HttpPath', displayName: 'HttpPath', cellTooltip: true },
{ name: 'Generate HttpPath', cellTemplate: '<center><input type="checkbox" ng-model="row.entity.ToGenerateHttpPath", ng-checked="row.entity.ToGenerateHttpPath", ng-click="grid.appScope.generateHttpPath(row.entity.ToGenerateHttpPath,row.entity.HttpPath)"></center>', enableFiltering: false, headerTooltip: true, enableCellEdit: false },
{field: 'TopLevelSchemaComments', displayName: 'Top Level\n Comments', headerTooltip: true, enableFiltering: true, cellTooltip: true},
{ name: 'Remove', enableFiltering: false, cellTemplate: '<div><center><button ng-disabled ="!(row.entity.IsEditable)" class="fa fa-trash-o" ng-click="grid.appScope.Remove(row.entity.XsdSchemaID,row.entity.XbrlLinkbaseID)"></button></center></div>', enableCellEdit: false }, ]
}
I've been working on a similar issue, which differs mainly in that rows are editable based on a flag in the data (rather than a stand-alone button as you have). You can see it in action here; here's the code in case that link breaks.
index.html:
<!DOCTYPE html>
<html ng-app="rowLockDemo">
<head>
<meta charset="utf-8" />
<title>Angular UI-Grid row-lock/cell-edit demo</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<script data-require="angular.js#1.2.x" src="https://code.angularjs.org/1.2.28/angular.js" data-semver="1.2.28"></script>
<script src="http://ui-grid.info/release/ui-grid-unstable.js"></script>
<link rel="stylesheet" href="http://ui-grid.info/release/ui-grid-unstable.css" type="text/css">
</head>
<body>
<div ng-controller="MainCtrl">
<div ui-grid="gridOptions" ui-grid-edit ui-grid-cellNav class="grid"></div>
<strong ng-show="msg.lastCellEdited">Last Edit:</strong> {{msg.lastCellEdited}}
</div>
<script src="app.js"></script>
</body>
</html>
app.js:
var app = angular.module('rowLockDemo', ['ui.grid', 'ui.grid.edit', 'ui.grid.cellNav']);
app.controller('MainCtrl', function($scope, $http) {
$scope.msg = {};
$scope.gridOptions = {
enableCellEdit: false, // set all columns to non-editable unless otherwise specified; cellEditableCondition won't override that
enableCellEditOnFocus: true, // set any editable column to allow edit on focus
cellEditableCondition: function($scope) {
// put your enable-edit code here, using values from $scope.row.entity and/or $scope.col.colDef as you desire
return $scope.row.entity.isActive; // in this example, we'll only allow active rows to be edited
}
};
$scope.gridOptions.columnDefs = [
{name: 'isActive', displayName: 'Edit Status', enableColumnMenu: false, cellTemplate: 'cellTemplate_lock.html'}, // displays isActive status as a button and allow toggling it
{name: 'name', enableCellEdit: true}, // editing is enabled for this column, but will be overridden per row by cellEditableCondition
{name: 'company', enableCellEdit: true} // same for this column
];
$scope.gridOptions.onRegisterApi = function(gridApi) {
$scope.gridApi = gridApi;
gridApi.edit.on.afterCellEdit($scope, function(rowEntity, colDef, newValue, oldValue) {
$scope.msg.lastCellEdited = 'ID: ' + rowEntity.id + ', Column: ' + colDef.name + ', New Value: ' + newValue + ', Old Value: ' + oldValue;
$scope.$apply();
});
};
$http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/500_complex.json').success(function(data) {
$scope.gridOptions.data = data;
});
})
cellTemplate_lock.html:
<!--
Button shows current state (locked/unlocked); clicking it toggles the state.
Initial button state is set by retrieved read-only grid data; lock state is not persisted.
-->
<button ng-click="row.entity.isActive = !row.entity.isActive" ng-model="row.entity.isActive" style="{{row.entity.isActive ? 'background-color: lightgreen' : ''}}">
{{ row.entity.isActive ? 'Unlocked' : 'Locked' }}
</button>

Angular ngGrid with a detail view

I would say that having a detail view for a grid is pretty standard, although I can't figure out for the life of me how I would accomplish this with ngGrid. I want a grid that I can expand a row and have it show the details of that row underneath.
Like the below grid:
How do I achieve this? Here is my code so far:
vm.filterOptions = {
filterText: '',
useExternalFilter: false
}
var columns = [{field: 'oper_status', displayName: 'Status', cellTemplate: '<div ng-class="{serverUp: row.getProperty(col.field) == 1}"></div>'},
{field: 'dns_name', displayName: 'Name'},
{field: 'mgmt_ip_address', displayName: 'IP'},
{field: 'model', displayName: 'Model'},
{field: 'boot_version', displayName: 'Version'}];
vm.gridOptions = {
data: 'vm.devices',
columnDefs: columns,
enableRowSelection: true,
multiSelect: false,
selectedItems: vm.selectedItems,
filterOptions: vm.filterOptions,
afterSelectionChange: function() {
vm.details = vm.selectedItems[0];
}
};
-html
<div ng-grid="vm.gridOptions" class="grid"></div>

ng-grid click edit to open pop-up

I've a ng-grid which has Edit, and Delete buttons at the bottom of the grid.
On clicking the Edit button, I want it to open a Modal pop-up with info. from selected rows shown in the modal.
This is my HTML.
<div class="gridStyle" ng-grid="gridOptions"><!--ng-grid-->
</div>
<button ng-click="??" ng- disabled="!singleSelection()">Edit</button>
<button ng-click="??" ng-disabled="disabled">Delete</button>
And my JS is as follows:
$scope.gridOptions = {
data: 'scheduleData.scheduleList',
columnDefs: [
{ field: 'id', displayName: 'ID', visible: false },
{ field: 'disabled', displayName: 'Enabled', cellFilter: 'checkmark' }
{ field: 'dpName', displayName: 'Description' },
{ field: 'dpType', displayName: 'Type' },
{ field: 'dpProtection', displayName: 'Protection' },
{ field: 'doProtectionParam', displayName: 'DP Protection Paramters', visible: false },
{ field: 'startDate', displayName: 'Start Date', visible: false, cellFilter: 'date:\'M/d/yy h:mm a\'' },
{ field: 'endDate', displayName: 'End Date', visible: false, cellFilter: 'date:\'M/d/yy h:mm a\'' },
{ field: 'recurrenceType', displayName: 'Recurrence' },
{ field: 'everyNth', displayName: 'Estimated Duration', visible: false },
enableCellSelection: false,
enableSorting: true,
enableColumnResize: true,
enableColumnReordering: true,
showColumnMenu: true,
showFilter: true,
showFooter: true,
enableRowselection: true,
multiSelect: true,
selectedItems: $scope.selections
};
Any help will be greatly appreciated.
Thanks
I got this to working making the foll. change to HTML
<button ng-click="openModal(selections[0])" ng- disabled="disableButtons(selections)">Edit</button>
And in my JS,
$scope.openModal = (selections) => {
var modalInstance = $modal.open({
templateUrl: 'link to URL',
controller:RelatedController,
resolve: {
schedule: function () {
return selections.id == null ? selections : selections.clone();
}
}
});
}

Resources