Reputation: 3956
Simple example below that re-orders fields on a form. Everytime you hit the "Top" button next to a row it should move it to the top of the list. The buttons seem to act in a few odd ways but I'll describe one for the sake of argument. Starting at the bottom click each button. You'll find that the console.log indicates that the field.order is always one but the UI doesn't quite match by the time you get to the last two; they remain as "10" and "20" in the textbox which is wrong but their order is still switched correctly.
Is this a ko bug or have I missed something?
Note:You should be able to copy and paste the code direct into an html file and run it.
<html>
<head>
<script src="http://knockoutjs.com/js/knockout-2.0.0.js" type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
function Field(name, order)
{
this.name = name;
this.order = order;
}
function Form() {
this.name = ko.observable("Test");
this.fields = ko.observableArray();
this.fields.push(new Field("field a", 10));
this.fields.push(new Field("field b", 20));
this.fields.push(new Field("field c", 30));
this.fields.push(new Field("field d", 40));
this.fields.push(new Field("field e", 50));
this.fields.push(new Field("field f", 60));
}
function AppViewModel() {
var self = this;
self.selectedForm = ko.observable(new Form());
reorderItems = function () {
self.selectedForm().fields.sort(
function (left, right) {
return (left.order == right.order)
? 0 : ((left.order < right.order) ? -1 : 1)
});
}
fieldMove = function (field) {
// find field in parent
var fldIdx = self.selectedForm().fields().indexOf(field);
field.order = 1;
console.log(field.order);
field.name = field.name + field.order;
// re-order the items
reorderItems();
}
}
$(document).ready(function () {
// Activates knockout.js
ko.applyBindings(new AppViewModel());
});
</script>
</head>
<body>
<div class="form" data-bind="with: selectedForm">
<!-- ko foreach: fields -->
<div class="field">
<span data-bind="html: name"></span>
<input data-bind="value: order"></input>
<button data-bind="click: fieldMove">Top</button>
</div>
<!-- /ko -->
</div>
</body>
Upvotes: 0
Views: 1426
Reputation: 15999
I'm not sure exactly why you were having problems, but I managed to get this working by replacing the standard properties of name
and order
with observable properties.
This working fiddle demonstrates the solution
Upvotes: 2