Search code examples
javascriptangularjsmddialog

Angular - modal MdDialog local controller vs. app level display shadow


I have been trying to use an app level controller to display a modal dialog. Tests of the local function controller work perfectly, however the app level controller is displaying a grey shadow rather than the dialog as desired.

The results of edit and delete (in this example) should behave the same, but they are not.

Plunker link

Thanks in advance.

index.HTML

 <!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <title>Sandbox Angular</title>
    <!-- Bootstrap Core CSS -->
    <link rel="stylesheet" href="assets/css/bootstrap.min.css">
    <!-- Content CSS -->
    <link rel="stylesheet" href="Content/angular-material.css">
    <link rel="stylesheet" href="Content/ui-grid.css">
</head>
<!--<body ng-app="mainApp">-->
<body>
    <div class="container">
        <div ng-controller="HeaderGridCtrl">
            <div class="grid" ui-grid="gridOptions" ui-grid-edit ui-grid-resize-columns></div>
        </div>
    </div>
        <!-- /.container -->
    <script src="Scripts/angular.js"></script>
    <script src="Scripts/angular-material/angular-material.js"></script>
    <script src="Scripts/angular-animate/angular-animate.js"></script>
    <script src="Scripts/angular-aria/angular-aria.js"></script>
    <script src="Scripts/ui-grid.js"></script>
    <script src="app/app.module.js"></script>
</body>
</html>

testEdit.HTML

<md-dialog>
<div>
    <form ng-cloak>
        <md-toolbar>
            <div class="md-toolbar-tools">
                <h2>{{firstName}} {{lastName}} ({{action}})</h2>
                <span flex></span>
            </div>
        </md-toolbar>
        <md-dialog-content>
            <div class="md-dialog-content">
                <p>
                    Life's actions....make sure the juice is worth the squeeze.
                </p>
            </div>
        </md-dialog-content>

    </form>
</div>

testDelete.HTML

<md-dialog>
<div ng-controller="DetailRecordCtrl">
    <form ng-cloak>
        <md-toolbar>
            <div class="md-toolbar-tools">
                <h2>{{firstName}} {{lastName}} ({{action}})</h2>
                <span flex></span>
            </div>
        </md-toolbar>
        <md-dialog-content>
            <div class="md-dialog-content">
                <h2>{{firstName}} {{lastName}} ({{action}})</h2>
                <p>
                    Life's actions....make sure the juice is worth the squeeze.
                </p>
            </div>
        </md-dialog-content>
    </form>
</div>

app.module.js

(function () {
'use strict';
//,'ui.router''ngGrid'
var app = angular.module('app', ['ngMaterial', 'ui.grid', 'ui.grid.resizeColumns']);

app.controller('DetailRecordCtrl', ['$scope', '$mdDialog', 'action', 'currentRow', initDetail])
app.controller('HeaderGridCtrl', ['$scope', '$mdDialog', initGrid]);
app.controller('testDialogCtrl', ['$scope', '$mdDialog', initModalTest]);

//---------------------------------
app.run([function () {
    /* Run is when the app gets kicked off*/
    console.log("Run processed");
}])

//---------------------------------
function initDetail($scope, $mdDialog, action, currentRow) {
    $scope = $scope;
    $scope.action = action;
    $scope.firstName = currentRow.entity.firstName;
    $scope.lastName = currentRow.entity.lastName;
    $scope.closeDialog = function () {
        $mdDialog.hide();
    };
}

//---------------------------------
function initGrid($scope, $mdDialog) {
    var currentRow = 0;

    $scope.showDelete = function (ev, keyAction, row) {
        $mdDialog.show({
            locals: { action: keyAction, currentRow: row },
            controller: 'DetailRecordCtrl',
            scope: $scope,
            preserveScope: true,
            targetEvent: ev,
            clickOutsideToClose: true,
            skipHide: true,
            fullscreen: $scope.customFullscreen // Only for -xs, -sm breakpoints.
        })
    };

    $scope.showEdit = function (ev, keyAction, row) {
        $mdDialog.show({
            locals: { action: keyAction, currentRow: row },
            controller: LocalDetailRecordCtrl,
            templateUrl: 'testEdit.html',

            scope: $scope,
            preserveScope: true,
            ariaLabel: 'Edit Record',
            targetEvent: ev,
            clickOutsideToClose: true,
            fullscreen: $scope.customFullscreen // Only for -xs, -sm breakpoints.
        })

    };

    $scope.editIcon = '<button class="md-primary md-raised" ng-click="grid.appScope.showEdit($event,\'EDIT\',row)">EDIT</button> ';
    $scope.deleteIcon = '<button class="md-primary md-raised" ng-click="grid.appScope.showDelete($event,\'DELETE\',row)">DELETE</button>';
    $scope.info = [{ firstName: "Jimmy", lastName: "John", grade: '1st', contributionDay01: 5.12, total: 0 },
                    { firstName: "Jane", lastName: "Pauley", grade: '2nd', contributionDay01: 4, total: 0 },
                    { firstName: "Andrea", lastName: "Kragel", grade: '3rd', contributionDay01: 11.28, total: 0 },
                    { firstName: "Zebra", lastName: "Zoo", grade: 'PK', contributionDay01: 19.23, total: 0 },
                    { firstName: "Jaguar", lastName: "Meowser", grade: 'K', contributionDay01: 25, total: 0 }];
    $scope.gridOptions = {
        data: 'info',
        enableFiltering: true,
        enableColumnResizing: true,
        enableSorting: false,

        enableRowHeaderSelection: true,
        enableColumnMenus: true,
        enableCellEditOnFocus: true,
        enableRowSelection: true,
        enableCellEdit: true,
        noUnselect: false,
        cellTemplate: '<div ng-repeat="col in renderedColumns"></div>',

        columnDefs: [
            {
                field: 'wrkDisplay', displayName: 'Actions', enableCellEdit: false, width: '*'
                , cellTemplate:
                    '<div class="testClass">' + $scope.editIcon + ' ' + $scope.deleteIcon + ' ' +
                    '</div>'
            },
            { field: 'firstName', displayName: 'First Name', enableCellEdit: true, minWidth: 100, },
            { field: 'lastName', displayName: 'Last Name', enableCellEdit: true, minWidth: 100 },
            { field: 'grade', displayName: 'Grade', enableCellEdit: true, minWidth: 70 },
            { field: 'getFullName()', displayName: 'Teacher', enableCellEdit: true, minWidth: 100 },
            { field: 'contributionDay01', displayName: 'Day1', enableCellEdit: true, minWidth: 50, cellFilter: 'number: 2' },
            { field: 'getTotal()', displayName: 'Total', enableCellEdit: false, cellFilter: 'currency' }]
    };

    //Calaculated fields
    angular.forEach($scope.info, function (row) {
        row.getTotal = function () {
            return this.contributionDay01 * 11;
        }
        row.getFullName = function () {
            return (this.firstName + ' ' + this.lastName);
        }

    });

    function LocalDetailRecordCtrl($scope, $mdDialog, action, currentRow) {
        $scope.action = action;
        $scope.firstName = currentRow.entity.firstName;
        $scope.lastName = currentRow.entity.lastName;
        $scope.closeDialog = function () {
            $mdDialog.hide();
        }
    };

}
})();

Solution

  • Issue resolved after looking at the Angular $mdDialog documentation for the n-th time.

    The controller listed under the $mdDialog.show method can be declared both with or without quotes.

    • Without quotes uses the local $scope function defined.
    • With quotes uses the app level controller [i.e. app.controller(...)] Additionally, the template / templateUrl can be used.

    This now enables me to have a single HTML detail record page that can be accessed from multiple data points if necessary.