Search code examples
angularjsui-grid

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


Solution

  • 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