AngularJS: File browser directive

by Danish Farman

HTML

<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/css/bootstrap-combined.min.css">
<script src="http://code.jquery.com/jquery.js"></script>
<script src="http://code.angularjs.org/1.0.3/angular.js"></script>
<div ng-controller="parentController">
    <p><a ng-click="load('one.tpl')">One</a> | <a ng-click="load('two.tpl')">Two</a></p>
    <hr>
    <div ng-include="tpl"></div>
</div>

<script type="text/ng-template" id="one.tpl">
    <p>Template One</p>
    <div file-browser>
        <input type="file" name="upload-file">
    </div>
</script>
<script type="text/ng-template" id="two.tpl">
    <p>Template Two</p>
</script>

CSS

body {padding:20px}
.proxied-field-wrap {
    display:block;
    position:absolute;
    height:0;
    width:0;
    overflow:hidden;
}

JavaScript

angular.module('testapp', []);
angular.module('testapp').controller('parentController', function($scope) {
    $scope.load = function(tpl) {
        $scope.tpl = tpl;
    };
    $scope.load('one.tpl');
});
angular.module('testapp').directive('fileBrowser', function() {
    return {
        restrict: 'A',
        replace: true,
        transclude: true,
        scope: false,
        template:
            '<div class="input-prepend extended-date-picker">'+
                '<input type="button" class="btn" value="browse...">'+
                '<input type="text" readonly class="override">'+
                '<div class="proxied-field-wrap" ng-transclude></div>'+
            '</div>',
        link: function($scope, $element, $attrs, $controller) {
            var button, fileField, proxy;
            fileField = $element.find('[type="file"]').on('change', function() {
                proxy.val(angular.element(this).val());
            });
            proxy = $element.find('[type="text"]').on('click', function() {
                fileField.trigger('click');
            });
            button = $element.find('[type="button"]').on('click', function() {
                fileField.trigger('click');
            });
        }
    };
});