Reputation: 559
I am trying to cancel the changes done during my page edit. But whenever I click on cancel, the updated changes are reflected. How to revert the changes on click of cancel button. Any help on this will be really helpful since I am new to knockout
https://jsfiddle.net/tan2dgsa/
// ViewModel.js
var viewModel = {
articles: [{
id: 1,
title: "KnockOut Templating",
content: "Content for Knockout goes here."
}, {
id: 2,
title: "SharePoint 2013 REST API",
content: "Content for SharePoint."
}, {
id: 3,
title: "Knockout with SharePoint",
content: "Content for knockout and SharePoint."
}],
selectedTemplate: ko.observable("readOnly"),
selectedMode: ko.observable(),
};
viewModel.currentTemplate = function (tbl) {
return tbl === this.selectedMode() ? 'editMode' : this.selectedTemplate();
}.bind(viewModel);
viewModel.reset = function (t) {
this.selectedMode("editMode");
};
ko.applyBindings(viewModel);
Upvotes: 7
Views: 3206
Reputation: 565
If you're using KO Mapping plugin, this will be quite simple.
Hold parameter 'data' in another local variable, say 'originalData', and then simply call mapping plugin's function to re-map data.
For ex.,
var myKOViewModel = function(data) {
var self = this;
var originalData = data;
ko.mapping.fromJS(data, null, self); // ViewModel initial mapping
//....
self.CancelClicked = function () {
ko.mapping.fromJS(originalData, null, self); // Refresh ViewModel
}
}
Please refer to KO's documentation https://knockoutjs.com/documentation/plugins-mapping.html for more details.
Upvotes: 1
Reputation: 63729
You ask a rather broad question, or it is fact a To Do:
Create rollback functionality on KnockoutJS based edit forms
The question behind that to do is: what is the idiomatic way to do that in KnockoutJS? The answer is: there is none. You need to write something yourself.
The basic idea behind any solution will be the same: save a copy of the original data from before editing so you can revert to it upon canceling.
Here are two good ways to do that:
Here's some sample code for the latter:
var dummyItem = { id: 42, name: "John doe" };
function ItemViewModel(data) {
var self = this, currentDto = data;
self.id = ko.observable();
self.name = ko.observable();
self.isInEditMode = ko.observable(false);
self.reset = function() {
self.id(currentDto.id);
self.name(currentDto.name);
self.isInEditMode(false);
};
self.saveState = function() {
currentDto = {
id: self.id(),
name: self.name()
};
self.isInEditMode(false);
};
self.reset();
}
function RootViewModel() {
var self = this;
self.items = ko.observableArray([new ItemViewModel(dummyItem)]);
self.startEdit = function(item) { item.isInEditMode(true); };
self.save = function(item) { item.saveState(); };
self.cancel = function(item) { item.reset(); };
}
ko.applyBindings(new RootViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<ul data-bind="foreach: items">
<li>
<span data-bind="text: id"></span>
<span data-bind="text: name"></span>
<input data-bind="textInput: name, visible: isInEditMode">
<button data-bind="visible: !isInEditMode(), click: $root.startEdit">edit</button>
<button data-bind="visible: isInEditMode, click: $root.save">save</button>
<button data-bind="visible: isInEditMode, click: $root.cancel">cancel</button>
</li>
</ul>
You should probably try to implement one of these two options for your own context. If you run into specific problems, I suggest getting back to SO with specific questions.
Upvotes: 9