Tuesday, October 9, 2012

Set focus on input upon click on ng-repeat

Live test: http://jsfiddle.net/epAxT/5/


Model and Controller:

function TestController($scope) {
        
    // Models
    $scope.messages = 
    [
    { Message: 'Life is what happens to you...', By: 'John Lennon' },
    { Message: 'If you can\'t explain...', By: 'Albert Einstein' },
    { Message: 'The answer to life...', By: 'Douglas Adams' }
    ];
    
    
    $scope.currentMessage = null;
    
    // Controller's actions
    
    $scope.setCurrentMessage = function(msg) {
        $scope.currentMessage = msg;
    };

    $scope.isCurrentMessage = function(msg) {
        return msg == $scope.currentMessage;
    };
    
    $scope.addMessage = function() {
        var msg = {Message: 'blah', By: 'Anonymous'};
        $scope.currentMessage = msg;
        $scope.messages.push(msg);
    };
    
}
    
    


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

appGreat.directive('toFocus', function ($timeout) {
    return function (scope, elem, attrs) {
        scope.$watch(attrs.toFocus, function (newval) {
            if (newval) {
                $timeout(function () {
                    elem[0].focus();
                }, 0, false);
            }
        });
    };
});
​


View:
<br/>
<div ng-app='AppGreat' ng-controller='TestController'>
    
    <table>
        <thead>
            <tr>
                <th>Message</th><th>By</th>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat='m in messages'>
                <td width='200px'>
                    <div ng-hide='isCurrentMessage(m)' 
                         ng-click='setCurrentMessage(m)'>
                        {{m.Message}}
                    </div>
                    <div ng-show='isCurrentMessage(m)'>
                        <input ng-model='m.Message'
                               to-focus='isCurrentMessage(m)'
                               style='width: 100%' />
                    </div>
                    
                    
                </td>
                
                <td>
                    <div ng-hide='isCurrentMessage(m)' 
                         ng-click='setCurrentMessage(m)'>
                        {{m.By}}
                    </div>
                    <div ng-show='isCurrentMessage(m)'>
                        <input ng-model='m.By'/>                        
                    </div>
                </td>
            </tr>
        </tbody>
    </table>
    
    
    <input type='button' ng-click='addMessage()' value='Add Message'/>
    
</div>       ​

1 comment:

  1. Excellent! I'm not trying to do anything very similar, but this seems like a clean way to handle focus. Very educational.

    ReplyDelete