Reputation: 1310
I've created a simple task list in AngularJS.
http://jsfiddle.net/simonbingham/RX63v/
HTML
<body ng-app="tasklist" ng-controller="TaskListController as taskListCtrl">
<div class="container">
<h1>Task List</h1>
<form ng-submit="taskListCtrl.addTask(task)">
<table class="table">
<tr>
<td style="width:20px;"></td>
<td><input type="text" ng-model="taskListCtrl.task.text"></td>
</tr>
</table>
</form>
<table class="table">
<tr ng-repeat="task in taskListCtrl.tasks | orderBy:['done', '-created']">
<td style="width:20px;"><input type="checkbox" ng-model="task.done"></td>
<td class="done-{{task.done}}">
<input type="text" ng-model="task.text" ng-blur="showInput=false" ng-show="showInput">
<a href="" ng-click="showInput=true" ng-hide="showInput">{{task.text}}</a>
</td>
</tr>
</table>
</div>
</body>
JS
(function () {
var app = angular.module('tasklist', []);
app.controller('TaskListController', function() {
var taskList = this;
taskList.tasks = [
{text:'do something 1', done:false, created:new Date(14, 1, 1)},
{text:'do something 2', done:true, created:new Date(14, 1, 2)},
{text:'do something 3', done:false, created:new Date(14, 1, 3)},
{text:'do something 4', done:true, created:new Date(14, 1, 4)},
{text:'do something 5', done:true, created:new Date(14, 1, 5)}
];
taskList.addTask = function (task) {
taskList.task.done = false;
taskList.task.created = new Date();
taskList.tasks.push(taskList.task);
taskList.task = {};
};
});
})();
You can click a task to edit it, but when the input field is shown I would like it to be given focus so the caret appears in the input field at the end of the current text. Currently when the input field is shown you need to click it again to give it focus.
I've tried various things, but can't figure out how to do it. Does anyone have any ideas?
Upvotes: 2
Views: 1803
Reputation: 48212
According to that answer, the simplest way is to focus the element and set:
el.selectionStart = el.selectionEnd = el.value.length;
You can create a custom directive that does that when a certain condition becomes true (and pass it the same condition that is passed to ngShow
.
This directive, will effectively set the cursor at the end of the text-field, when it get's displayed.
E.g.:
.directive('focusInputOn', function ($timeout) {
return {
restrict: 'A',
link: function focusInputOnPostLink(scope, elem, attrs) {
attrs.$observe('focusInputOn', function (newValue) {
if (newValue) {
// Since the element will become visible (and focusable) after
// the next render event, we need to wrap the code in `$timeout`
$timeout(function () {
var el = elem[0];
el.focus();
el.selectionStart = el.selectionEnd = el.value.length;
});
}
});
}
};
});
<input type="text" ... ng-show="showInput" focus-input-on="{{showInput}}" />
See, also, this short demo.
Make sure you test this feature on all browsers you plan to support, because some older browsers might not support certain things.
I tested it on latest Chrome (v35), latest Firefox (v30) and IE v10/11 and it works fine.
Upvotes: 4