define(function() {
    'use strict';

    return ['$compile', '$timeout', function CountdownDirective($compile, $timeout) {
        return {
            scope: {},
            link: function(scope, element, attrs) {
                var limit = attrs.maxlength;
                var span = $compile('<span class="countdown" ng-class="countdown.status">{{ charsLeft }}</span>')(scope);

                scope.charsLeft = attrs.maxlength;
                element.after(span);

                function limitCheck(event) {
                    var length = element.val().length;
                    var code = event.keyCode;

                    if (length < limit) {
                        return;
                    }

                    switch (code) {
                        case 8: // allow delete
                        case 9:
                        case 17:
                        case 36: // and cursor keys
                        case 35:
                        case 37:
                        case 38:
                        case 39:
                        case 40:
                        case 46:
                        case 65:
                            return;
                    }
                }

                var updateCount = function() {
                    $timeout(function() {
                        var length = element.val().length;
                        var diff = limit - length;
                        var status = 'text-success';

                        scope.charsLeft = diff || 0;

                        if (scope.charsLeft < attrs.maxlength * 0.3) {
                            status = 'text-warning';
                        }

                        if (scope.charsLeft < attrs.maxlength * 0.1) {
                            status = 'text-danger';
                        }

                        scope.countdown = {
                            status: status
                        };

                        // Truncate
                        if (diff < 0) {
                            element.val(element.val().substr(0, limit));

                            updateCount();
                        }
                    }, 0);
                };
                element.focus(updateCount).change(updateCount);
                element.keyup(updateCount).change(updateCount);
                element.keydown(limitCheck);

                updateCount();
            }
        };
    }];
});
define([
    'jquery'
], function($) {
    'use strict';

    return ['$rootScope', '$scope', 'RevenueFactory', function RevenueController($rootScope, $scope, RevenueFactory) {
        $scope.revenues = RevenueFactory.getRevenues();

        $scope.createRevenue = function() {
            $scope.$emit('revenue.initialize', {});

            $('#revenue-modal').modal('show');
            dialog.result.finally(function() {
              alert('clean up resources');
            });
        };

        $scope.editRevenue = function(revenue) {
            $scope.$emit('revenue.initialize', revenue);

            $('#revenue-modal').modal('show');
        };

        $scope.removeRevenue = function(revenue) {
            RevenueFactory.removeRevenue(revenue);
        };

        $rootScope.$on('revenue.created', function(scope, revenue) {
            $scope.revenues.push(revenue);
        });

        $scope.CharCount = function(scope, element, attrs) {
            scope.charsLeft = attrs.maxlength;
            updateCount();
        };
    }];
});
<div id="revenue-modal" class="modal fade" ng-controller="RevenueController" ng-click="CharCount">
    <div class="modal-dialog">
        <div class="modal-content">
            <form name="revenue" action="{% verbatim %}{{ url }}{% endverbatim %}" method="post" novalidate autocomplete="off" xhr xhr-success="{% verbatim %}{{ callback }}{% endverbatim %}">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                    <h4 class="modal-title">{% verbatim %}{{ ('revenues.' + action + '.title') | trans }}{% endverbatim %}</h4>
                </div>

                <div class="modal-body">
                    <div ng-include="'errors.html'"></div>

                    <input type="hidden" name="_method" ng-value="method">
                    <input type="hidden" name="id" ng-value="model.id">

                    <div class="form-group" ng-class="{ 'has-error': revenue.name.$invalid }">
                        <label>{{ 'revenues.form.name.label'|trans }}</label>
                        <input name="name" type="text" class="form-control" ng-model="model.name" ng-required="true" countdown maxlength="80" placeholder="{{ 'revenues.form.name.placeholder'|trans }}">
                    </div>
                </div>

                <div class="modal-footer">
                    <button type="button" class="btn btn-link" data-dismiss="modal">{% verbatim %}{{ ('revenues.' + action + '.actions.cancel') | trans }}{% endverbatim %}</button>
                    <button type="submit" class="btn btn-primary">{% verbatim %}{{ ('revenues.' + action + '.actions.submit') | trans }}{% endverbatim %}</button>
                </div>
            </form>
        </div>
    </div>
</div>