1
votes

I am attempting to open a modal, when clicking the edit button on an Angular UI Grid. I am new to Angular and still learning. I have done some searching but still cannot work out how to inject my modal instance into the StaffController, so it can be used. Will really appreciate any advice / help on this. Thanks,

I am using the angular modal example off: https://angular-ui.github.io/bootstrap/

Index File(Contains the Grid and example Modal Buttons):

@*Staff Grid*@
<body ng-app="Application">
<div ng-controller="ApiStaffController">
    <div class="table-responsive angular-grid" ui-grid="gridOptions" ui-
grid-move-columns ui-grid-resize-columns ui-grid-exporter ui-grid-selection>
    </div>
</div>

<div ng-controller="ModalDemoCtrl as $ctrl" class="modal-demo">
    <script type="text/ng-template" id="myModalContent.html">
        <div class="modal-header">
            <h3 class="modal-title" id="modal-title">Create User</h3>
        </div>
        <div class="modal-body" id="modal-body">
            <label asp-for="Person.Forename" class="control-label"></label>
            <input type="text" class="form-control" ng-model="$ctrl.newUser.Forename" />
            <label asp-for="Person.Surname" class="control-label"></label>
            <input type="text" class="form-control" ng-model="$ctrl.newUser.Surname" />
        </div>
        <div class="modal-footer">
            <button class="btn btn-primary" type="button" ng-click="$ctrl.ok()" ng-disabled="!$ctrl.newUser.Forename || !$ctrl.newUser.Surname">OK</button>
            <button class="btn btn-warning" type="button" ng-click="$ctrl.cancel()">Cancel</button>
        </div>
    </script>

    <script type="text/ng-template" id="stackedModal.html">
        <div class="modal-header">
            <h3 class="modal-title" id="modal-title-{{name}}">The {{name}} modal!</h3>
        </div>
        <div class="modal-body" id="modal-body-{{name}}">
            Having multiple modals open at once is probably bad UX but it's technically possible.
        </div>
    </script>


    <button type="button" class="btn btn-default" ng-click="$ctrl.open()">Open me!</button>
    <button type="button" class="btn btn-default" ng-click="$ctrl.open('lg')">Large modal</button>
    <button type="button" class="btn btn-default" ng-click="$ctrl.open('sm')">Small modal</button>
    <button type="button" class="btn btn-default" ng-click="$ctrl.open('sm', '.modal-parent')">
        Modal appended to a custom parent
    </button>
    <button type="button" class="btn btn-default" ng-click="$ctrl.toggleAnimation()">Toggle Animation ({{ $ctrl.animationsEnabled }})</button>
    <button type="button" class="btn btn-default" ng-click="$ctrl.openComponentModal()">Open a component modal!</button>
    <button type="button" class="btn btn-default" ng-click="$ctrl.openMultipleModals()">
        Open multiple modals at once
    </button>
    <div ng-show="$ctrl.selected">Selection from a modal: {{ $ctrl.selected }}</div>
    <div class="modal-parent">
    </div>
</div>

I have a file named: ModalController that contains the below: (This is from the example)

angular.module('Application').controller('ModalDemoCtrl', function 
($uibModal, $log, $document) {
var $ctrl = this;
$ctrl.items = ['item1', 'item2', 'item3'];

$ctrl.animationsEnabled = true;

$ctrl.open = function (size, parentSelector) {
    var parentElem = parentSelector ?
        angular.element($document[0].querySelector('.modal-demo ' + 
parentSelector)) : undefined;
    var modalInstance = $uibModal.open({
        animation: $ctrl.animationsEnabled,
        ariaLabelledBy: 'modal-title',
        ariaDescribedBy: 'modal-body',
        templateUrl: 'myModalContent.html',
        controller: 'ModalInstanceCtrl',
        controllerAs: '$ctrl',
        size: size,
        appendTo: parentElem,
        resolve: {
            items: function () {
                return $ctrl.items;
            }
        }
    });

    modalInstance.result.then(function (selectedItem) {
        $ctrl.selected = selectedItem;
    }, function () {
        $log.info('Modal dismissed at: ' + new Date());
    });
};

$ctrl.openComponentModal = function () {
    var modalInstance = $uibModal.open({
        animation: $ctrl.animationsEnabled,
        component: 'modalComponent',
        resolve: {
            items: function () {
                return $ctrl.items;
            }
        }
    });

    modalInstance.result.then(function (selectedItem) {
        $ctrl.selected = selectedItem;
    }, function () {
        $log.info('modal-component dismissed at: ' + new Date());
    });
    };

$ctrl.openMultipleModals = function () {
    $uibModal.open({
        animation: $ctrl.animationsEnabled,
        ariaLabelledBy: 'modal-title-bottom',
        ariaDescribedBy: 'modal-body-bottom',
        templateUrl: 'stackedModal.html',
        size: 'sm',
        controller: function ($scope) {
            $scope.name = 'bottom';
        }
    });

    $uibModal.open({
        animation: $ctrl.animationsEnabled,
        ariaLabelledBy: 'modal-title-top',
        ariaDescribedBy: 'modal-body-top',
        templateUrl: 'stackedModal.html',
        size: 'sm',
        controller: function ($scope) {
            $scope.name = 'top';
        }
    });
};

$ctrl.toggleAnimation = function () {
    $ctrl.animationsEnabled = !$ctrl.animationsEnabled;
};
});

// Please note that $uibModalInstance represents a modal window (instance) dependency. // It is not the same as the $uibModal service used above.

angular.module('Application').controller('ModalInstanceCtrl', function 
($uibModalInstance, StaffService, items) {
var $ctrl = this;
$ctrl.items = items;
$ctrl.selected = {
    item: $ctrl.items[0]
};

$ctrl.ok = function () {
    alert($ctrl.newUser.Forename);
    alert($ctrl.newUser.Surname);
    //$uibModalInstance.close($ctrl.selected.item); //Untill we do the saving staff
};

$ctrl.cancel = function () {
    $uibModalInstance.dismiss('cancel');
};
});

// Please note that the close and dismiss bindings are from $uibModalInstance.

angular.module('Application').component('modalComponent', {
templateUrl: 'myModalContent.html',
bindings: {
    resolve: '<',
    close: '&',
    dismiss: '&'
},
controller: function () {
    var $ctrl = this;

    $ctrl.$onInit = function () {
        $ctrl.items = $ctrl.resolve.items;
        $ctrl.selected = {
            item: $ctrl.items[0]
        };
    };

    $ctrl.ok = function () {
        $ctrl.close({ $value: $ctrl.selected.item });
    };

    $ctrl.cancel = function () {
        $ctrl.dismiss({ $value: 'cancel' });
    };
}
});`

I have a staff controller here that returns data from an API call, to populate the UI grid.`

var editButtonTemplate = '<div class="ui-grid-cell-contents"><button type= 
"button" class="btn btn-xs btn-primary" ng-
click="grid.appScope.vm.editRow(grid, row)" <i class="fa fa-edit"></i>
</button></div>'

/*Staff Grid*/
app.controller('ApiStaffController', function ($scope, StaffService) {

$scope.gridOptions = {
    data: 'Data',
    enableFiltering: true,
    showGroupPanel: true,
    enableGridMenu: true,
    resizable: true,
    enableColumnResizing: true,
    enableRowSelection: true,
    enableRowHeaderSelection: false,
    showGridFooter: true,
    noUnselect: true,
    multiSelect: false,
    modifierKeysToMultiSelect: false,
    noUnselect: true,
    columnDefs: [{ field: 'person.forename', displayName: 'Forename' },
    { field: 'person.surname', displayName: 'Surname' },
    { field: 'person.dateofbirth', displayName: 'DOB' },
    { field: 'employmentStartDate', displayName: 'Employment Start Date' },
    { field: 'employmentEndDate', displayName: 'Employment End Date' },
    { name: 'edit', displayName: 'Edit', cellTemplate: editButtonTemplate },
    { name: 'delete', displayName: 'Delete', cellTemplate: '<button id="deleteBtn" type="button" class="btn-xs btn-danger fa fa-1x fa-trash-o" ng-click="$parent.$parent.deleteTeam(row.entity)"></button> ' }]
};

/*Gets all the staff records using the service*/
GetAllStaff();
function GetAllStaff() {
    var promiseGet = StaffService.getAllStaff();
    promiseGet.then(function (pl) { $scope.Staff = pl.data, $scope.Data = pl.data },
        function (errorPl) {
            $log.error('Error Getting Records.', errorPl);
        });
}
});
1
Have you look at this post stackoverflow.com/questions/32950698/… ?Amadou Beye
I have seen it yes, but it has not helped me unfortunately. @AmadouBeyeDavid B

1 Answers

0
votes

I managed to resolve this by injecting: $uibModal into the staff controller like below: app.controller('ApiStaffController', function ($scope, StaffService, $uibModal)

Then testing it by displaying the modal like this:

  var modalInstance = $uibModal.open({
    templateUrl: 'myModalContent.html',
    scope: $scope, //passed current scope to the modal
    size: 'lg'
});

If there is a better / more flexible way of doing this I appreciate all feedback, thanks.