How can I use knockout.js
to set focus on an element that was created by a template bound to an array?
I have an observable array bound to a table, where each row is a set of input elements to allow the array element's properties to be edited. At the bottom is an "Add"
button which pushes a new element into the array, creating a new row of input fields.
What I'm trying to do is have the focus set to the first of the newly created input fields after the "Add"
button has been pressed.
HTML:
<html>
<head>
<script src="http://cdn.jsdelivr.net/knockout/3.0.0/knockout.debug.js"></script>
</head>
<body>
<table data-bind='foreach: Attributes'>
<tr>
<td><input type='text' data-bind='value: Name, disable: HardCoded/></td>
<td><input type='text' data-bind='value: Description'/></td>
<td><button data-bind="click: $parent.removeAttribute">Delete</button></td>
</tr>
</table>
<button data-bind="click: addAttribute">Add attribute</button>
</body>
</html>
Javascript:
function Attribute(id, name, description, hardcoded) {
var self=this;
self.AttributeID=ko.observable(id || 0);
self.Name=name || '';
self.Description=description || '';
self.HardCoded=hardcoded || false;
self.nameFocus = true;
}
function AttributeSchema(attributeArray) {
var self=this;
// Properties
self.Attributes=ko.observableArray(attributeArray);
// Operations
self.addAttribute=function() {
self.Attributes.push(new Attribute());
};
self.removeAttribute=function() {
self.Attributes.remove(this);
};
}
var vmSchema=new AttributeSchema(
[
new Attribute(5, 'FirstName', 'First Name', true),
new Attribute(6, 'LastName', 'Last Name', true),
new Attribute(7, 'Blah', 'Blah', false)
]
);
ko.applyBindings(vmSchema);
Currently, you have such code:
<input type='text' data-bind='value: Name, disable: HardCoded' />
You can try to add the property hasfocus: true
:
<input type='text' data-bind='value: Name, disable: HardCoded, hasfocus: true' />
See: http://knockoutjs.com/documentation/hasfocus-binding.html
I have a field where visibility is determined by a checkbox and I wanted the field to get focus as soon as it became visible. Using the default hasfocus binding meant that the field became hidden as soon as it lost focus.
To solve this I created a "oneway" hasfocus binding like this:
ko.bindingHandlers.koFocus = {
update: function (element, valueAccessor) {
var value = valueAccessor();
var $element = $(element);
if (value()) {
$element.focus();
}
}
};
I then replaced:
data-bind="hasfocus: myObservable"
with:
data-bind="koFocus: myObservable"
Problem solved
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With