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
Related
I have angular ui grid in application and I want a field to be hide if any field value is null or empty.
$scope.gridOptions = {
paginationPageSize: 10,
columnDefs: [
{ displayName: 'First Name', field: 'firstName', headerCellClass: "GridHeader" },
{ displayName: 'Last Name', field: 'lastName', headerCellClass: "GridHeader" },
{ displayName: 'Active Status', field: 'activeStatus', headerCellClass: "GridHeader" },
{ displayName: 'RoleName', field: 'roleName', headerCellClass: "GridHeader" },
]
};
How to put a filter in field. Suppose if my rolename in above code is empty/null then hide the role field from grid.
Any help and suggestion highly appreciated. Thanks in advance:)
Yes, I fixed it.
var result = [];
var gridValue= [
{ displayName: 'First Name', field: 'firstName', headerCellClass: "GridHeader" },
{ displayName: 'Last Name', field: 'lastName', headerCellClass: "GridHeader" },
{ displayName: 'Active Status', field: 'activeStatus', headerCellClass: "GridHeader" },
{ displayName: 'RoleName', field: 'roleName', headerCellClass: "GridHeader" },
];
in the response I checked for null value.
if(response.data != null)
{
if (response.data.roleName === null) {
result = gridValue.slice(0, 3);
}
else {
result = gridValue;
}
$scope.gridOptions = {
paginationPageSize: 10,
columnDefs: result,
};
}
this helped me :)
I would recommend just using
that.grid.columnDefs[3].visible = false;
I haven't tested, but it should be more efficient than removing the column from your definition and re-applying the definition to the grid.
I think you could also set the visibility as a function that checks the data.
that.grid.columnDefs[3].visible = function () {
// replace with code checking grid.data
return false;
}
I have simple controller:
angular.module('it.works', ['ngResource'])
.controller 'ItWorksCtrl', ($scope, Task) ->
$scope.worksTable = {
data: Task.query(),
columnDefs: [
{ field: "created_at", cellFilter: "date:'dd.MM.yyyy'", displayName: 'Дата создания' },
{ field: "task", cellFilter: "limitTo:300", displayName: 'Описание задачи' },
{ field: "performer", displayName: 'Исполнитель' },
{ field: "task_type", displayName: 'Срочность' },
{ field: "is_orgtechnik_task", displayName: 'Оргтехника', cellTemplate: "<div class='ui-grid-cell-contents'><i class='fa {{ COL_FIELD == true && \"fa-check\" }}'></i></div>" },
{ field: "department", displayName: 'Подразделение' },
{ field: "customer", displayName: 'Заказчик' },
{ field: "customer_telephone", displayName: 'Телефон заказчика' },
{ field: "end_date", displayName: 'Дата окончания', cellFilter: "date:'dd.MM.yyyy'" },
{ field: "task_status", displayName: 'Статус', cellTemplate: "<div class='ui-grid-cell-contents status-{{ COL_FIELD }}'>{{['В процессе выполнения', 'Выполнено', 'Невыполнимо'][COL_FIELD]}}</div>"}
]
}
.factory 'Task', ($resource) ->
$resource('/api/it_works/:id.json')
When in looks like that (it have 10 columns), it looks fine.
But if I add one more column (or double any existing):
{ field: "performer", displayName: 'Исполнитель' },
It becomes look like that:
So, it renders only 4 columns. But why? How to fix it?
i have come with this issue and have solved it.
First, you should add ui-grid-auto-resize to your html:
<div ui-grid="gridOptions" ui-grid-pagination ui-grid-resize-columns ui-grid-auto-resize
ui-grid-selection class="grid"></div>
Then, you should add ui.grid.autoResize to your js:
angular.module('it.works', ['ngResource','ngAnimate', 'ngSanitize', 'ui.grid', 'ui.grid.pagination','ui.grid.autoResize','ui.grid.selection', 'ui.grid.resizeColumns'])
.controller 'ItWorksCtrl', ($scope, Task) ->
$scope.worksTable = {
data: Task.query(),
columnDefs: [
{ field: "created_at", cellFilter: "date:'dd.MM.yyyy'", displayName: 'Дата создания' },
{ field: "task", cellFilter: "limitTo:300", displayName: 'Описание задачи' },
{ field: "performer", displayName: 'Исполнитель' },
{ field: "task_type", displayName: 'Срочность' },
{ field: "is_orgtechnik_task", displayName: 'Оргтехника', cellTemplate: "<div class='ui-grid-cell-contents'><i class='fa {{ COL_FIELD == true && \"fa-check\" }}'></i></div>" },
{ field: "department", displayName: 'Подразделение' },
{ field: "customer", displayName: 'Заказчик' },
{ field: "customer_telephone", displayName: 'Телефон заказчика' },
{ field: "end_date", displayName: 'Дата окончания', cellFilter: "date:'dd.MM.yyyy'" },
{ field: "task_status", displayName: 'Статус', cellTemplate: "<div class='ui-grid-cell-contents status-{{ COL_FIELD }}'>{{['В процессе выполнения', 'Выполнено', 'Невыполнимо'][COL_FIELD]}}</div>"}
]
}
.factory 'Task', ($resource) ->
$resource('/api/it_works/:id.json')
My view have below code section but when user click on cell edit option is avilable but in textbox instead-of dropdown list:
<div id="grdAreaDetails" ui-grid="gridOptions" class="grid" ui-grid-edit ui-grid-row-edit></div>
And controller is below
$scope.cellSelectEditableTemplate = '<select ng-model="COL_FIELD" ><option value="volvo">Volvo</option><option value="saab">Saab</option></select>';
$scope.maxLength = 200;
$scope.sites = [];
$scope.showloadingdiv = true;
$scope.isAreaAddPanelHide = false;
$scope.gridOptions = {};
$scope.gridOptions.columnDefs = [
{
name: 'code', field: 'code', enableCellEditOnFocus: true,
editableCellTemplate: $scope.cellSelectEditableTemplate
},
{ name: 'name',field:'name'},
{ name: 'notes',field:'notes'},
{ name: 'description', field: 'description' },
{ name: 'siteid', field: 'siteid' },
{ name: 'status',field:'status' }
];
$scope.gridOptions = {
data: $scope.AreaRecord,
multiSelect: false,
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
gridApi.rowEdit.on.saveRow($scope, $scope.UpdateArea);
}
}
Just Remove enableCellEditOnFocus: true and add " enableCellSelection: true"
And let me know what happens.
$scope.gridOptions.columnDefs = [
{
name: 'code', field: 'code' , enableCellSelection: true,
editableCellTemplate: $scope.cellSelectEditableTemplate
},
{ name: 'name',field:'name'},
{ name: 'notes',field:'notes'},
{ name: 'description', field: 'description' },
{ name: 'siteid', field: 'siteid' },
{ name: 'status',field:'status' }
];
If this doesn't work then make fiddle.
How to add conditional when showing data in ui-grid cellTemplate below:
$scope.status = ['Active', 'Non Active', 'Deleted'];
$scope.gridOptions = {
columnDefs: [{
field: 'code'
}, {
field: 'name'
}, {
field: 'status',
cellTemplate: '<div>{{status[row.entity.status]}}</div>'
}]
};
The expected result should be row status show Active/NonActive/Deleted.
Here is the plunker
Thanks in advance.
You have to use externalScopes.
In your markup define the gridholder like this.
<div ui-grid="gridOptions" external-scopes="states" class="grid"></div>
And in your controller use this code:
var statusTxt = ['Active', 'Non Active', 'Deleted'];
$scope.states = {
showMe: function(val) {
return statusTxt[val];
}
};
var statusTemplate = '<div>{{getExternalScopes().showMe(row.entity.status)}}</div>';
$scope.gridOptions = {
columnDefs: [{
field: 'code'
}, {
field: 'name'
}, {
field: 'status',
cellTemplate: statusTemplate
}]
};
Or use an angular filter.
Note that this only renders text. The best approach would be to transform myData to have real text states before using it in ui-grid. Just in case you want to do some text based filtering later on.
Here is a Plunker
I would suggest to use ng-if solve this problem.
$scope.gridOptions = {
columnDefs: [{
field: 'code'
}, {
field: 'name'
}, {
field: 'status',
cellTemplate: '<div ng-if="row.entity.status == 0">Active</div><div ng-if="row.entity.status == 1">Non Active</div>'
}]
};
I have got another solution for you without using external scopes:
The Template looks like this:
var statusTemplate = '<div>{{COL_FIELD == 0 ? "Active" : (COL_FIELD == 1 ? "Non Active" : "Deleted")}}</div>';
Here is the plunker:
http://plnkr.co/edit/OZtU7GrOskdqwHW5FIVz?p=preview
Use a cellFilter.
columnDefs: [{
field: 'code'
}, {
field: 'name'
}, {
field: 'status',
cellFilter: 'mapStatus'
}]
app.filter('mapStatus', function() {
var statusMap = ['Active', 'Non Active', 'Deleted'];
return function(code) {
if (!angular.isDefined(code) || code < 0 || code > 2) {
return '';
} else {
return statusMap[code];
}
};
});
plunker
You must change your template. When you are referring to external scopes in angular-ui-grid you may use grid.appScope.
var statusTemplate = '<div>{{grid.appScope.status[row.entity.status]}}</div>';
Try below script. It is working for me.
app.controller('MainCtrl', ['$scope',
function($scope) {
var statusTxt = ['Active', 'Non Active', 'Deleted'];
$scope.showMe= function(val) {
return statusTxt[val];
};
var statusTemplate = '<div>{{grid.appScope.showMe(row.entity.status)}}</div>';
$scope.gridOptions = {
columnDefs: [{
field: 'code'
}, {
field: 'name'
}, {
field: 'status',
cellTemplate: statusTemplate
}]
};
$scope.gridOptions.data = [{
"code": "Cox",
"name": "Carney",
"status": 0
}, {
"code": "Lorraine",
"name": "Wise",
"status": 1
}, {
"code": "Nancy",
"name": "Waters",
"status": 2
}];
}
]);
first I got a Filter "fromMSDate" that I use to transform json dates not normal dates, if this filter is place then refresh my input that is bound to filterOptions.filterText I get 'Circular dependency' and 'Unknown provider: fromMSDate | dateFilterProvider <- fromMSDate '
//Module
var mainApp = angular.module('mainApp', ['ngGrid']);
//Controller
mainApp.controller('MandateListController', function MandateListController($scope) {
$scope.filterOptions = { filterText: '' };
$scope.mandates = data;
$scope.gridOptions = {
data: "mandates",
filterOptions: $scope.filterOptions,
sortInfo: { fields: ['ExpectedDate', 'ProjectName'], directions: ['desc', 'asc'], columns: ['ExpectedDate', 'ProjectName'] },
columnDefs: [
{ field: 'ProjectName', displayName: 'Project Name', width: '30%', cellClass: 'text-center' },
{ field: 'Amount', displayName: 'Size', cellFilter: 'number:2', cellClass: 'text-right' },
{ field: 'RatingId', displayName: 'Rating', cellClass: 'text-center' },
{ field: 'CurrencyId', displayName: 'Currency', cellClass: 'text-center' },
{ field: 'MaturityId', displayName: 'Maturity', cellClass: 'text-center' },
{ field: 'EstimatedPl', displayName: 'Estimated P/L', cellFilter: 'number:2', cellClass: 'text-right' },
{ field: 'ExpectedDate', displayName: 'Expected Date', cellClass: 'text-center', cellFilter: "fromMSDate | date:'mediumDate'" }
]
};
});
//filter
mainApp.filter("fromMSDate", [function () {
var result = function(date, formatstring) {
if (formatstring === null || formatstring === undefined) {
formatstring = "DD MMM YYYY";
}
return moment(date).format(formatstring);
};
return result;
}]);
If I correctly understand you somehow include into the HTML page the contents of $scope.gridOptions.columnDefs[].cellFilter. In the last columnDef you have the following filter:
fromMSDate | date:'mediumDate'
I think you expect that date will be passed as the first argument and 'mediumDate' as the second, but filters in angular.js has another syntax and you need to write this way:
date | fromMSDate:'mediumDate'
Filters are added to the expression with | character and get the prior expression as the first argument. Other arguments could be specified after :.
So in your example angular.js recognizes 'date' as filter name and fails to find DateFilter or DateFilterProvider for it.