简体   繁体   中英

Put cursor inside input box onChange in React

I have a component of basic editable list items that operates as such:

在此处输入图片说明

My problem is that the cursor does not move into the input box onChange , making a hassle for the user to always click twice. I tried https://coderwall.com/p/0iz_zq/how-to-put-focus-at-the-end-of-an-input-with-react-js but it did not work. Component looks like:

import React from 'react';

import MyComponent from '../utils/MyComponent';


export default class BasicList extends MyComponent {

    constructor(props) {
        let custom_methods = ['renderItemOrEditField', 'toggleEditing', 'moveCaretAtEnd'];
        super(props, custom_methods);
        this.state = {editing: null};
    }

    moveCaretAtEnd(e) {
        var temp_value = e.target.value
        e.target.value = ''
        e.target.value = temp_value
    }

    renderItemOrEditField(item) {
        console.log(item);
        if (this.state.editing === item.id) {
            return (
                <input
                  onKeyDown={ this.handleEditField }
                  type="text"
                  className="form-control"
                  ref={ `${item.type}_name_${ item.id }` }
                  name="title"
                  autofocus
                  onFocus={this.moveCaretAtEnd}
                  defaultValue={ item.name }
                />
            );
        } else {
            return (
                <li
                  onClick={this.toggleEditing.bind(null, item.id)}
                  key={item.id}
                  className="list-group-item">
                    {item.name}
                </li>
            );
        }
    }

    toggleEditing(item_id) {
        this.setState({editing: item_id});
    }


    render() {
        let li_elements = null;
        let items = this.props.items;

        if (items.length > 0) {
          li_elements = items.map((item) => {
              return (
                  this.renderItemOrEditField(item)
                //   {/* }<li key={item.id}>
                //       {item.name} -
                //       <button onClick={() => {this.props.deleteCallback(this.props.item_type, item.id, item.name)} }>
                //         Delete
                //       </button>
                //   </li> */}

              );
          });
        }

        return (
          <div>
            <h4>{this.props.title}:</h4>
                <ul className="list-group">
                    {li_elements}
                </ul>
          </div>
        );
    }
}

The items I'm working with now only have a name and ID (type denotes a 'role' or 'task')

How can I make the cursor start at the end of the input box text on change?

Autofocus triggers when a component is mounted. Not sure that's happening by your conditional render. You could moving your conditional logic to a separate container and that should trigger a mount each time it's shown.

I ended up setting focus as in the callback that causes the input box to show:

toggleEditing(item_id) {
        // this syntax runs the function after this.setState is finished
        this.setState({editing: item_id}, function() {
            this.textInput.focus();
        });
    }

Then the original solution given worked:

   // https://coderwall.com/p/0iz_zq/how-to-put-focus-at-the-end-of-an-input-with-react-js
    moveCaretAtEnd(e) {
        var temp_value = e.target.value
        e.target.value = ''
        e.target.value = temp_value
    }

and

 <input
      onKeyDown={ this.handleEditField }
      type="text"
      className="form-control"
      ref={(input) => { this.textInput = input; }}
      name="title"
      autofocus
      onFocus={this.moveCaretAtEnd}
      defaultValue={ item.name }
      onChange={(event) => this.editItem(event)}
      style={ {maxWidth: 500} }
    />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM