Skip to content
This repository has been archived by the owner on Sep 21, 2022. It is now read-only.

API for managing selection state #4

Open
sophiebits opened this issue May 7, 2014 · 4 comments
Open

API for managing selection state #4

sophiebits opened this issue May 7, 2014 · 4 comments

Comments

@sophiebits
Copy link
Member

Managing the selection with something like a filtered controlled <input> is a huge pain right now -- if you do the simple thing of filtering the value in the onChange handler

handleChange: function(e) {
  this.setState({text: e.target.value.replace(/^[0-9]/g, '')});
},

then your cursor jumps to the end of the text box when typing non-digit characters anywhere into the field.

For comparison, Elm treats the selection state as part of an input's value.

@montoya-azul
Copy link

Did you solve this?

@GetContented
Copy link

@spicyj I was also wondering if you'd had any further movement on this. I'm actually just getting it in my normal controlled inpet when typing at a speed over 40 wpm (I happend to have a lot of other stuff going on at the same time in my app).

@sophiebits
Copy link
Member Author

None currently. If you have good ideas we'd love to hear them.

@syranide
Copy link

I did a lot of experiments on this a year or so ago. It's not terribly complex but the API becomes rather cumbersome or inflexible with if done naively:

A. Always only mutate text left/right/inside of selection, works as-is.
B. Selection as a property, {text: '', selection: [0, 1]}.
C. Text left/right/inside of selection as a property, {left: '', right: '', selected: ''}.

Problem is that only A is self-contained, but it does not behave (strictly) as intended if the value of the input is replaced entirely and is rather inflexible. The other 2 are actually incomplete. So what's really needed is probably a (somewhat) opaque type, provide a bunch of helpers for mutating it.

Something like this perhaps:

var FooBar = React.createClass({
  getInitialState() {
    return {
      inputValue: createSuperInputValue({
        value: '',
        onChange: function(value) {}
      })
    }
  },
  mutateInput() {
    this.setState({
      inputValue: fooBarMutateSuperInputValue(this.state.inputValue, ...)
    });
  },
  render() {
    return (
      <SuperInput
        value={this.props.inputValue}
        onChange={newValue => this.setState({inputValue: newValue})}
      />
    );
  }
});

However, regardless of what the solution is. Know that in most browsers you end up discarding the undo history, in Chrome you actually end up corrupting it so undoing ruins what you wrote. So my current recommendation is to just stick with text-transform and preventDefault in onKeyPress.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants