Search text from cell template not working in ui-grid - angularjs

I have defined a conditional cell template for one of the column. Its displaying the data correctly but I am not able to search for the text in the cell template.
Here is my plunkr:
https://plnkr.co/edit/TDX5jtPord1hkzCVaw3L?p=preview
var template1 = '<div class="">' +
'<div class="" ng-if="COL_FIELD > 30">Greater </div> ' +
'<div class="" ng-if="COL_FIELD < 30"> Lesser </div> ' +
'</div>';
In the template I have put the condition that.. if COL_FIELD > 30 then then write Greater.. or else write Lesser. And now I should be able to search for the Greater or Lesser in Number column.

A solution could be to add a property on your data like :
$http.get('data.json').success(function(data) {
data.map(function(item) {
item.greaterLesser = item.amount > 30 ? 'Greater' : 'Lesser';
});
$scope.gridOptions.data = data;
});
and then instead of using the amount with a template, just bind on this property.
$scope.gridOptions = {
enableFiltering: true,
columnDefs: [{
field: 'name',
width: 70
}, {
field: 'greaterLesser',
name: 'Number',
width: 90,
}, {
field: 'amount',
name: 'Currency',
cellFilter: 'currencyFilter:this',
}]
};
Here is the updated plunker
Edit
If you want to use the template, you could implement the search function yourself. You can add the filter option to your field and implement the condition function. Something like:
filter: {
condition: function(searchTerm, cellValue) {
var value = cellValue > 30 ? 'greater' : 'lesser';
var result = value.search(searchTerm.toLowerCase());
return result > -1;
}
}
Here I used the search function but you could use match or some other function.
Here is a demo plunker

I used the below code to make search work
field: 'EmpId',
displayName: 'Employee Type',
cellTemplate: '<div style="cursor:pointer" class="ui-grid-cell-contents">{{grid.appScope.GetEmployeeType(row)}}</div>',
filter: {
condition: function (searchTerm, cellValue,row,column) {
var value = $scope.GetEmployeeType(row);//same function that you use to display value in cell Template
return (value.toLocaleLowerCase().indexOf(searchTerm.toLocaleLowerCase())>-1);
}
}

Related

angular ui-grid enable disable row element based on flag

I am using angular ui-grid to show list of rows from database table(Users).
I am doing a back end call and NodeJS fetches the data from DB and returns.
This data is being shown in angular ui-grid.
I want to enable or disable few html elements ., view/edit/delete based on the accessibility of the current user.
If the current user is ADMIN then all the links are enabled. If he is BASIC user then VIEW is enabled and EDIT and DELETE are disabled.
Project accessibility is also returned from the server . I just need to check this flag and disable/enable the links.
Please let me know , how to do this?
id name actions
1 AAA view edit delete
2 BBB view edit delete
3 CCC view edit delete
4 DDD view edit delete
<div class="box">
<div class="box-content box-table">
<div ui-grid="gridUsers" ui-grid-pagination>
</div>
</div>
</div>
$scope.gridUsers = {
paginationPageSizes: [15, 30, 45],
paginationPageSize: 15,
enableColumnMenus: false,
data: $scope.users,
filterOptions: $scope.filterOptions,
columnDefs: [{ field: 'id', displayName: 'Id', width: '20%'},
{ field: 'name', displayName: 'Name', width: '25%', enableFiltering: true},
{ name: 'Actions', displayName: 'Actions', width: '55%', cellTemplate:
'<div class="grid-action-cell action-btns">'+
'<span class="btn-small"><span style="color:#214c77;">view</span> </a>' +
'<a ng-click="grid.appScope.edit(row.entity.id)" class="btn-small btn-link"><span style="color:#80bb41;">edit</span> </a>' +
'<a ng-click="grid.appScope.delete(row.entity.id)" class="btn-small btn-link"> <span style="color:#e15829;">delete</span> </a>'
'</div>'}
]
};
Service.GetAllUsers(function (response) {
if (response.length != 0) {
$scope.users = response;
$scope.gridUsers.data = $scope.users;
}
});
I had the same problema.
In order to resolve it, I call a function after retrieving columns :
function updateColumnsDefs() {
columnsDefs
.forEach(function(column) {
switch (column.field) {
case 'status' :
columnVal = '<span ng-if="c.' + column.filterBy + '">{{c.' + column.filterBy + '}}</span>';
column.cellTemplate = '<div class="ui-grid-cell-contents">' + columnVal + '</span></div>';
break;
default :
break;
}
}
Look how I made a dynamic cellTemplate using ng-if.
After that, I apply the updated columnsDefs to gridOptions:
updateColumnsDefs();
vm.gridOptions = {
...
columnDefs : columnsDefs,
...
};
You should pay attention if use lazy loading or filter. In that case remember to recall updateColumnsDefs every time your data model changes.

dynamic angular filter in ui-grid grouped custom cell template

I need a cell table with more than one value. I made a construct for ui-grid options, a custom template for the cell and few css lines. It works and permit me to decide if value must stay in the same line or in more than one line.
Custom template:
var template =
'<div class="ui-grid-cell-contents crm-group">'+
'<div class="crm-group-row" ng-repeat="rowFields in col.colDef.fields">' +
'<div class="crm-group-col" ng-repeat="colField in rowFields" ng-if="row.entity[colField.name]">' +
'<span class="title" ng-if="colField.descr">'+
'{{colField.descr}}: '+
'</span>' +
'<span class="content">'+
//"{{row.entity[colField.name] }}"+ //without filter
"{{row.entity[colField.name] | colField.cellFilter}}"+ //<-- HERE doesn't work
'</span>' +
'</div>'+
'</div>' +
'</div>';
option structure:
{ field: 'group',
name: 'Group',
width: '**',
fields : [
[
{
name: "age",
descr: "Num",
cellFilter : "floatToFixed:'2'",
},
{
name: "email",
descr: "Email",
},
],
],
cellTemplate: template
},
Now i need to apply a possible different filter to each value. So i set it on the field structure. In this case i want apply a custom filter to the first field value.
Filter:
app.filter('floatToFixed', function () {
return function (input, number) {
console.log(input);
console.log(number);
if (!input)
return null;
if (!number)
return input;
else
return parseFloat(input).toFixed(parseInt(number));
}
});
But it doesn't work. Here the plunker.
Help is appreciate.
First of all, you have incorrect format after pipe | - name of the filter can't contain dot, what you could do is have a filter that applies filter from a string, that's the solution I can came up from top of my head:
http://plnkr.co/edit/by8vQBgeau0823akwQvu?p=preview
.filter('applyFilter', function($filter) {
return function(input, filter) {
var filterToApply = filter !== undefined ? filter.split(':') : undefined;
return filterToApply === undefined ? input : $filter(filterToApply[0])(input, parseInt(filterToApply[1], 10))
}
})
and then in html
"{{row.entity[colField.name] | applyFilter:colField.cellFilter}}"

Angular UI Grid - Filter on display values within registerRowsProcessor

We have a requirement to filter the contents of a grid using values/inputs that are not embedded into the UI Grid Column headers. The filtering must occur on the values that are displayed or in other word have been "filtered" for presentment. I have been able to successfully filter on values that don't have a cellFilter specified by specifying a filter method using the registerRowsProcessor.
$scope.externalFilterImpl = ( renderableRows ) => {
if($scope.externalFilterValues.name.length>0)
{
// Case insensitive matching
var matcher = new RegExp($scope.externalFilterValues.name, "i");
renderableRows.forEach( function( row ) {
var match = false;
debugger;
if ( row.entity["id"].match(matcher) ){
//var value = $scope.gridApi.grid.getCellDisplayValue(row, "id");
//if ( value.match(matcher) ){
match = true;
}
if ( !match ){
row.visible = false;
}
});
}
return renderableRows;
};
The code expects to filter on the display value (filtered value) for the column with the columnDef field property of "id". The columnDef for "id" appears as follows:
{
field: "id",
cellClass: "cellContent",
displayName: $translate.instant('tableHeading.item'),
enableColumnMenu: false,
enableHiding: false,
suppressRemoveSort: true,
filter: {
placeholder: "Enter a name search"
},
cellFilter: 'translateIds:"itemIds"',
filterCellFiltered:true,
sortCellFiltered:true,
sort: {
direction: uiGridConstants.ASC,
priority: 0,
},
cellTemplate: `<div class="ui-grid-cell-contents">
{{COL_FIELD CUSTOM_FILTERS}}
</div>`
}
Any assistance would be greatly appreciated.

Angular UI-Grid Conditional Cell Template

I have a cell template that displays data from an external ui-select. However I only want the cell template to appear if the row(s) is/are selected. Here is my current code:
$scope.gridOptions.columnDefs = [
{ name: 'resourceChannel',
cellTemplate: '<div ng-if="$(\'.ui-grid-row\').hasClass(\'ui-grid-row-selected\')">{{grid.appScope.channel.selected.channel}}</div>'},
];
You could add something like a Row-Selected-Listener and ng-if - check if the current row is in the selection.
I added a Plunkr that demonstrates a possiblity of show/hide cellTemplate.
First you add an ng-click to the ui-grid rowtemplate, f.e. addRowtoSelection().
$templateCache.put('ui-grid/uiGridViewport',
...
"<div ng-repeat=\"(rowRenderIndex, row) in rowContainer.renderedRows track by $index\"" +
"ng-click=\"grid.appScope.addRowtoSelection(row)\"" +
...
);
Then you add that function to your appScope.
all.gridOptions = {
columnDefs: [
{field: 'firstName', cellTemplate: '<div ng-if="grid.appScope.isRowSelected(row.uid)">something</div>'},
{field: 'lastName'},
{field: 'company'},
{field: 'employed'}
],
...,
appScopeProvider : {
addRowtoSelection : function(row) {
var contains = false;
for (var i = 0, len = all.rowsSelectedIds.length; i < len; i++) {
if(all.rowsSelectedIds[i] === row.uid) {
all.rowsSelectedIds.splice(i, 1);
contains = true;
}
}
if(!contains) {
all.rowsSelectedIds.push(row.uid);
}
},
isRowSelected : function(id) {
for (var i = 0, len = all.rowsSelectedIds.length; i < len; i++) {
if(all.rowsSelectedIds[i] === id) {
return true;
}
}
return false;
},
},
I also added a check for already selected row-IDs so you add/remove on click. In ColumnDefs you can see the reference to the isRowSelected() check, where you pass in the row.uid. That parses the current array and returns true or false.

angular-ui ng-grid How to make the aggregate row be an editable row

I think that what I'm trying to achieve is having a tree-like inside the ng-grid. I didn't found such an implementation but I'm wondering if I can use the grouping mechanism
I need to have the group header be editable in the same manner as the rows below it (see image above), with exactly the same editable cells, acting as a master row. When updating one cell from the header group should update all the cells beneath that group.
From ng-grid docs http://angular-ui.github.io/ng-grid/ :
default value for aggregateTemplate:
<div ng-click="row.toggleExpand()" ng-style="{'left': row.offsetleft}" class="ngAggregate">
<span class="ngAggregateText">{{row.label CUSTOM_FILTERS}} ({{row.totalChildren()}} {{AggItemsLabel}})</span>
<div class="{{row.aggClass()}}"></div>
</div>
Is it possible to use this option in order to render the aggregate row as I described?
The below answer/comment is related to tree like structure and not related to making aggregate row editable...
If you are looking for tree-like structure in ng-grid, then you could achieve that with the combination of ng-if, ng-click and API(s) that updates the ng-grid data option on click of a particular row. Here is a sample plnkr.
On click of a parent row, a toggle function is called to add/remove child rows in to the ng-grid data. (Refer to my plunker code for complete details)
$scope.toggleDisplay = function(iType) {
$scope.displayItemDetails[iType] = $scope.displayItemDetails[iType] ? 0 : 1;
$scope.selItems = $scope.updateTable();
};
$scope.updateTable = function() {
var selItems = [];
for (var i in $scope.allItems) {
var iType = $scope.allItems[i]["Type"];
if (angular.isUndefined($scope.displayItemDetails[iType])) {
$scope.displayItemDetails[iType] = 0;
}
if (1 == $scope.displayItemDetails[iType]) {
$scope.allItems[i]["Summary"] = '-';
} else {
$scope.allItems[i]["Summary"] = '+';
}
selItems.push($scope.allItems[i]);
if ($scope.displayItemDetails[iType]) {
for (var j in $scope.allItems[i]["Details"]) {
$scope.allItems[i]["Details"][j]["Summary"] = "";
selItems.push($scope.allItems[i]["Details"][j]);
}
}
}
return selItems;
};
$scope.gridOptions = {
data: 'selItems',
columnDefs: [{
field: 'Summary',
displayName: '',
cellTemplate: summaryCellTemplate,
width: 30
}, {
field: 'Name',
displayName: 'Name',
}, {
field: 'Type',
displayName: 'Type',
}, {
field: 'Cost',
displayName: 'Cost',
}, {
field: 'Quantity',
displayName: 'Quantity',
}],
enableCellSelection: false,
enableColumnResize: true
};

Resources