max-mapper/yo-yo

Cant clear an input value

Opened this issue · 10 comments

Demo: https://codepen.io/anon/pen/jyapVW?editors=1010

If the user enters a value into an input, and then you use yo to set the value to '', the change doesn't occur. How can we clear the value via yo?

Looking at the tests this is expected behavior for a reason- but can probably be handled.

test('input values get copied', function (t) {
  t.plan(1)
  var el = yo`<input type="text" />`
  el.value = 'hi'
  var newEl = yo`<input type="text" />`
  yo.update(el, newEl)
  t.equal(el.value, 'hi')
})

But I suspect the reason is: if in the yo-yo dom string, there is nothing bound to input's value and nothing bound to input and oninput, then it should just behave normally. Basically, sometimes there is just inputs, and they should still behave like text inputs when event handlers aren't explicitly telling them what their value is on each input.

I think the best route would be to check then if that element has something bound to onchange or oninput event. If there is a handler bound, then the value must be explicitly updated. Otherwise the input can copy over the value as normal.

I am also running into this issue, but do not have handlers on the input. It seems like it would make more sense to simply see if the value attribute was actually present and update it if so, e.g:

// (from main.js)
if ((f.nodeName === 'INPUT' && f.type !== 'file') || f.nodeName === 'SELECT') {
  if (t.getAttribute('value') === null) {
    t.value = f.value;
  }
  else {
    f.value = t.value;
  }
} else…

Which is somewhere in between what this originally did and the change that led to current behavior: 893b779

FWIW, the value property is always a string, but the attribute will be null if not present.

I like the above idea. Though since morphdom is being used under the hood- it doesn't appear to be a requirement that the compared node even have the getAttribute function, just hasAttributeNS as the closest equivalent (which, TIL is a thing that exists)... so...

// (from main.js)
if ((f.nodeName === 'INPUT' && f.type !== 'file') || f.nodeName === 'SELECT') {
  if (!t.hasAttributeNS(null, 'value')) {
    t.value = f.value;
  }
  else {
    f.value = t.value;
  }
} else…

It also specifies the vnode should have value but in this case, if you do <input id='foo' type='text' />, the document.getElementById('foo').value is actually just any empty string ""

So I suppose hasAttributeNS(null, 'value') is the best way to go?

Oh, yeah, totally forgot nodes created outside the browser won’t be full DOM nodes. If they support hasAttributeNS, that would be more correct than what I was proposing anyhow :)

Hey, is there any update with this? We're finding a few areas of our app where we're wanting to clear inputs (search inputs etc). Happy to lend a hand if there's anything blocking.

tgfjt commented

fixed? :)

the codepen linked in the original post for this issue (https://codepen.io/anon/pen/jyapVW?editors=1010) seems to run as expected with the latest version of yo-yo, i.e. user input is cleared when the code sets the value attribute of the <input> tag to an empty string.

should this issue be closed ?

The core issue I was encountering certainly seems to be fixed. I can’t say whether it practically does so because the project I encountered it in was using Choo, which switched to Bel before the updated release of Yo-yo.