Menu

Bootstrap Modal with AngularJS

September 22, 2015 by Christopher Sherman

To use demonstrate using the Bootstrap frameworks’s modal component within an AngularJS project, we’ll create a custom directive for editing text properties throughout an application. This example makes use the modal.js file that is part of the core Bootstrap framework.

In the directive below, you’ll notice we restrict the directive to being instantiated as an attribute only. This provides us with a nice hook on the element upon which the attribute appears. We take advantage of this hook within the link property at the bottom of the directive. Access to the element enables us to add a dismiss function to the directive’s scope, which hides the modal.

The directive’s scope property allows us to configure properties on the model, making it flexible enough to work in a variety of fashions. It also enables us to pass in objects from the parent scope.

Within the controller property, we initialize a property with the parent scope’s original value. We will use this property if the new value fails to be saved, allowing us to revert the parent scope’s object back to its original state.

Directive

angular.module('app.directives')
.directive('appEditTextPropertyModal', function () {
return {
restrict: 'A',
scope: {
heading: '@',
isPasswordProperty: '@',
item: '=',
itemProperty: '@',
label: '@',
submitFn: '&',
},
controller: function EditTextPropertyModalController($scope) {
// Public properties
$scope.originalValue = undefined;

                // Public methods.
                $scope.cancel = cancel;
                $scope.submitFunction = submitFunction;

               $scope.item.$promise.then(initializeOriginalValue);

                // Private methods.
                function cancel () {
                    // Reset item to its original value.
                   $scope.item[$scope.itemProperty] = $scope.originalValue;
                }

                function initializeOriginalValue() {
                  $scope.originalValue = $scope.item[$scope.itemProperty];
                }

                function submitFunction() {
                    return $scope.submitFn()
                        .then(function success() {
                            initializeOriginalValue();
                        })
                        .catch(function fail() {
                            cancel();
                        })
                        .finally(function always() {
                            $scope.dismiss();
                        });
                }
            },
            templateUrl: 'app/shared/views/_edit-text-property-modal.html',
            link: function (scope, element, attr) {
                scope.dismiss = function dismiss() {
                    element.modal('hide');
                };
            }
        };
    });

Template

<div class="modal-dialog">
    <div class="modal-content">
        <form name="myForm" ng-submit="myForm.$valid && submitFunction()" novalidate>
            <div class="modal-header">
                <button type="button" class="close" ng-click="cancel(); dismiss()">
                    <span aria-hidden="true">&times;</span>
                </button>

                <h1 class="h4">

{{heading}}

</h1>
</div>

            <div class="modal-body">
                <div class="form-group">
                    <label>

{{label}}
</label>

                    <input type="text" class="form-control"

ng-if="!isPasswordProperty"
ng-model="item[itemProperty]"
name="{{itemProperty}}"
ng-model-options="{ updateOn: 'submit' }"
required />

                    <input type="password" class="form-control"

ng-if="isPasswordProperty"
ng-model="item[itemProperty]"
name="{{itemProperty}}"
ng-model-options="{ updateOn: 'submit' }"
required />

                    <div class="error-message" ng-messages="myForm[itemProperty].$error"

ng-if="myForm.$submitted || myForm[itemProperty].$touched">
<validation-messages></validation-messages>

</div>
</div>
</div>

            <div class="modal-footer">
                <button type="button" class="btn btn-default" ng-click="cancel(); dismiss()">

Cancel
</button>

                <button type="submit" class="btn btn-primary">

Update
</button>

</div>
</form>
</div>

</div>

Usage

<div app-edit-text-property-modal class="modal fade name-modal" heading="Object name"
label="Enter a new name for this object." 
submit-fn="updateObjectName()"
item="myObj" 
item-property="name">
</div>

AngularJS Twitter Bootstrap