Force edit mode for individual rows ui grid 3.0 - angularjs

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>

Related

Handling filter event in ui-grid

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!

UI-Bootstrap Datepicker in ng-grid not working with enableCellEditOnFocus=true

I know how to have a working UI-Bootstrap-Datepicker inside an ng-grid cell's editableCellTemplate.
My Question:
It does not work anymore when I replace the enableCellEdit=true option with enableCellEditOnFocus=true (single-click on cell to edit). Does anyone have an Idea why it breaks and how to fix that?
var editableCellTemplateUsingDatePicker = '<input ng-class="\'colt\' col.index" datepicker-popup="dd.MM.yyyy" datepicker-append-to-body=true is-open="isOpen" ng-model="COL_FIELD" my-input="COL_FIELD"/>';
$scope.gridOptions = {
data: 'myData',
//enableCellEdit: true,
enableCellEditOnFocus: true,
enableCellSelection: true,
enableRowSelection: false,
columnDefs: [{
field: 'name',
displayName: 'Name'
}, {
field:'dateOfBirth',
displayName:'Date of Birth',
editableCellTemplate: editableCellTemplateUsingDatePicker,
cellFilter: 'date:"dd.MM.yyyy"',
}]
};
Plunker
Now, I found another way to get to the desired behaviour of single-click edit with the ui-bootstrap datepicker.
You can add ng-click="editCell()" to your custom cellTemplate to enter edit-mode through single-click of the cell. Here the working setup:
var cellTemplateEditOnClick = '<div class="ngCellText" ng-click="editCell()" ng-class="col.colIndex()"><span ng-cell-text>{{row.getProperty(col.field) CUSTOM_FILTER}}</span></div>';
$scope.gridOptions = {
data: 'myData',
enableCellEdit: true,
enableCellSelection: true,
enableRowSelection: false,
columnDefs: [{
field: 'name',
displayName: 'Name',
cellTemplate: cellTemplateEditOnClick.replace('CUSTOM_FILTER', '')
}, {
field:'dateOfBirth',
displayName:'Date of Birth',
editableCellTemplate: editableCellTemplateUsingDatePicker,
cellTemplate: cellTemplateEditOnClick.replace('CUSTOM_FILTER', '| date:"dd.MM.yyyy"')
}]
};
Plunker

Bind to field name containing a backslash in angular ui-grid

I have a data model that looks like this:
myData = [{
"ListName": "list1",
"domain\\UserA": true,
"UserB": true,
"userC": true
}, {
"ListName": "list2",
"domain\\UserA": true,
"UserB": true,
"userC": true
}];
and I am trying to bind in to a ui-grid like this:
$scope.gridOpts = {
data: myData,
columnDefs: [{
field: "ListName",
displayName: 'listName'
},
{
field: "domain\\UserA",
displayName: 'UserA',
cellTemplate: "<div class='ui-grid-cell-contents'><input type='checkbox' ng-checked='{{COL_FIELD CUSTOM_FILTERS}}' /></div>",
},
{
field: "UserB",
displayName: 'UserB',
cellTemplate: "<div class='ui-grid-cell-contents'><input type='checkbox' ng-checked='{{COL_FIELD CUSTOM_FILTERS}}' /></div>",
}
The user without the backslash works just fine, but I cannot bind the user with the embedded baskslash. How do I resolve this?
Plunkr is here : http://plnkr.co/edit/y61beZ4F8aKpHj83J9jx?p=preview
It is because (two slashes) "\" in the field gets resolved to (one slash) "\" while ui grid internally creates map based on the field name in the column definition provided. So if you are getting 2 slashes in the data's field name (i.e in the bound object's key) then update your column Def to have double slashes to match each slash in the key name. This will enable the internal field mapping with the key name in the data in sync
In your case change def to:-
columnDefs: [{
field: "ListName",
displayName: 'listName'
},{
field: "domain\\\\UserA", //<-- 4 slashes here to match 2 slash in the bound data's key
displayName: 'UserA',
cellTemplate: "<div class='ui-grid-cell-contents'><input type='checkbox' ng-checked='{{COL_FIELD CUSTOM_FILTERS}}' /></div>",
},
angular.module('app', ['ui.grid']).controller('ctrl', function($scope) {
var myData = [{
"ListName": "list1",
"domain\\UserA": true,
"UserB": true,
"userC": true
}, {
"ListName": "list2",
"domain\\UserA": true,
"UserB": true,
"userC": true
}];;
$scope.gridOpts = {
data: myData,
columnDefs: [{
field: "ListName",
displayName: 'listName'
}, {
field: "domain\\\\UserA",
displayName: 'UserA',
cellTemplate: "<div class='ui-grid-cell-contents'><input type='checkbox' ng-checked='{{COL_FIELD CUSTOM_FILTERS}}' /></div>",
}, {
field: "UserB",
displayName: 'UserB',
cellTemplate: "<div class='ui-grid-cell-contents'><input type='checkbox' ng-checked='{{COL_FIELD CUSTOM_FILTERS}}' /></div>",
}]
};
});
<link rel="stylesheet" href="http://ui-grid.info/release/ui-grid-unstable.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="http://ui-grid.info/release/ui-grid-unstable.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div ui-grid="gridOpts"></div>
</div>

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