Reputation: 2817
I have a requirements in my project where I need to put my selected item in the Modal and user can click next to show the next item.
I am using a with binding to display the content of selected in a form. I don't have an idea on how can I apply paging inside a "With" binding.
<div class="container" data-bind="with: itemForEditing">
<div id="riskRegisterForm" class="modal hide fade">
<div class="modal-header" style="background:#4bafef; height: 30px;">
<h5 style="color:#FFFFFF; font:16px Arial;">Item</h5>
</div>
<div class="modal-body" style="background:#fff">
<div>
<form class="form-horizontal">
<div class="control-group">
<label class="control-label" for="itemName">Name</label>
<div class="controls">
<input type="text" id="itemName" data-bind="value: name" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="itemPrice">Price</label>
<div class="controls">
<input type="number" step=".01" id="itemPrice" data-bind="value: price" />
</div>
</div>
</form>
</div>
</div>
<div class="modal-footer">
<button type="button" data-dismiss="modal" class="btn" data-bind="click:$parent.revertItem">Cancel</button>
<button type="button" data-dismiss="modal" class="btn" data-bind="click:$parent.acceptItem">Update</button>
</div>
<span><a href=#>next</a></span>
<span><a href=#>prev</a></span>
</div>
</div>
when I click the next it should autmatically select the next records and put in the contorls. Here is the JsFiddle http://jsfiddle.net/ramon26cruz/Tt96J/6/
Upvotes: 1
Views: 332
Reputation: 2983
I've had a go at this. I changed my tack from above. Basically I created 2 method, a next and a prev. In the methods I find the index of the selected / editable object in the array and the either increment or decrement based on which method has been used. I then update the selected and editable property objects:
var Item = function(data) {
this.name = ko.observable();
this.price = ko.observable();
//populate our model with the initial data
this.update(data);
};
//can pass fresh data to this function at anytime to apply updates or revert to a prior version
Item.prototype.update = function(data) {
this.name(data.name || "new item");
this.price(data.price || 0);
};
var ViewModel = function(items) {
this.index = 0;
//turn the raw items into Item objects
this.items = ko.observableArray(ko.utils.arrayMap(items, function(data) {
return new Item(data);
}));
//hold the currently selected item
this.selectedItem = ko.observable();
//make edits to a copy
this.itemForEditing = ko.observable();
this.selectItem = this.selectItem.bind(this);
this.acceptItem = this.acceptItem.bind(this);
this.revertItem = this.revertItem.bind(this);
this.next = this.next.bind(this);
this.prev = this.prev.bind(this);
};
ko.utils.extend(ViewModel.prototype, {
//select an item and make a copy of it for editing
selectItem: function(item) {
this.selectedItem(item);
this.itemForEditing(new Item(ko.toJS(item)));
},
next:function(){
var pos = this.items.indexOf(this.selectedItem()) + 1;
if(pos > this.items().length - 1){pos = 0};
this.selectedItem(this.items()[pos]);
this.itemForEditing(new Item(ko.toJS(this.items()[pos])));
},
prev:function(){
var pos = this.items.indexOf(this.selectedItem()) - 1;
if(pos < 0){pos = this.items().length - 1};
this.selectedItem(this.items()[pos]);
this.itemForEditing(new Item(ko.toJS(this.items()[pos])));
},
acceptItem: function(item) {
var selected = this.selectedItem(),
edited = ko.toJS(this.itemForEditing()); //clean copy of edited
//apply updates from the edited item to the selected item
selected.update(edited);
//clear selected item
this.selectedItem(null);
this.itemForEditing(null);
},
//just throw away the edited item and clear the selected observables
revertItem: function() {
this.selectedItem(null);
this.itemForEditing(null);
}
});
ko.applyBindings(new ViewModel([
{ name: "Cheese", price: 2.50 },
{ name: "Pepperoni", price: 3.25 },
{ name: "Deluxe", price: 4.25 }
]));
Here's a link to my JS Fiddle.
Upvotes: 2
Reputation: 338336
One way to do it would be like this:
<div class="container" data-bind="with: itemForEditing">
<!-- ... -->
<span><a href=# data-bind="click: $root.nextItem">next</a></span>
<span><a href=# data-bind="click: $root.prevItem">prev</a></span>
</div>
and
ko.utils.extend(ViewModel.prototype, {
// offset the selected item by a certain amount (i.e. -1/+1 for next/prev)
offsetItem: function (by) {
var items = this.items(),
i = ko.utils.arrayIndexOf(items, this.selectedItem()),
newItem = (i > -1) ? items[i + by] : null;
if (newItem) {
this.selectItem(newItem);
}
},
prevItem: function () {
this.offsetItem(-1);
},
nextItem: function () {
this.offsetItem(1);
},
/* ... */
}
See it live http://jsfiddle.net/Tt96J/11/
Upvotes: 1