Conditional cell template in ui-grid angularjs - angularjs

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
}];
}
]);

Related

Hide column in ui grid if no data present

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

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.

Angular Ui Grid

apologies if this is really simple but....
I want to display a grid of data but need a look up for some columns. This will become an editable grid but I am suffering with the basics so god help me.
I have two sets of data:
$gridOptions1.data = [{"group_id":"1","location_id":"-1","group_name":"Cars","active":"1"},{"group_id":"2","location_id":"1","group_name":"Trains","active":"1"},{"group_id":"3","location_id":"2","group_name":"Buses","active":"0"}]
and
$scope.locations=[{value: "-1", text: 'All Locations'},
{value: "0", text: 'Location 1'},
{value: "1", text: 'Location 2'},
{value: "2", text: 'Location 3'},
{value: "3", text: 'Location 4'}];
And want to display in the grid.
$scope.gridOptions1 = {
enableSorting: true,
columnDefs: [
{ field: 'location_id' },
{ field: 'group_name' },
{ field: 'active' },
{ name: 'Location', field:'location_id', cellFilter: 'maplocation:this'}
],
onRegisterApi: function( gridApi ) {
$scope.grid1Api = gridApi;
}
};
What I need to do is map the location id
I thought I could use a filter but cannot seem to get access to the scope data.
If anyone could give me a simple example of how to do this I would be very grateful as I am struggling to find any examples of what I want to do.
From what I can see the 'this' parameter is a pointer to the record and not the scope in which the grid options is defined.
I don't want to define the data in the filter because it is coming from the database.
Hope that makes sense.
If you want to use part of the data that's in your application scope to transform the data displayed in UI grid it's best to go with a custom template and calling in the function from your template.
Something like this should work:
columnDefs: [
{ field: 'location_id' },
{ field: 'group_name' },
{ field: 'active' },
{ name: 'Location', field:'location_id', cellTemplate: 'location-template'}
],
And then HTML:
<script type="text/ng-template" id="location-template">
<div class="ui-grid-cell-contents" title="TOOLTIP">{{grid.appScope.formatLocation(row)}}</div>
</script>
Now all you have to do is to define function formatLocation in your controller's scope and do the magic there.
When calling functions from within the cell template, make sure you use grid.appScope to get access to your controller's scope, like in the example I've provided.
Thanks to #Ethnar, here is a workable solution that keeps the template in the source:
columnDefs: [ { field: 'location_id' },
{ field: 'group_name' },
{ field: active' },
{ name: 'Location', field:'location_id',
cellTemplate: '<div class="ui-grid-cell-contents" title="TOOLTIP">{{grid.appScope.formatLocation(row)}}</div>'
}],
Then all is needed is the formatLocation function:
$scope.formatLocation=function(row)
{
locationid=row.entity.location_id;
if(locationid && $scope.locations.length) {
var selected = $filter('filter')($scope.locations, {value: locationid});
return selected.length ? selected[0].text : 'Not set';
} else {
return 'Not set';
} };

DropDown not render in UI Grid angular js

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.

Populate ng-grid by another grid selection

I am trying to populate a ng-grid based on the JSON array returned from a selection of a first ng-grid. As of right now I can get the JSON array displayed onto the screen but I cannot navigate deeper into the JSON array or get anything to display in the second grid. I have the controller code attached and the plnkr can be found at http://plnkr.co/edit/nULoI4?p=info.
'use strict';
function ArticleDataCtrl($rootScope, $scope, articleDataService) {
articleDataService
.getArticles()
.then(
function(articles) {
$rootScope.articles = articles;
$scope.articleGridItems = articles.data.specialMerchandise.specialMerItem;
});
$scope.articleGrid = {
data: 'articleGridItems',
showGroupPanel: false,
multiSelect: true,
checkboxHeaderTemplate: '<input class="ngSelectionHeader" type="checkbox" ng-click="getDeliveryLocations()" ng-model="allSelected" ng-change="toggleSelectAll(allSelected)"/>',
showSelectionCheckbox: true,
selectWithCheckboxOnly: true,
enableColumnResize: true,
selectedItems: [],
columnDefs: [{
field: 'soMerArticleNbr',
displayName: 'Article'
}, {
field: 'soMerOrdQty',
displayName: 'Qty'
}, {
field: 'soArtDeliveryCode',
displayName: 'Delivery Code'
}, {
field: 'dsgnSysRecDesc',
displayName: 'Description'
}]
};
//This is not being called on header template click
$scope.getDeliveryLocations = function() {
$scope.deliveryLocationData = $scope.commonDeliveryLocations;
};
$scope.selections = $scope.articleGrid.selectedItems;
var jsonObject = JSON.stringify($scope.selections);
//Thought a json problem occured here...was wrong
$scope.test = jsonObject.deliveryLocations;
$scope.deliveryGrid = {
data: 'selections',
showGroupPanel: false,
multiSelect: false,
columnDefs: [{
displayName: 'Delivery Methods'
}]
};
}
myApp.controller('ArticleDataCtrl', ['$rootScope', '$scope',
'articleDataService', ArticleDataCtrl
]);
So instead of trying to use angular's built in checkboxes I used my own with a custom method on ng-click. Here is the code and the plunker demonstrating the functionality is http://plnkr.co/edit/nULoI4?p=info.
'use strict';
function ArticleDataCtrl($rootScope, $scope, articleDataService) {
articleDataService
.getArticles()
.then(
function(articles) {
$rootScope.articles = articles;
$scope.articleGridItems = articles.data.specialMerchandise.specialMerItem;
});
$scope.articleGrid = {
data: 'articleGridItems',
showGroupPanel: false,
multiSelect: false,
enableColumnResize: true,
selectWithCheckboxOnly: true,
columnDefs: [{
/*
headerCellTemplate: myHeaderCellTemplate,
*/
cellTemplate: '<input id="checkSlave" name="articleCheckBox" ng-checked="master" type="checkbox" ng-click="getDeliveryLocation(row.entity)" />'
}, {
field: 'soMerArticleNbr',
displayName: 'Article'
}, {
field: 'soMerOrdQty',
displayName: 'Qty'
}, {
field: 'soMerUOIDesc',
displayName: 'UOM'
}, {
field: 'soArtDeliveryCode',
displayName: 'Delivery Code'
}, {
field: 'soMerShrtMerDesc',
displayName: 'Description'
}, {
field: 'soMerDesc',
displayName: 'Vendor'
}]
};
$scope.getDeliveryLocation = function(deliveryLocation) {
$scope.deliveryLocationData = deliveryLocation.deliveryLocation;
for (var i = 0; i < $scope.deliveryLocationData.length; i++) {
var locationId = $scope.deliveryLocationData[i].dlvryLocId;
var locationDesc = $scope.deliveryLocationData[i].dlveryLocDesc;
$scope.deliveryLocationData[i].dlvryLocId = locationId + locationDesc;
}
return $scope.deliveryLocationData;
};
return $scope.deliveryLocationData;
};
$scope.deliveryGrid = {
data: 'deliveryLocationData',
showGroupPanel: false,
multiSelect: false,
columnDefs: [{
field: 'dlvryLocId',
displayName: 'Delivery Methods'
}]
};
$scope.customerGroup = {
value: 'DIY'
};
}
myApp.controller('ArticleDataCtrl', ['$rootScope', '$scope',
'articleDataService', ArticleDataCtrl
]);

Resources