I'm using mapping plugin. I have an on 'blur' event whenever someone takes away focus from a text box. I would like to know if the old value is different from new value. This works correct for "enter" key. For some reason whenever I change the value and press enter I get this console output FIRST time; 'oldValue | newValue'. However this is not the case when 'blur' fires. I get 'newValue | newValue'
How come?. How can i get the new and old values on blur?
HTML:
<input class="percent-text" data-bind="text: Percent, value: Percent, event: { keypress: $root.percentUpdate, blur: $root.percentUpdate }" type="number" min="1" max="100" oninput="maxlength(this)" maxlength="3" />
Knockout:
self.percentUpdate = function (data, event) {
if (event.keyCode === 13 || event.type == 'blur') {
var $target = $(event.currentTarget);
console.log(data.Percent() + " | " + event.target.value);
}
return true;
};
You could do it with your approach (I had a succesful testcase), but as @AnotherDev mentioned it's simpler to use the built-in tools. Inside the subscribe
function you have access to the value before or after it is changed, and act upon it accordingly. If you want to still be able to retrieve previous values afterwards, you could easily do this with caching the preceding value, or even all preceding values (in an array). Note that the only reason cachedPercent(s)
are observable in the fiddle is to update the viewModel JSON; in a real app I would use plain array/ number (and ev. in private variable).
Test it in the fiddle below; wth this approach the ENTER
key function only needs a manual call to valueHasMutated
to notify the subscribe function.
function App(percent) {
var self = this;
this.cachedPercent = ko.observable(percent || 0);
this.cachedPercents = ko.observableArray([percent || 0]);
this.PercentRaw = ko.observable(percent || 0);
// Percent stores an integer, and is ratelimited to make sure
// that the value isn't stored 1000x every time the user increments
this.Percent = ko.computed(function() {
return parseInt(self.PercentRaw());
}).extend({rateLimit: 500});
this.storePercents = this.Percent.subscribe(function(oldVal) {
// delete this if clause if you want to manually check somewhere else
// because this tells JS not to store any value when similar to the previous one
if (self.cachedPercent() !== oldVal) {
self.cachedPercent(self.Percent());
self.cachedPercents.splice(0, 0, self.Percent());
}
}, null, 'beforeChange');
}
ko.applyBindings(new App(50));
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input data-bind="value: PercentRaw,
event: {keydown: function(d, e) { if (e.keyCode === 13) PercentRaw.valueHasMutated(); } " type="number" min="1" max="100" maxlength="3" class="percent-text" />
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>