MRenard MRenard - 1 month ago 14
AngularJS Question

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

Answer

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