Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

knockout.js set focus in a template

Tags:

knockout.js

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);
like image 391
Richard Avatar asked Feb 26 '12 09:02

Richard


2 Answers

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

like image 73
Vladimir Posvistelik Avatar answered Nov 15 '22 14:11

Vladimir Posvistelik


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

like image 23
79IT Avatar answered Nov 15 '22 14:11

79IT