I am trying to set cellEditableCondition based on content of other cell in same row.
For that how do I pass row.entity to cellEditableCondition?
I tried passing row as arguement to function defined oncellEditableCondition but that row object does not have entity property.
I want something like below:
columnDefs: [{
name: 'column1',
field: 'name',
cellEditableCondition: function(row) {
return row.entity.lastname === 'Adams'
}
}, {
name: 'column2',
field: 'lastname'
}]
This small tweak to your code should do it:
var app = angular.module('app', ['ui.grid', 'ui.grid.edit']);
app.controller('MainCtrl', ['$scope', function($scope) {
$scope.gridOptions = {
columnDefs: [{
name: 'column1',
field: 'name',
cellEditableCondition: function(scope) {
return scope.row.entity.lastname === 'Adams'
}
}, {
name: 'column2',
field: 'lastname'
}],
data: [{name: "Tim", lastname: "Harker"},
{name: "Akash", lastname: "Adams"}]
}
}]);
div[ui-grid] {
height: 130px;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.0.2/ui-grid.min.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.0.2/ui-grid.min.css" />
<div ng-app="app" ng-controller="MainCtrl">
<div ui-grid="gridOptions" ui-grid-edit>
</div>
</div>
Let me know if you have any other questions. Happy to help further, if needed.
Related
When I'm finished editing a textarea in the grid the edit mode is not closing.
In this Plunker, if you double-click one of the cells under Title, the textarea opens correctly, but does not close after I click out of the cell.
http://plnkr.co/edit/9jrzziWOP6hWWQ1Gab39?p=preview
<div ui-grid="{ data: data, columnDefs: columnDefs }" ui-grid-edit></div>
var app = angular.module('app', ['ui.grid', 'ui.grid.edit']);
app.controller('MainCtrl', ['$scope', function ($scope) {
$scope.data = [
{ name: 'John', title: 'CEO' },
{ name: 'Jane', title: 'Developer' }
];
$scope.columnDefs = [
{name: 'name', enableCellEdit: false},
{ name: 'title',
cellEditableCondition: true,
enableCellEdit: true,
editType: 'textarea',
editableCellTemplate: '<textarea rows="4" cols="140" ng-model="MODEL_COL_FIELD"></textarea>'
}
];
}]);
Your problem has to do with the line:
editableCellTemplate: '<textarea rows="4" cols="140" ng-model="MODEL_COL_FIELD"></textarea>'
In the API for uiGrid-edit, it states that you must have valid html, templateCache Id, or url that returns html content to be compiled when edit mode is invoked. In your case, you haven't included a means for the textarea to exit edit mode. To remedy this, include ui-grid-editor in the tag as follows.
editableCellTemplate: '<textarea ui-grid-editor rows="4" cols="140" ng-model="MODEL_COL_FIELD"></textarea>'
I want to hide columns in ui-grid if there is no data present in that column. Like here the column "Issued By" and "Issued On" should be hidden as there is no data present.
HTML
<body ng-app="appHome">
<div ng-controller="ctrlRequestDetail">
<div class="gridStyle" ui-grid="gridInvUsage">
</div>
</div>
</body>
Controller.js
var myApp = angular.module('appHome', ['ui.grid']);
myApp.controller("ctrlRequestDetail", ['$scope', 'MetadataOrgFactory', function ($scope, MetadataOrgFactory) {
MetadataOrgFactory.getIdApiCall('geteventinvlist', $scope.reqDetailData.EventId, function (dataSuccess) {
//Web API call to Fetch Data
$scope.invUsageData = dataSuccess;
}, function (dataError) {
});
$scope.gridInvUsage = {
data: 'invUsageData',
columnDefs: [
{ field: 'InvBookStartTime', displayName: 'Book Start Time', cellFilter: 'date:"dd-MM-yyyy HH:mm"' },
{ field: 'InvBookEndTime', displayName: 'Book End Time', cellFilter: 'date:"dd-MM-yyyy HH:mm"' },
{ field: 'SourceInvNumber', displayName: 'Source Inventory' },
{ field: 'BookingRemarks', displayName: 'Booking Remarks' },
{ field: 'BookingStatus', displayName: 'Booking Status' },
{ field: 'AcceptRejectBy', displayName: 'Accept/Reject By' },
{ field: 'IssuedBy', displayName: 'Issued By' },
{ field: 'IssuedOnTime', displayName: 'Issued On' },
]
}
}])
How to achieve this functionality?
You could easily toggle the particular column visible property to show and hide the based on arrived data from API.
Code
$scope.columns = [
{ field: 'InvBookStartTime', displayName: 'Book Start Time', cellFilter: 'date:"dd-MM-yyyy HH:mm"' },
{ field: 'InvBookEndTime', displayName: 'Book End Time', cellFilter: 'date:"dd-MM-yyyy HH:mm"' },
{ field: 'SourceInvNumber', displayName: 'Source Inventory' },
{ field: 'BookingRemarks', displayName: 'Booking Remarks' },
{ field: 'BookingStatus', displayName: 'Booking Status' },
{ field: 'AcceptRejectBy', displayName: 'Accept/Reject By' },
{ field: 'IssuedBy', displayName: 'Issued By' },
{ field: 'IssuedOnTime', displayName: 'Issued On' },
];
$scope.gridOptions = {
data: 'invUsageData',
columnDefs: $scope.columns,
onRegisterApi: function(gridApi) {
$scope.gridApi = gridApi;
}
};
//Once data arrives, inside ajax success
//Web API call to Fetch Data
$scope.invUsageData = dataSuccess;
$scope.columns.forEach(function(col){
col.visible = $scope.invUsageData.filter(function(item){
return angular.isDefined(item[col. field]);
}).length;
});
Plunker Demo
Retrieve column definition via ajax and after updating columnDefs property refresh the grid to see the changes
function getColumns() {
$http.get('columns.json').then(function(response) {
$scope.columns = response.data;
$scope.gridOptions.columnDefs = $scope.columns;
$scope.columns.forEach(function(col) {
col.visible = $scope.invUsageData.filter(function(item) {
return angular.isDefined(item[col.field]);
}).length;
});
//updated grid after colDef changed.
$scope.gridApi.grid.refresh();
});
}
$scope.gridOptions = {
data: 'invUsageData',
columnDefs: $scope.columns,
onRegisterApi: function(gridApi) {
$scope.gridApi = gridApi;
}
};
Updated Demo
var app = angular.module("finApp", ["ui.grid"]);
app.controller(
"finController",
function($scope, $http) {
$http.get("url", "data")
.then(function(response) {
$scope.gridOptions.data = response.data;
}, function(errorResponse) {});
});
<link href="https://cdn.rawgit.com/angular-ui/bower-ui-grid/master/ui-grid.min.css" rel="stylesheet"/>
<script src="https://cdn.rawgit.com/angular-ui/bower-ui-grid/master/ui-grid.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ui-grid="gridOptions" class="grid"></div>
While executing above code I am getting below error:
angular.min.js:122 TypeError: Cannot read property 'data' of undefined
at new (ui-grid.js:3330)
at Object.invoke (angular.min.js:43)
at Q.instance (angular.min.js:93)
Initialize $scope.gridOptions = {} before the http request
Try this :
on success response from the API just concat the response data into the gridData array. As gridData is assigned back to the $scope.gridOptions.data only.
--------
JS file
--------
$scope.gridOptions = {
data: 'gridData',
..........,
..........,
..........
}
$scope.gridData = [];
$scope.gridData = $scope.gridData.concat(response.data);
Check response by log or alert
or Define grids column like below to test whether your ui-grid is working or not:
$scope.gridOptions = {
paginationPageSizes: [10, 20, 50],
paginationPageSize: 10,
enableColumnMenus: false,
columnDefs: [
{
width: '10%',
field: 'lastname',
displayName: 'Last Name'
},
{
width: '25%',
field: 'firstname',
displayName: 'First Name'
},
{
width: '8%',
field: 'Status',
displayName: 'Status'
},
{
width: '6%',
field: "actions",
displayName: "Actions",
cellTemplate: ''
}
]
};
And in JS
var app = angular.module("finApp", ["ui.grid"]);
app.controller(
"finController",
function($scope,$http){
$http.get("url","data")
.then(function(response) {
$scope.gridOptions.data =response.data;
},function(errorResponse) {
});
});
Refer this: UI GRID
I'd like to use NgMask in an angularGrid table to edit fields, but I don't know how.
The information from table cames from PHP and fields change depending on the search.
How could I implement it?
Link to NgMask: http://candreoliveira.github.io/bower_components/angular-mask/examples/index.html#/
The angularGrid code with a example:
var module = angular.module("example", ["angularGrid"]);
module.controller("exampleCtrl", function($scope, $timeout) {
var columnDefs = [
{displayName: "Default String", field: "defaultString", width: 150, editable: true, volatile: true, cellRenderer: cellRenderer, newValueHandler: numberNewValueHandler},
{displayName: "Upper Case Only", field: "upperCaseOnly", width: 150, volatile: true, editable: true, cellRenderer: cellRenderer, newValueHandler: numberNewValueHandler},
{displayName: "Number", field: 'number', width: 150, volatile: true, editable: true, cellRenderer: cellRenderer, newValueHandler: numberNewValueHandler},
{displayName: "Custom With Angular", field: "setAngular", width: 175, editable: true, volatile: true, cellRenderer: cellRenderer, newValueHandler: numberNewValueHandler},
{displayName: "Custom No Angular", field: "setNoAngular", width: 175, cellRenderer: cellRendererLink, cellTemplate: '{{row.entity[col.field]}}'
}];
var data = [
{ID:111, defaultString: 'APPLE', upperCaseOnly: 'APPLE', number: 11, setAngular: 'AAA', setNoAngular: 'AAA'},
{ID:222, defaultString: 'ORANGE', upperCaseOnly: 'ORANGE', number: 22, setAngular: 'BBB', setNoAngular: 'BBB'},
{ID:333, defaultString: 'BANANA', upperCaseOnly: 'BANANA', number: 33, setAngular: 'CCC', setNoAngular: 'CCC'},
{ID:444, defaultString: 'PEAR', upperCaseOnly: 'PEAR', number: 44, setAngular: 'DDD', setNoAngular: 'DDD'}
];
$scope.gridOptions = {
columnDefs: columnDefs,
rowData: data,
enableCellEditOnFocus: true,
enableSorting: true,
enableFilter: true,
};
});
I dont want to use ui-grid or something, just angularGrid and some mask.
You could dynamically create the columnsDef and specify in the editableCellTemplate your required mask.
The code works like this:
Get the data from server
Create fields from data keys
Extend the keys with the mappingObj.
Set mappedData to the scope, so ngGrid updates.
You could probably also add a validation property to your data and use this to create the column definition.
The uppercase mask is not working properly. I don't know what's wrong. If you enter some uppercase chars and then quickly a lowercase char it will be possible to enter.
Please have a look at the demo below or in this plunkr.
// main.js
var app = angular.module('myApp', ['ngGrid', 'ngMask']);
app.controller('MyCtrl', function($scope, $http) {
/*$scope.myData = [{name: "Moroni", age: 50, personalId: '123-234-445'},
{name: "Tiancum", age: 43, personalId: '223-234-445'},
{name: "Jacob", age: 27,personalId: '323-234-445'},
{name: "Nephi", age: 29, personalId: '423-234-445'},
{name: "Enos", age: 34, personalId: '523-234-445'}];
*/
$scope.myData = [];
$scope.colDef = [];
/*
var columnDef = [{ field: 'name', displayName: 'First Name', width: 90 },
{ field: 'age', width:50, cellClass: 'ageCell', headerClass: 'ageHeader',
editableCellTemplate: '<input type="number" ng-class="\'colt\' + col.index" ng-input="COL_FIELD" ng-model="COL_FIELD" />' },
{ field: 'personalId', displayName: 'ID', width: 150, editableCellTemplate: '<input ng-model="COL_FIELD" ng-input="COL_FIELD" mask="255-255-255"/>'}];
*/
$http.jsonp('http://www.mocky.io/v2/559304993c82b23c10eea6a6?callback=JSON_CALLBACK').then(function(response){
//'http://www.mocky.io/v2/5592fc513c82b22510eea699?callback=JSON_CALLBACK').then(function (response){
//$scope.colDef=response.data;//["ColumnName":data.something]
var data = response.data,
keys = [],
curKeys = '',
mappedData,
mappingObject = {
/*
name: {
displayName: 'First Name',
width: 90
},*/
age: {
width: 50,
cellClass: 'ageCell',
headerClass: 'ageHeader',
editableCellTemplate: '<input type="number" ng-class="\'colt\' + col.index" ng-input="COL_FIELD" ng-model="COL_FIELD" />'
},
personalId: {
displayName: 'ID',
width: 150,
editableCellTemplate: '<input ng-model="COL_FIELD" ng-input="COL_FIELD" mask="255-255-255"/>'
},
upperCaseOnly: {
displayName: 'uper case only property',
width: 100,
editableCellTemplate: '<input ng-model="COL_FIELD" ng-input="COL_FIELD" mask="A" repeat="10" limit="false" restrict="reject"/>'
}
};
$scope.myData = data;
data.forEach(function(row, index) {
curKeys = Object.keys(row);
console.log(curKeys);
curKeys.forEach(function(key) {
if (keys.indexOf(key) == -1)
keys.push(key);
});
});
mappedData = keys.map(function(key){
return angular.extend({field: key}, mappingObject[key]);
});
console.log(mappedData);
$scope.colDef = mappedData;
});
$scope.filter = {filterText:''};
$scope.gridOptions = {
data: 'myData',
enableFiltering: true,
filterOptions: $scope.filter,
showFilter: true,
enableCellEditOnFocus: true, //enables the editor on a single click, if you use enableCellEdit: true you would have to doubleclick
columnDefs: 'colDef'//columnDef
};
$scope.showRowCount = function() {
console.log($scope.gridOptions.ngGrid.filteredRows.length);
}
});
/*style.css*/
.gridStyle {
border: 1px solid rgb(212,212,212);
width: 400px;
height: 300px
}
<!DOCTYPE html>
<html ng-app="myApp">
<head lang="en">
<meta charset="utf-8">
<title>Custom Plunker</title>
<link rel="stylesheet" type="text/css" href="http://angular-ui.github.com/ng-grid/css/ng-grid.css" />
<link rel="stylesheet" type="text/css" href="style.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.1/angular.js"></script>
<script type="text/javascript" src="http://angular-ui.github.com/ng-grid/lib/ng-grid.debug.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/candreoliveira/ngMask/master/dist/ngMask.js"></script>
<script type="text/javascript" src="main.js"></script>
</head>
<body ng-controller="MyCtrl">
<input ng-model="filter.filterText"/>
<div class="gridStyle" ng-grid="gridOptions"></div>
currently visible items: {{gridOptions.ngGrid.filteredRows.length}}
</body>
</html>
i am using angularjs to write click event for selected row from ng-grid.but i want to write right click event for selected row from ng-grid in angularjs.below is my sample code for click event for selected row in ng-grid.
Sample.html:
<html>
<body>
<div ng-controller="tableController">
<div class="gridStyle" ng-grid="gridOptions"></div>
</div>
</body>
</html>
Sample.js:
app.controller('tableController', function($scope) {
$scope.myData = [{
name: "Moroni",
age: 50
}, {
name: "Tiancum",
age: 43
}, {
name: "Jacob",
age: 27
}, {
name: "Nephi",
age: 29
}, {
name: "Enos",
age: 34
}];
$scope.gridOptions = {
data: 'myData',
enableRowSelection: true,
columnDefs: [{
field: 'name',
displayName: 'Name',
cellTemplate: '<div ng-click="foo()" ng-bind="row.getProperty(col.field)"></div>'
}, {
field: 'age',
displayName: 'Age',
cellTemplate: '<div ng-click="foo()" ng-bind="row.getProperty(col.field)"></div>'
}
]
};
$scope.foo = function() {
alert('select');
}
});
please suggest me how to do this.
you may need a new directive, I find this
may help you
app.directive('ngRightClick', function($parse) {
return function(scope, element, attrs) {
var fn = $parse(attrs.ngRightClick);
element.bind('contextmenu', function(event) {
scope.$apply(function() {
event.preventDefault();
fn(scope, {$event:event});
});
});
};
});
http://jsfiddle.net/bcaudan/vTZZ5/