Angularjs ui-grid filter complex expression - angularjs

How can I filter a complex expression mapping like "brand.title". Here is my fileds initialization :
$scope.gridOptions2.columnDefs = [
{ field: 'code', displayName: "Code" },
{ field: 'brand.title', displayName: "Brand", resizable: true },
];
And the filter :
$scope.singleFilter = function(renderableRows) {
var matcher = new RegExp($scope.selectedBrand);
renderableRows.forEach(function(row) {
var match = false;
['code', 'brand.title' ].forEach(function(field) {
if (row.entity[field].match(matcher)) {
match = true;
}
});
if (!match) {
row.visible = false;
}
});
return renderableRows;
};
Filtring on code field works fine but brand.title gives the following error :
TypeError: Cannot read property 'match' of undefined

The alternative is :
$scope.gridOptions2 = {
columnDefs : [
{ field: 'code', displayName: "Code", enableFiltering: true },
{ field: 'brand.title', displayName: "Brand", resizable: true, enableFiltering: true, filter: {
term : $scope.term }}
],
onRegisterApi : function(gridApi) {
$scope.gridApi = gridApi;
}
};
$scope.singleFilter = function() {
$scope.gridApi.grid.columns[2].filter.term = $scope.term;
};

Related

setting a editableCellCondition in a ui-grid inside an angular 1.5 component

I am trying to set rows editable/not editable based on a flag in the data.
I can get this working outside an angular 1.5 component, but can't seem to access row.entity inside a controller in a component.
function memberDisplayCtrl ($scope, memberFactory,uiGridConstants) {
var ctrl = this;
ctrl.people = memberFactory.getMembers();
ctrl.checkStatus = function(ctrl){
// How do I do something like this:
// if (ctrl.row.entity.Status === 'Y') { return 'true'; } else {return 'false';}
};
ctrl.gridOptions = {
enableSorting: true,
enableCellEdit:false,
cellEditableCondition: ctrl.checkStatus(ctrl),
enableHorizontalScrollbar : 0,
enableVerticalScrollbar : 0,
enableColumnMenus: false,
minRowsToShow: ctrl.people.length,
columnDefs: [
{ displayName:'First Name', name: 'fname', enableCellEdit:true },
{ displayName:'Last Name', name: 'lname', enableCellEdit:true },
{ displayName:'Date of Birth', name: 'DOB', type:'date', enableCellEdit:true, cellFilter: 'date:"yyyy-MM-dd"'},
{ displayName:'Address', name: 'address', enableCellEdit:true},
{ displayName:'Status',name: 'Status', enableCellEdit: true}
],
data : ctrl.people
};
}
I'm pretty sure I have a scope problem but can't seem to figure it out. How do I access row.entity? I have an isolated scope inside my controller (since it is part of a component)
plunker here: https://plnkr.co/edit/Wz7gKs
Thanks
just pass a function to cellEditableCondition instead of executing it:
cellEditableCondition: ctrl.checkStatus
and note, that parameter received by that function is not current controller's this (aliased in your case as ctrl), but ui-grid's scope, so I renamed ctrl to scope:
function memberDisplayCtrl ($scope, memberFactory,uiGridConstants) {
var ctrl = this;
ctrl.people = memberFactory.getMembers();
ctrl.checkStatus = function(scope) {
return scope.row.entity.Status === 'Y'
};
ctrl.gridOptions = {
enableSorting: true,
enableCellEdit:false,
cellEditableCondition: ctrl.checkStatus,
enableHorizontalScrollbar : 0,
enableVerticalScrollbar : 0,
enableColumnMenus: false,
minRowsToShow: ctrl.people.length,
columnDefs: [
{ displayName:'First Name', name: 'fname', enableCellEdit:true },
{ displayName:'Last Name', name: 'lname', enableCellEdit:true },
{ displayName:'Date of Birth', name: 'DOB', type:'date', enableCellEdit:true, cellFilter: 'date:"yyyy-MM-dd"'},
{ displayName:'Address', name: 'address', enableCellEdit:true},
{ displayName:'Status',name: 'Status', enableCellEdit: true}
],
data : ctrl.people
};
}
also, I see your commented code:
if (ctrl.row.entity.Status === 'Y') {
return 'true';
}
else {
return 'false';
}
here you intend to return string variable in both cases which will always evaluated as boolean true, you should return boolean:
if (ctrl.row.entity.Status === 'Y') {
return true;
}
else {
return false;
}
which is equal to much shorter version:
return ctrl.row.entity.Status === 'Y';
plunker: https://plnkr.co/edit/KXbJ40?p=preview

Struggling to write a Jasmine testcase for AngularJS

The below code is my controller logic and I want to create a Jasmine test case for it. With $inject I am getting problem how to mock or use the services used in $inject and write a Jasmine test case for below AngularJS controller logic.
(function () {
'use strict';
var controllerId = 'user';
angular.module('app').controller(controllerId, user);
user.$inject = ['$rootScope', 'userService', 'common'];
function user($rootScope, $userService, common) {
var vm = this;
vm.users = [];
vm.sorting = {
column: "UpdatedDate",
order: 0
};
vm.gridHeaders = [
{ title: "UserName", visible: true, sort: true, name: 'UserName', filter: true, type: 'string' },
{ title: "First Name", visible: true, sort: true, name: 'FirstName', filter: true, type: 'string' },
{ title: "Middle Name", visible: true, sort: true, name: 'MiddleName', filter: true, type: 'string' },
{ title: "Last Name", visible: true, sort: true, name: 'LastName', filter: true, type: 'string' },
{ title: "Email Address", visible: true, sort: true, name: 'EmailID', filter: true, type: 'string' },
{ title: "Phone Number", visible: true, sort: true, name: 'PhoneNumber', filter: true, type: 'string' },
{ title: "Mobile Number", visible: true, sort: true, name: 'MobileNumber', filter: true, type: 'string' },
{ title: "City", visible: true, sort: true, name: 'City', filter: true, type: 'string' },
{ title: "Role", visible: true, sort: true, name: 'RoleID', filter: true, type: 'int' },
{ title: "Address", visible: true, sort: true, name: 'Address', filter: true, type: 'string' },
{ title: "UserType", visible: true, sort: true, name: 'UserType', filter: true, type: 'int' },
{ title: "RoleName", visible: true, sort: true, name: 'RoleName', filter: true, type: 'string' }
];
vm.editUser = function (value) {
if (value > 0) {
var request = [{
"PageNumber": vm.pagination.currentPage,
"PageSize": vm.pagination.pageSize,
"SortColumn": vm.sorting.column,
"SortOrder": vm.sorting.order,
"Query": "UserID=" + value
}];
$userService.sendUserID(request);
}
}
vm.loadUserSearchDetails = function () {
//common.showSpinngMan();
var pageConstants = common.preparePageConstants();
vm.pageDropDown = pageConstants.pageDropDown;
vm.pagination = pageConstants.pagination;
loadGrid();
};
vm.loadPageData = function (scenario) {
vm.pagination.currentPage = common.setPagination(scenario, vm.pagination)
loadGrid();
};
//Load grid
var loadGrid = function (data) {
var request = [{
"PageNumber": vm.pagination.currentPage,
"PageSize": vm.pagination.pageSize,
"SortColumn": vm.sorting.column,
"SortOrder": vm.sorting.order,
"Query": ""
// Filters: vm.filterPanel.savedFilter
}];
$rootScope.loading = true;
$userService.getUserDetails(request).then(function (result) {
debugger;
if (!!result) {
vm.users = result.SearchUsers;
vm.pagination.totalRecords = vm.users.length;
vm.pagination.totalPages = Math.ceil(vm.pagination.totalRecords / vm.pagination.pageSize);
}
}).catch(function (result) {
console.log("error load grid");
//$location.path("/error");
}).finally(function () {
$rootScope.loading = false;
})
};
return vm;
}
})();
for the above controller code i have written jasmine testcase by removing injected service userservice and common.js
the new part consists :
//user.$inject = ['$rootScope', 'userService', 'common']; //line removed
function user($rootScope) { // , $userService, common params removed
var vm = this;
vm.users = [];
commented the code relating to $userservice and written jasmine testcase like below and it's working fine.. my question is how write when i inject the other dependencies i.e. 'userservice' 'common'
describe("A suite", function () {
beforeEach(module('app'));
var $controller;
var mockServiceDepedency;
beforeEach(inject(function (_$controller_) {
$controller = _$controller_;
}));
it("testing 5", function () {
var $rootScope = {};
var controller = $controller('user', { $rootScope: $rootScope });
expect(controller.users).not.toBeNull();
expect(controller.users).toEqual([]);
expect(controller.sorting.column).toEqual("UpdatedDate");
expect(controller.sorting.order).toEqual(0);
expect(controller.gridHeaders[0]).toEqual({ title: "UserName", visible: true, sort: true, name: 'UserName', filter: true, type: 'string' });
expect(controller.pageDropDown).not.toBeNull();
expect(controller.pageDropDown).not.toBeNull();
expect(controller.loadUserSearchDetails.pageConstants).not.toBeNull();
});
});

ui.grid data displayed is the same on each row

I am using a cell template for each row in my data grid. If I qualify the json object with an index then the value appears correctly but of course it is the same for each row. If I remove the index, then all rows are displayed with the same value but the value is an array.
---the js file
(function() {
angular.module('xxxSurvey').controller('EditxxxSurveyController', EditxxxSurveyController);
EditxxxSurveyController.$inject = ['$scope', 'UserFacilityListService', 'xxxSurveyService'];
function EditxxxSurveyController($scope, UserFacilityListService, xxxSurveyService) {
$scope.dataLoaded = false;
$scope.currentPage = 1;
$scope.pageSize = 10;
// test ui-grid setup
$scope.dataLoaded = true;
$scope.editWorksheetOptions = {
enableSorting: true,
columnDefs: [
{
name: 'all', field: 'MasterPatientId', width: 40,
enableSorting: false, enableColumnMenu: false, pinnedLeft: true,
//cellTemplate: '<input type="checkbox" id="i{{COL_FIELD}}">'
cellTemplate: '<div class="ui-grid-cell-contents">{{grid.appScope.worksheetInfo.MasterProviderId}}</div>'
},
{name: 'residentName', field: 'residentName', minWidth: 90, pinnedLeft: true,
cellTemplate: '<div class="ui-grid-cell-contents">{{grid.appScope.editWorksheetOptions.data[0].ResidentNameLast}}</div>'
},
{name: 'residentRoom', field: 'residentRoom', width: 90, pinnedLeft: true},
{name: 'status', field: 'status', width: 90},
],
data: []
};
$scope.$on('FacilitySelected', function() {
if (UserFacilityListService.getSelectedFacility()) {
$scope.selectedFacility = UserFacilityListService.getSelectedFacility();
}
var promise = xxxSurveyService.getCurrentWorksheet($scope.selectedFacility.MasterProviderId);
promise.then(
function(payload) {
if (payload !== null) {
$scope.worksheetInfo = payload.worksheetInfo;
$scope.editWorksheetOptions.data = payload.residentData;
}
}
);
});
}
})();
--the json data
[{"AssessmentId":1,"WorksheetId":4,"MasterPatientId":1,"ResidentNameFirst":"xx","ResidentNameMiddle":"^","ResidentNameLast":"zzz","ResidentNameSuffix":"^"},
{"AssessmentId":2,"WorksheetId":2,"MasterPatientId":2,"ResidentNameFirst":null,"ResidentNameMiddle":null,"ResidentNameLast":null,"ResidentNameSuffix":null}]
--the html div id="editWorksheetGrid" ui-grid="editWorksheetOptions" class="grid" ui-grid-pinning>
i had same issue. For me it was rowIdentity problem.
Define following in your controller.
$scope.gridOptions.rowIdentity = function (row) {
return row.ID; //make sure ID is unique.
};
This fixed my problem.
Thanks

Can you tell me PageSize Change Event in Kendo Angular grid

Can you tell me page size Change event in Kendo-Angular grid as i am new in kendo grid control. Please help me. Thank you in advance.
app.controller("dataController", function ($compile, dataFactory, $scope, $timeout) {
$scope.obj = [];
$scope.DistrictList = [];
$scope.DistrictTextToShow = "Select District";
$scope.GetDistrict = function () {
dataFactory.getdistrictList().success(function (data) {
$scope.DistrictList = data;
}).error(function (data) {
$.toaster({ priority: 'error', title: 'Error', message: 'Error while fetching data' });
});
};
if ($("#ddldistrict").val() == '') {
$scope.ddldistrict = GuidEmpty;
}
else {
$scope.ddldistrict = $("#ddldistrict").val();
}
$scope.gridData = new kendo.data.DataSource({
serverPaging: true,
serverSorting: true,
transport: {
read: {
url: baselocation + "api/Customer/GetAllCustomerByDistrictId",
data: { DistrictId: $scope.ddldistrict, isactive: $("#ddlstatus").val() }
}
},
schema: {
data: function (data) {
return data.Rows;
},
total: function (data) {
return data.TotalRows;
}
},
pageSize: 5
});
$scope.detailGridOptions = {
sortable: true,
pageable: {
"pageSizes": true,
change: function (e) {
if ($("#ddldistrict").val() == '') {
$scope.ddldistrict = GuidEmpty;
}
else {
$scope.ddldistrict = $("#ddldistrict").val();
}
//$("#grid1").data('kendoGrid').dataSource.pageSize(parseInt(this.value()));
$("#grid1").data('kendoGrid').dataSource.read({ DistrictId: $scope.ddldistrict, isactive: $("#ddlstatus").val() });
$("#grid1").data('kendoGrid').refresh();
}
},
datasource: $scope.gridData,
groupable: true,
scrollable: true,
columns: [{
field: "Customername",
title: "Customer Name",
width: "150px"
}, {
field: "mobile",
title: "Mobile",
width: "120px"
}, {
field: "email",
title: "Email",
width: "120px"
}, {
field: "Districtname",
title: "District",
width: "120px"
}]
};
$scope.GetDistrict();
$scope.BindData = function () {
if ($("#ddldistrict").val() == '') {
$scope.ddldistrict = GuidEmpty;
}
else {
$scope.ddldistrict = $("#ddldistrict").val();
}
$("#grid1").data('kendoGrid').dataSource.read({ DistrictId: $scope.ddldistrict, isactive: $("#ddlstatus").val() });
$("#grid1").data('kendoGrid').refresh();
}
//$("#grid1").kendoPager({
//});
//$scope.gridData.read();
});

I want to read a array value inside factory in angularjs

I am trying to read value in array in factory but I am unable to do so. I am using ng-grid and when I click on one row I get selecteditems list which I pass in another controller where I call a factory service in which I pass that as a parameter but that parameter in the factory stays as array and when I read it using index it shows blank.
My code is as below -
myNgApp.controller('MyGrid', ['$scope', function ($scope) {
$scope.mySelections = [];
$scope.mySelItems = [];
$scope.myData = [{ Reference: 12, Customer: "fff", Title: "sd", Task: "Enter Details", Received: "Today", Due: "01/09/2014" },
{ Reference: 7899, Customer: "eee", Title: "dsd", Task: "Enter Details", Received: "Yesterday", Due: "05/09/2014" }];
$scope.gridOptions = {
data: 'myData',
checkboxHeaderTemplate: '<input class="ngSelectionHeader" type="checkbox" ng-model="allSelected" ng-change="toggleSelectAll(allSelected)"/>',
selectWithCheckboxOnly: true,
showSelectionCheckbox: true,
selectedItems: $scope.mySelections,
multiSelect: true,
columnDefs: [{ field: 'Reference', displayName: 'Reference', width: '*' }, { field: 'Customer', displayName: 'Customer', width: '**' }, { field: 'Title', displayName: 'Title', width: '***' }, { field: 'Task', displayName: 'Task', width: '***' }, { field: 'Received', displayName: 'Received', width: '**' }, { field: 'Due', displayName: 'Due', width: '**' }],
showGroupPanel: true,
enableCellSelection: false,
enableRowSelection: true,
enableCellEditOnFocus: false,
enablePinning: true,
showColumnMenu: true,
showFilter: true,
enableColumnResize: true,
enableColumnReordering: true,
maintainColumnRatios: true,
afterSelectionChange: function () {
angular.forEach($scope.mySelections, function (item) {
if ($scope.mySelItems.length == 0) {
$scope.mySelItems.push(item.Title)
}
else {
$scope.mySelItems[0] = item.Title
}
});
}
};
}]);
myNgApp.factory('myPreviewDataService', function () {
return function (x) {
var arr = [x, "Apple", "Banana", "Orange"];
return arr
};
});
myNgApp.factory('myPreviewTplService', function () {
return function () {
return '<div><div class="ngPreviewItems" ng-repeat="item in items">{{item}}</div></div>';
};
});
myNgApp.directive('showPreview', function ($compile) {
return {
scope: true,
link: function (scope, element, attrs) {
var el;
attrs.$observe('template', function (tpl) {
if (angular.isDefined(tpl)) {
// compile the provided template against the current scope
el = $compile(tpl)(scope);
// stupid way of emptying the element
element.html("");
// add the template content
element.append(el);
}
});
}
};
});
myNgApp.controller('myPreviewController', function ($scope, myPreviewDataService, myPreviewTplService) {
//$scope.showContent = function () {
$scope.items = myPreviewDataService($scope.mySelItems);
$scope.template = myPreviewTplService();
//};
});
here $scope.mySelItems is from ng grid controller that gets updated when we select a checkbox.
What I get is an array but I am unable to read its content, when I display the array as it is it gets displayed like ["test"] but when I try to read it x[0] in myPreviewDataService factory or by $scope.mySelItems[0] in myPreviewController then I get blank. I am not able to figure out why this is happening
I was able to solve it. In myPreviewDataService factory I changed the array elements from string to array
var arr = [x, "Apple", "Banana", "Orange"];
changed to
var arr = [x, ["Apple"], ["Banana"], ["Orange"]];
and in myPreviewTplService factory I changed {{item}} to {{item[0]}}
it worked.
P.S I think we can also use ng switch based on condition in myPreviewTplService factory based on the type of item, I tried to do it but I was not able to do so and worked with my earlier solution.

Resources