prograde prograde - 5 months ago 104
AngularJS Question

Trigger OK click by pressing enter in ui-bootstrap modal

I've got a simple ui-bootstrap modal with a template like this:

<div class="modal-header">
<h3 class="modal-title">{{title}}</h3>
</div>
<div class="modal-body">
{{body}}
</div>
<div class="modal-footer">
<button class="btn btn-default"
ng-click="cancel()">
Cancel
</button>
<button class="btn btn-primary"
ng-click="ok()">
OK
</button>
</div>


Default behaviour of the modal is that the modal is closed if I press Escape. In the same way, I want the ok() method to be triggered if I press Enter. How do I do that?

Answer

Thanks to Diana R who led me to this answer:

I can use a ng-enter directive, as described here: https://gist.github.com/EpokK/5884263

That will allow my modal to listen fors the Enter key. But focus needs to be in the modal for it to work. So I also create a directive that I call focused:

angular.module('webApp').directive('focused', function ($timeout, $parse) {
    return {
        link: function ($scope, element, attributes) {
            var model = $parse(attributes.focused);
            $scope.$watch(model, function (value) {
                if (value === true) {
                    $timeout(function () {
                        element[0].focus();
                    });
                }
            });

            // set attribute value to 'false' on blur event:
            element.bind('blur', function () {
                if (model && model.assign) {
                    $scope.$apply(model.assign($scope, false));
                }
            });
        }
    };
});

Then I update my modal template so that it looks like this:

<div ng-enter="ok()">
    <div class="modal-header">
        <h3 class="modal-title">{{title}}</h3>
    </div>
    <div class="modal-body">
        {{body}}
    </div>
    <div class="modal-footer">
        <button class="btn btn-default"
                ng-click="cancel()">
            Cancel
        </button>
        <button class="btn btn-primary"
                focused="true"
                ng-click="ok()">
            OK
        </button>
    </div>
</div>

Since the focused="true" directive is inside the wrapping div with the ng-enter directive, the enter key will trigger the ok() method.