choojs / choo

:steam_locomotive::train: - sturdy 4kb frontend framework
https://choo.io/
MIT License
6.78k stars 595 forks source link

text field loosing state on `render` #579

Open perguth opened 7 years ago

perguth commented 7 years ago

Expected behavior

Input fields should retain their state (and possibly focus as well as cursor position) regardless of emitter.emit('render')

Actual behavior

Text input fields loose their state/value on rendering.

Steps to reproduce behavior

Minimally adjusted code from the README shows the described behaviour: http://requirebin.com/?gist=829488013f4333ed528825df65c6a406

simonwjackson commented 6 years ago

@perguth Did you ever find a solution to this? I'm running into the same issue.

perguth commented 6 years ago

Yes, thanks to the friendly folks :two_men_holding_hands: in #choo on freenode. I wrapped the input element in a Nanocomponent like so:

let Input = class Component extends Nanocomponent {
  constructor () {
    super()
    this.state = {}
  }
  createElement (state) {
    this.state = state
    return html`
      <input onkeypress=${state.onkeypress} onfocus=${state.onfocus} onblur=${state.onblur}
      class=form-control type=text placeholder='name or mac address' data-toggle=dropdown>
    `
  }
  update () {}
}
let input = new Input()

(source) and included it like so:

${input.render({onkeypress: search, onfocus: showSuggestions, onblur: hideSuggestions})}

(source).

Nonetheless this behaviour was considered a :beetle:bug.

bates64 commented 6 years ago

Is this a bug in nanomorph? I guess it just needs to not consider el.value a modified property.

jfr3000 commented 6 years ago

is there any update on this?

my workaround in the meantime is to attach an isSameNode handler to the input field as documented here: https://github.com/choojs/choo#caching-dom-elements

const inputField = input({type: "text"})
inputField.isSameNode = (target) => {
  return (target && target.nodeName && target.nodeName === 'INPUT')
}