Angular ngTarget Demonstration

I propose this method of setting focus in angular. You add the ng-target attribute to your element, then call .focus() on the $scope variable you specified. Works for blur() and select() too. Details blogged here: http://goo.gl/4rdZa

by bseib

HTML

<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.js"></script>
<div class="box">
    <div ng-app="myApp" ng-controller="MyCtrl">
         <h3>Demo of ng-target</h3>

        <input type="text" x-ng-model="form.color" x-ng-target="form.colorTarget"x-ng-change="onChange()">    
        <span>type "blur" to blur</span>
        <br/>
        <button class="btn" x-ng-click="form.colorTarget.focus()">do focus</button>
        <button class="btn" x-ng-click="form.colorTarget.blur()" disabled>do blur</button>
        <button class="btn" x-ng-click="form.colorTarget.select()">do select</button>
        <br/>
        <br/>
        <h3>Demo of ng-target with ng-repeat</h3>
        <div x-ng-repeat="p in people">
            <span>{{$index}}</span>
        	<span x-ng-bind="p.name"></span>
            <input type="text" x-ng-target="p" x-ng-model="p.val" x-ng-change="('blur'==p.val)&&p.blur()">
            <button class="btn btn-mini" x-ng-click="p.select()">select</button>
            <span>type "blur" to blur</span>
        </div>
        <button class="btn" x-ng-click="people[0].focus()">focus item 0</button>
        <button class="btn" x-ng-click="people[2].blur()" disabled>blur item 2</button>
        <button class="btn" x-ng-click="people[3].select()">select item 3</button>
            <br/>
            <br/>
            <a target="_top" href="http://goo.gl/4rdZa">Details blogged here: http://goo.gl/4rdZa</a>
    </div>
</div>
</div>

CSS

@import url('http://twitter.github.com/bootstrap/assets/css/bootstrap.css');
.box {
    margin-top: 10px;
    margin-left: 10px;
}

JavaScript

var myApp = angular.module('myApp', []);

myApp.controller('MyCtrl', function ($scope) {

    $scope.form = { color: '' };
    $scope.onChange = function () {
        if ("blur" === $scope.form.color) {
            $scope.form.colorTarget.blur();
        }
    };

    $scope.people = [
		{id: 123, name: 'alice'},
		{id: 714, name: 'bob'},
		{id: 531, name: 'carly'},
		{id: 284, name: 'dave'},
	];

});

angular.module('ng').directive('ngTarget', function ($parse, $timeout) {
    var NON_ASSIGNABLE_MODEL_EXPRESSION = 'Non-assignable model expression: ';
    return {
        restrict: "A",
        link: function (scope, element, attr) {
            var buildGetterSetter = function (name) {
                var me = {};
                me.get = $parse(name);
                me.set = me.get.assign;
                if (!me.set) {
                    throw Error(NON_ASSIGNABLE_MODEL_EXPRESSION + name);
                }
                return me;
            };

            // *********** focus *********** 
            var focusTriggerName = attr.ngTarget + "._focusTrigger";
            var focusTrigger = buildGetterSetter(focusTriggerName);
            var focus = buildGetterSetter(attr.ngTarget + ".focus");

            focusTrigger.set(scope, 0);
            focus.set(scope, function () {
                focusTrigger.set(scope, 1);
            });

            // $watch the trigger variable for a transition
            scope.$watch(focusTriggerName, function (newValue, oldValue) {
                if (newValue > 0) {
                    $timeout(function () { // a timing workaround hack
                        element[0].focus(); // without jQuery, need [0]
                        focusTrigger.set(scope, 0);
                    }, 50);
                }
            });

            // *********** blur *********** 
            var blurTriggerName = attr.ngTarget + "._blurTrigger";
            var blurTrigger = buildGetterSetter(blurTriggerName);
            var blur =...