Skip to content

Commit

Permalink
fix textInput so that it won't update the model if the value is chang…
Browse files Browse the repository at this point in the history
…ed only by the browser. fixes #2281
  • Loading branch information
mbest committed Oct 3, 2017
1 parent 3949c3e commit 716eb28
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 1 deletion.
26 changes: 25 additions & 1 deletion spec/defaultBindings/textInputBehaviors.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ describe('Binding: TextInput', function() {
expect(myobservable()).toEqual("some user-entered value");
});

it('Should write only changed values to observable', function () {
it('Should write only changed values to model', function () {
var model = { writtenValue: '' };

testNode.innerHTML = "<input data-bind='textInput: writtenValue' />";
Expand All @@ -236,6 +236,30 @@ describe('Binding: TextInput', function() {
expect(model.writtenValue).toBeUndefined();
});

it('Should not write to model other than for user input', function () {
// In html5, the value returned by element.value is normalized and CR characters are transformed,
// See http://www.w3.org/TR/html5/forms.html#the-textarea-element, https://github.com/knockout/knockout/issues/2281
var originalValue = '12345\r\n67890',
model = { writtenValue: ko.observable(originalValue) };

testNode.innerHTML = "<textarea data-bind='textInput: writtenValue'></textarea>";
ko.applyBindings(model, testNode);

// No user change; verify that model isn't changed (note that the view's value may be different)
ko.utils.triggerEvent(testNode.childNodes[0], "blur");
expect(model.writtenValue()).toEqual(originalValue);

// A change by the user is written to the model
testNode.childNodes[0].value = "1234";
ko.utils.triggerEvent(testNode.childNodes[0], "change");
expect(model.writtenValue()).toEqual("1234");

// A change from the model; the model isn't updated even if the view's value is different
model.writtenValue(originalValue);
ko.utils.triggerEvent(testNode.childNodes[0], "blur");
expect(model.writtenValue()).toEqual(originalValue);
});

if (typeof DEBUG != 'undefined' && DEBUG) {
// The textInput binds to different events depending on the browser.
// But the DEBUG version allows us to force it to bind to specific events for testing purposes.
Expand Down
1 change: 1 addition & 0 deletions src/binding/defaultBindings/textInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ ko.bindingHandlers['textInput'] = {
if (element.value !== modelValue) {
previousElementValue = modelValue; // Make sure we ignore events (propertychange) that result from updating the value
element.value = modelValue;
previousElementValue = element.value; // In case the browser changes the value (see #2281)
}
};

Expand Down

0 comments on commit 716eb28

Please sign in to comment.