ui.grid data displayed is the same on each row - angularjs

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

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

How can I display a grid repeater using ui-grid?

I have data of messages including {id,message,date}.
I would like to display a grid for each Date with data{message} in AngularJs using ui-grid
I was thinking of something like this:
<div ng-repeat="(item in data | groupBy: 'Date'">
<div>{{ item.Date }}</div>
<div id="grid1" ui-grid="gridOptions(item.Date) " class="grid"></div>
</div>
but it's not working!
$scope.gridOptions = function (date) {
return {
enableSorting: true,
enableFiltering: true,
data: 'data',
columnDefs: $scope.filterGrid(date),
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
},
};
};
$scope.filterGrid= function (date){
return [
{ field: 'id', enableFiltering: False},
{
field: 'Date', enableFiltering: false, filter: {
noTerm: true,
condition: function (searchTerm, cellValue) {
return cellValue.match(date);
}
}
},
{ field: 'Message' , enableFiltering: false },
]
}
First of all - ui-grid has a grouping feature, but this is still in beta.
You can try to use this example to group the data and build grids accordingly.
var dataSource = {};
$scope.gridOptions = {};
var generalGridOptions = {
enableSorting: true,
columnDefs: [
{ name: 'prop1' },
{ name: 'prop2' },
],
data: null
};
// group the data
for(var i = 0; i < data.length; i++){
if(!dataSource[data[i].month]){
dataSource[data[i].month] = [];
}
var obj = {};
for(var prop in data[i]){
if(prop!='month'){
obj[prop] = data[i][prop];
}
}
dataSource[data[i].month].push(obj);
}
// build the grid options
for (var item in dataSource) {
$scope.gridOptions[item] = angular.copy(generalGridOptions);
$scope.gridOptions[item].data = dataSource[item];
}
ui-grid attribute recieves a gridOptions object containing several parameters. Two of them are:
columnDefs - defining the columns and their data-binding.
data - the message objects in your case.
Look at the the documentation for further study: http://ui-grid.info/docs/#/tutorial
Code Example
template:
<div ng-repeat='item in items track by item.id' ui-grid='getItemGridOptions($index)'></div>
Passing the item index to the controller allows you to process your data. Then you can return an object containing the data and columnDefs properties. Like this:
private getItemGridOptions(index): IGridOptions {
//get the data you need for your items array using the index...
// then return the gridOptions object (I put random values)
return {
columnDefs: this.columns,
rowHeight: 24,
rowTemplate: rowtpl,
enableHorizontalScrollbar: this.uiGridConstants.scrollbars.NEVER,
enableColumnMenus: false,
enableRowSelection: true,
enableRowHeaderSelection: false,
enableFiltering: true,
modifierKeysToMultiSelect: true,
multiSelect: true,
data: null,
};
}

returning json object in a modal to a grid and editing it in Angularjs

I constructed a ui grid which has a column for editing, the grid information is populated by a json. Upon clicking the edit column a modal is opened. I want the user to be able to edit the row it clicked. So far I was able to return the entire json object to the modal, but I'm having trouble understanding how to turn that object into just the row I want to edit. I have a variable named ClickedRow which returns the $$hashkey id but I'm not sure how to access it. I tried a forEach utility but it's not working. I am new to angularjs can anyone help me
This is my controller:
import {safeApply} from 'ems';
import modalTemplate from './modal/modal.html';
import controller from './modal/modal.controller.js';
class AssetsController {
/* #ngInject */
constructor(AssetsService, $uibModal, $state) {
this.label = 'Assets Controller !!';
this.assetsService = AssetsService;
this.assetModal= $uibModal;
this.$state = $state;
var assetsData;
var clickedRow;
this.assetsService.resolvePromise().then((response) => {
this.gridOptions.data = response;
assetsData = this.gridOptions.data;
//console.log(response);
safeApply();
});
this.modalOptions ={
template: modalTemplate,
controller: controller,
size: 'large',
backdrop: false,
resolve: {
assetData: function(){
console.log('number 2'+clickedRow);
return [clickedRow, assetsData];
}
}
};
this.myAppScopeProvider ={
modal: this.assetModal,
modalOptions: this.modalOptions,
open:function(row){
console.log('number 1'+row);
clickedRow = row;
this.modal.open(this.modalOptions)
}
};
this.initialize();
}
initialize() {
this.gridOptions = {
paginationPageSizes: [15, 30, 45],
paginationPageSize: 9,
rowHeight: 50,
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: false,
enableColumnResizing: true,
enableSelectAll: false,
noUnselect: true,
columnDefs: [
{
field: 'Thumbnail',
displayName: '',
width: 100,
cellTemplate: '<span class="glyphicon glyphicon-picture" aria-hidden="true"></span>'
},
{
field: 'File Name',
displayName: 'File Name',
cellClass:'blue',
width: 100
},
{
field: 'Description_',
displayName: 'Description',
minWidth: 150
},
{
field: 'Edit_',
displayName: 'Edit',
cellTemplate: '<button class="btn btn-link pull-right" ng-click="grid.appScope.open(row)">Edit</button>',
cellClass:'blue',
width: 100
},
{ field: 'Uploaded_Date', displayName: 'Upload Date'},
{ field: 'Uploaded_By'},
{ field: 'File_Size' },
{ field: 'File_Source'},
{ field: 'In_Use'},
{
field: 'Lock_Status',
displayName: '',
cellClass:'black',
cellTemplate: '<span class="glyphicon glyphicon-lock" aria-hidden="true">'
}
],
onRegisterApi:function (gridApi) {
this.gridApi = gridApi;
},
appScopeProvider: this.myAppScopeProvider,
rowTemplate:''
};
}
}
export default AssetsController;
class ModalController {
/* #ngInject */
constructor($scope, $uibModalInstance, assetData) {
this.label = 'Modal Controller !!';
this.scope = $scope;
this.scope.assetData = assetData;
}
initialize() {
/* this.modalService.resolvePromise().then((response) => {
this.data = response.data;
});*/
}
}
export default ModalController;
Pass row.entity as parameter to your open method:
<button class="btn btn-link pull-right" ng-click="grid.appScope.open(row.entity)">Edit</button>
You'll need to declare your resolve object in your open method so you can pass entity directly:
open: function (entity) {
this.modalOptions.resolve = {
entity: entity
}
this.modal.open(this.modalOptions)
}
Inject entity into your modal controller and you're good to go
Here's a working example on Plunker: http://plnkr.co/edit/Agvcc6CZFBvQQLRpQeRk?p=preview

Angularjs ui grid with grouping column sequence is getting jumbled up

I am using AngularJs ui grid with grouping. The table is displaying fine but the problem I am facing is that the months sequence in the table is getting jumbled up. Please find my Plunker. In the table the Months are appearing in the jumbled up sequence 11-14, 05-15, 04-15, ... 02-15. But I need it in the sequence of 11-14, 12-14, 01-15, 02-15, 03-15, 04-15, 05-15. Can any one help me to fix it?
I am using the following for to get colDefs:
$scope.getColumnDefsForUiGrid = function(columns) {
var colDef = [];
colDef.push({
name: 'mode',
grouping: {
groupPriority: 0
},
displayName: 'Type',
enableCellEdit: false,
width: '5%'
});
colDef.push({
name: 'service',
displayName: 'Catg',
enableCellEdit: false,
width: '5%'
});
angular.forEach(columns, function(value, key) {
colDef.push({
name: key,
displayName: value,
enableCellEdit: true,
aggregationType: uiGridConstants.aggregationTypes.sum,
width: '5%'
})
});
return colDef;
};
Here is a workaround for your problem
you can see it working on this plunker
$scope.getColumnDefsForUiGrid = function( columns ){
var colDef = [];
colDef.push({name: 'mode', grouping: { groupPriority: 0 }, displayName: 'Type', enableCellEdit: false, width: '5%'});
colDef.push({name: 'service', displayName: 'Catg', enableCellEdit: false, width: '5%'});
//I split the monthColumns into an other array
var monthCol = [];
angular.forEach(columns, function( value, key ) {
monthCol.push({name: key, displayName: value, enableCellEdit: true, aggregationType : uiGridConstants.aggregationTypes.sum, width: '5%' })
});
//I sort this array using a custom function
monthCol.sort(function(a,b){
a = a.displayName.split("-");
b = b.displayName.split("-");
if(a[1] < b[1]){
return -1;
}else if (a[1] > b[1]){
return 1;
}else {
if(a[0] < b[0]){
return -1;
}else{
return 1;
}
}
});
//I concat the two array
return colDef.concat(monthCol);
};

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