I am developing a table editor with Ember.js. I created a view called FocusedTextFieldthat focuses the text box when it is rendered. I want to implement this tabbing feature so that tab targeting focuses the next cell in the row. The current code changes the currently selected cell, which will be invalid, and changes the next cell as a text field, but will not focus on the next field value. It seems that the code is not working, it is a time effect. What is the best way to approach this issue?
Here is my JSBin: http://emberjs.jsbin.com/tey/12/edit
jQuery 1.10.2 Steering racks 1.2.1 Ember 1.1.2
HTML:
<script type="text/x-handlebars" data-template-name="row">
<tr>
{{#collection cellCollection}}
{{view view.content.view}}
{{/collection}}
</tr>
</script>
<script type="text/x-handlebars" data-template-name="cell">
<td {{action "click"}}>
{{#if editMode}}
{{view textField valueBinding=value}}
{{else}}
{{value}}
{{/if}}
</td>
</script>
<script type="text/x-handlebars" data-template-name="table">
<table>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Points</th>
</tr>
{{#collection rowCollection}}
{{view view.content.view}}
{{/collection}}
</table>
</script>
<div id="main"></div>
JavaScript:
App = Ember.Application.create();
var TemplatedViewController = Ember.Object.extend({
templateFunction: null,
viewArgs: null,
viewBaseClass: Ember.View,
view: function () {
var controller = this;
var viewArgs = this.get('viewArgs') || {};
var args = {
template: controller.get('templateFunction'),
controller: controller
};
args = $.extend(viewArgs, args);
return this.get('viewBaseClass').extend(args);
}.property('templateFunction', 'viewArgs'),
appendView: function (selector) {
this.get('view').create().appendTo(selector);
},
appendViewToBody: function () {
this.get('view').create().append();
},
appendPropertyViewToBody: function (property) {
this.get(property).create().append();
}
});
var FocusedTextField = Ember.TextField.extend({
focusTheTextField: function() {
this.$().focus();
}.on('didInsertElement')
});
var Cell = TemplatedViewController.extend({
row: null,
editMode: false,
value: null,
textField: function () {
var cell = this;
return FocusedTextField.extend({
keyDown: function (event) {
if (event.keyCode === 13) {
cell.set('editMode', false);
} else if (event.keyCode === 9) {
cell.set('editMode', false);
var nextCell = cell.getNextCell();
nextCell.set('editMode', true);
}
}
});
}.property(),
flipEditMode: function () {
if (this.get('editMode')) {
this.set('editMode', false);
} else {
this.set('editMode', true);
}
},
click: function () {
console.log('cell clicked, value: '+this.get('value'));
this.flipEditMode();
},
getNextCell: function () {
return this.get('row').getNextCell(this);
},
view: function () {
var controller = this;
return this.get('viewBaseClass').extend({
controller: controller,
templateName: 'cell'
});
}.property()
});
var Row = TemplatedViewController.extend({
headers: ['firstName', 'lastName', 'points'],
firstName: null,
lastName: null,
points: null,
cells: null,
cellCollection: function () {
return Ember.CollectionView.extend({
content: this.get('cells')
});
}.property('cells'),
init: function () {
this._super();
var row = this;
var cells = [];
this.get('headers').forEach(function (item, index, enumerable) {
var header = item;
var value = row.get(header);
var cell = Cell.create({
row: row,
value: value
});
cells.pushObject(cell);
});
this.set('cells', cells);
},
getNextCell: function (cell) {
if (this.get('cells').contains(cell)) {
var lastIndex = this.get('cells').length - 1;
var cellIndex = this.get('cells').indexOf(cell);
if (cellIndex < lastIndex) {
var nextIndex = cellIndex + 1;
return this.get('cells')[nextIndex];
}
}
},
view: function () {
var controller = this;
return this.get('viewBaseClass').extend({
controller: controller,
templateName: 'row'
});
}.property()
});
var rows = [];
var DATA = [
{first_name: 'Jill', last_name: 'Smith', points: 50},
{first_name: 'Eve', last_name: 'Jackson', points: 94},
{first_name: 'John', last_name: 'Doe', points: 80},
{first_name: 'Adam', last_name: 'Johnson', points: 67}
];
DATA.forEach(function (item, index, enumerable) {
var row = Row.create({
firstName: item.first_name,
lastName: item.last_name,
points: item.points
});
rows.pushObject(row);
});
var Table = TemplatedViewController.extend({
view: function () {
var controller = this;
return this.get('viewBaseClass').extend({
controller: controller,
templateName: 'table'
});
}.property(),
rows: null,
rowCollection: function () {
return Ember.CollectionView.extend({
content: this.get('rows')
});
}.property('rows')
});
var table = Table.create({rows: rows});
$(function () {
table.appendView('#main');
});