From e3cfccb20602efb3265c413dc3882e35f54b108c Mon Sep 17 00:00:00 2001 From: Avital Oliver Date: Thu, 5 Jun 2014 17:45:50 -0700 Subject: [PATCH] Stop not updating form controls if they're focused On Blaze, we copied functionality we had on Spark: Don't update form controls (INPUT, TEXTAREA) if they are focused and their underlying value reactively updates. This was never meant to be the eventual solution -- we'd eventually have a way to define strategies for two-way data binding. Maybe you'd be able to define a callback that notifies the app when a change happens to a field that hasn't been saved yet. Moreover, not only is the feature incomplete, but with Blaze it works much more poorly than in Spark. Due to fine-grained updates, users his this more frequently and don't seem to like the behavior (in Spark you would only hit this behavior if you set up your preserve rules exactly right, which many users did not do). So, we're just ripping out this functionality. Now if a field gets edited by some other user while you're focused it will just lose its value. Focus will remain. Fixes #1965 --- packages/spacebars-tests/template_tests.js | 15 +++------ packages/ui/attrs.js | 39 ++++------------------ 2 files changed, 10 insertions(+), 44 deletions(-) diff --git a/packages/spacebars-tests/template_tests.js b/packages/spacebars-tests/template_tests.js index b0782a697e..88a10f0dca 100644 --- a/packages/spacebars-tests/template_tests.js +++ b/packages/spacebars-tests/template_tests.js @@ -1344,22 +1344,15 @@ _.each(['textarea', 'text', 'password', 'submit', 'button', test.equal(DomUtils.getElementValue(input), "This is a fridge"); if (canFocus) { - // ...unless focused + // ...if focused, it still updates but focus isn't lost. focusElement(input); + DomUtils.setElementValue(input, "something else"); R.set({x:"frog"}); Deps.flush(); - test.equal(DomUtils.getElementValue(input), "This is a fridge"); - - // blurring and re-setting works - blurElement(input); - Deps.flush(); - test.equal(DomUtils.getElementValue(input), "This is a fridge"); + test.equal(DomUtils.getElementValue(input), "This is a frog"); + test.equal(document.activeElement, input); } - R.set({x:"new frog"}); - Deps.flush(); - - test.equal(DomUtils.getElementValue(input), "This is a new frog"); // Setting a value (similar to user typing) should prevent value from being // reverted if the div is re-rendered but the rendered value (ie, R) does diff --git a/packages/ui/attrs.js b/packages/ui/attrs.js index c87392b2b2..a9427c8654 100644 --- a/packages/ui/attrs.js +++ b/packages/ui/attrs.js @@ -98,46 +98,19 @@ var SVGClassHandler = BaseClassHandler.extend({ var BooleanHandler = AttributeHandler.extend({ update: function (element, oldValue, value) { - var focused = this.focused(element); - - if (!focused) { - var name = this.name; - if (value == null) { - if (oldValue != null) - element[name] = false; - } else { - element[name] = true; - } - } - }, - // is the element part of a control which is focused? - focused: function (element) { - if (element.tagName === 'INPUT') { - return element === document.activeElement; - - } else if (element.tagName === 'OPTION') { - // find the containing SELECT element, on which focus - // is actually set - var selectEl = element; - while (selectEl && selectEl.tagName !== 'SELECT') - selectEl = selectEl.parentNode; - - if (selectEl) - return selectEl === document.activeElement; - else - return false; + var name = this.name; + if (value == null) { + if (oldValue != null) + element[name] = false; } else { - throw new Error("Expected INPUT or OPTION element"); + element[name] = true; } } }); var ValueHandler = AttributeHandler.extend({ update: function (element, oldValue, value) { - var focused = (element === document.activeElement); - - if (!focused) - element.value = value; + element.value = value; } });