2017-11-13 6 views
5

空白のワークシートの塗りの編集を有効にするには、モジュールreact-simple-contenteditableを使用しています。入力要素の代わりにコンテンツ編集可能な要素を使用する必要があるのは、問題のテキストを折り返したいからです。たとえば、問題に空白が1つある場合、空白の前の部分、空白、および後の部分の3つのセクションにテキストを分割します。外側の2つを別々のdiv(または入力フィールド)として表現すると、テキストは段落のように折り返されません。代わりに、空白の入力フィールドと両側のフリーテキストを含む1つのコンテンツ編集可能なdivが必要です。内容が一致するカーソルが先頭にジャンプ

テキストは私が望むように折り返していますが、contenteditableフィールドにテキストを入力すると、カーソルが先頭にジャンプします。なぜ私はmodule's github siteの例題を試したので、私の実装はもう少し複雑ですが、それは本質的に同じです。ここで

<ContentEditable />を使用して、私のレンダリング機能である:ここでは

render() { 
    const textPieces = 
     <div className='new-form-text-pieces'> 
     { 
      this.props.problem.textPieces.map((textPiece, idx) => { 
      if (textPiece.blank) { 
       return (
        <div data-blank={true} className='blank' key={ textPiece.id } style={{display: 'inline'}}> 
        <input 
         placeholder="Answer blank" 
         className='new-form-answer-input' 
         value={ this.props.problem.textPieces[idx].text } 
         onChange={ (event) => this.props.handleTextPiecesInput(this.props.problemIdx, idx, event.target.value) } 
        /> 
        <button className='modify-blank remove-blank' onClick={ (event) => this.props.removeBlank(this.props.problemIdx, idx) }>-</button> 

        </div> 
      ); 
      } else { 
       let text = this.props.problem.textPieces[idx].text; 
       const placeholder = idx === 0 ? 'Problem text' : '...continue text'; 
       // text = text === '' ? placeholder : text; 
       if (text === '') { 
       text = <span style={{color:'gray'}}>{placeholder}</span>; 
       } else { 

       } 
       return (
       this.props.isTextSplit ? 
        <TextPiece 
        key={ textPiece.id } 
        problemIdx={this.props.problemIdx} 
        textPieceIdx={idx} 
        dropBlank={this.props.dropBlank} 
        moveBlank={this.props.moveBlank} 
        > 
        <div style={{display: 'inline-block', }}>{text}</div> 
        </TextPiece> 
       : text 

      ); 
      } 
      }) 
     } 
     </div>; 



    return (
     this.props.isTextSplit ? textPieces : 
     <ContentEditable 
      html={ReactDOMServer.renderToStaticMarkup(textPieces)} 
      className="my-class" 
      tagName="div" 
      onChange={ (event, value) => this.props.handleProblemChange(event, this.props.problemIdx, value) } 
      contentEditable='plaintext-only' 
     /> 
    ); 

    } 

onChange機能である:

handleProblemChange(event, problemIdx) { 
    const problems = cloneDeep(this.state.problems); 
    event.target.children[0].childNodes.forEach((textPieceNode, idx) => { 
     if (textPieceNode.constructor === Text) { 
     problems[problemIdx].textPieces[idx].text = textPieceNode.wholeText; 
     } else { 
     problems[problemIdx].textPieces[idx].text = textPieceNode.childNodes[0].value; 
     } 
    }); 
    this.setState({ problems }); 
    } 

そして、ここではそれだけの事を明確にするために、を指し状態であります

this.state = { 
    problems: [ 
    { 
     id: shortid.generate(), 
     textPieces: [ 
     { 
      text : "Three days was simply not a(n)", 
      blank : false, 
      id: shortid.generate(), 
     }, 
     { 
      text : "acceptable", 
      blank : true, 
      id: shortid.generate(), 
     }, 
     { 
      text : "amount of time to complete such a lot of work.", 
      blank : false, 
      id: shortid.generate(), 
     } 
     ] 
    } 

ありがとうございました

答えて

1

簡単に言えば、これを行う簡単な方法はありません。私はこれを自分自身で試してみた。基本的には、カーソルの位置を保存し、更新後に自分自身の位置を変更する必要があります。このすべてがwindow.getSelection()

https://developer.mozilla.org/en-US/docs/Web/API/Window/getSelection

で達成することができる。しかし、それはあなたのコンテンツがどれだけ変化したかに応じて、本当にトリッキー得ることができます。

代わりにdraftJSを使用しました。それは、facebookでcontenteditable div以上の抽象化です。少し長く

https://draftjs.org/docs/overview.html#content

ピックアップしていますがお返事のため

+0

多くの感謝を行うことができるようになります! DraftJSをもう一度見てみましょう。かなり複雑に見えました。私がやっていることのような単純なフィールドのために実装することはできますか?それは宣伝されているようなリッチテキストの編集だけですか? –

+0

それは両方を行うことができます。シンプルではありませんが、自分でカーソルの状態を管理するより簡単です。 – klugjo

+0

これに戻ります...私はDraftJSのドキュメントをスキャンしましたが、別の質問に対する回答が見つからないため、知っているかもしれないと思いました。つまり、内部コンテンツhtml要素を作成できますか?コンテンツ編集可能なテキストに加えて、私はそれの周りにボックスでテキストが必要です。 –

関連する問題