如何在ReactJs的Textarea中设置光标位置?

时间:2018-12-14 15:40:49

标签: javascript reactjs

是否可以通过编程方式在文本区域内设置光标位置?

我的用例是标记用户。

当用户输入@tar时,我正在显示建议,用户将单击其中之一(例如@tarik),但是焦点将丢失,这是预期的。我需要重新关注我知道如何计算的特定职位。

我正在使用react-textarea-autosize中的Textarea

我在构造函数中定义了我的引用:

 this.textareaInput = React.createRef();

我正在将组件分配给参考:

 <Textarea
                ref={this.textareaInput}
                rows={1}
                value={comment}
                onChange={this.handleInputChanged}
                tabIndex={tabIndex || 0}
              />

在这一行中,我应该能够使用光标位置进行操作,但是我不能。

this.textareaInput.current._ref.focus();    
this.textareaInput.current._ref.selectionStart = 1;

 this.textareaInput.current._ref.focus(); 
 this.textareaInput.current._ref.selectionEnd = 3;

这些示例都不起作用。

注意:硬编码值仅用于测试代码。

我也尝试使用setSelectionRange方法,但没有成功。

6 个答案:

答案 0 :(得分:1)

我发现解决方案将selectionStartselectionEnd设置为相同的值。

答案 1 :(得分:1)

onChangeHandler = event =>{
  if (typeof(this.input)==='object'&&this.input!==null) {
  const selectionStart = this.input.selectionStart
  if (typeof(selectionStart)==='number') {
    this.setState({
      value:event.target.value,
      selectionStart:selectionStart,
    },()=>console.log("cursor Point is in"+this.state.selectionStart))
    return
  }
  }
  }    
  onClickHandler = () =>{
    if (typeof(this.input)==='object'&&this.input!==null) {
      const selectionStart = this.input.selectionStart
      this.setState({
        selectionStart: selectionStart,
      })
    }
  }

    <textarea
      ref={el=>this.input=el}
      value={this.state.value}
      onChange={(event)=>this.onChangeHandler(event)}
      onClick={()=>this.onClickHandler() }
    />

答案 2 :(得分:0)

我认为问题在于自定义<Textarea>块没有.focus()方法。

您可以尝试以下代码:

import TextareaAutosize from 'react-textarea-autosize'

class MyComponent extends React.Component {
    componentDidMount() {
        this.inputRef.focus()
    }

    inputRef = ref => (this.inputRef = ref)

    render() {
        return <TextareaAutosize inputRef={this.inputRef} />
    }
}

发现于fst-package manual

答案 3 :(得分:0)

尝试一下:

HTML:

import csv
import pandas as pd

# the file names
f1 = "csv1.csv"
f2 = "csv2.csv"
out_f = "csv3.csv"

# read the files
df1 = pd.read_csv(f1)
df2 = pd.read_csv(f2)

# get the keys
keys1 = list(df1)
keys2 = list(df2)

# merge both files
for idx, row in df2.iterrows():
    data = df1[df1['id'] == row['id']]

    # if row with such id does not exist, add the whole row
    if data.empty:
        next_idx = len(df1)
        for key in keys2:
            df1.at[next_idx, key] = df2.at[idx, key]

    # if row with such id exists, add only the missing keys with their values
    else:
        i = int(data.index[0])
        for key in keys2:
            if key not in keys1:
                df1.at[i, key] = df2.at[idx, key]

# save the merged files
df1.to_csv(out_f, index=False, encoding='utf-8', quotechar="", quoting=csv.QUOTE_NONE)

React-jsx:

<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

答案 4 :(得分:0)

相同的问题,可以通过以下方式解决:

  // in the constructor
    this.focusCommentsInput = this.focusCommentsInput.bind(this);
    this.textInput = React.createRef();

  // the function to call
    focusCommentsInput(){
        this.textInput.current.focus();
    }

  // the Textarea inputRef instead of ref
    <Textarea minRows={1} maxRows={10} className="input-textarea" placeholder={"Comments"} inputRef={this.textInput} />

  // the action onClick
  <div className="comments" onClick={ this.focusCommentsInput }>
  </div> 

答案 5 :(得分:0)

它对我来说是这样的: (使用钩子)

function ChatInput(props) {
    const { TextArea } = Input;
    const [value, setValue] = useState('');

    const [caret, setCaret] = useState({
        start: 0,
        end: 0
    });

    const changeHandler = (e) => { setValue(e.target.value); }

    // updates the cursor position onselect
    const handleSelect = (e) => {
        setCaret({ start: e.target.selectionStart, end: e.target.selectionEnd });
    }

    //calling to this function you can insert text in the cursor position
    const insertText = (text) => {
        setValue(
            value.substring(0, caret.start)
            + text +
            value.substring(caret.end, value.length)
        )
    }

    return (
        <div className="input">
            {/* this is the target textarea which is a controlled component */}
            <TextArea
                placeholder='Enter message'
                value={value}
                onChange={changeHandler}
                onSelect={(e) => handleSelect(e)}
            />
        </div>
    );
}