2017-11-13 20 views
5

모듈 react-simple-contenteditable을 사용하여 빈 워크 시트의 채우기 편집을 활성화합니다. 입력 요소 대신 편집 가능한 요소를 사용해야하는 이유는 문제의 텍스트를 줄 바꿈하기 위해서입니다. 예를 들어, 문제가있는 공백이 하나있는 경우, 공백, 공백 및 이후의 파트의 세 부분으로 텍스트를 나눕니다. 바깥 두 개를 별도의 div (또는 입력 필드)으로 나타내려면 단락처럼 줄 바꿈하지 않습니다. 대신, 공백 및 자유 텍스트의 입력 필드가 양면에 포함되어있는 하나의 contenteditable div이 있어야합니다.접촉 식 커서가 처음으로 점프

텍스트가 원하는대로 배치되어 있지만 contenteditable 필드에 텍스트를 입력하면 커서가 처음으로 이동합니다. 나는 왜 module's github site에서 예제를 시도했기 때문에 왜 완벽하게 작동하는지 이해하지 못한다. 물론 구현은 좀 더 복잡하지만 실제로는 똑같이 작동한다.

: 단지 분명히 일을하기 위해,

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 }); 
    } 

그리고 여기가 참조하는 상태 :

여기
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 기능입니다 : 여기

<ContentEditable />를 사용하여 내 렌더링 기능입니다
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를 사용했습니다. contenteditable div over facebook 자체에 대한 추상화입니다.

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

A를 데리러 이상 비트하지만 당신은 당신의 응답을 훨씬 더

+0

감사를 할 수있을 것입니다! DraftJS를 다시 살펴 보겠습니다. 매우 복잡해 보입니다. 내가하고있는 일과 같은 단순한 필드 용으로 구현 될 수 있습니까? 아니면 광고용처럼 풍부한 텍스트 편집 용입니까? –

+0

둘 다 할 수 있습니다. 간단하지는 않지만 커서 상태를 직접 관리하는 것보다 간단 할 것입니다. – klugjo

+0

지금이 문제로 돌아 가기 ... 나는 DraftJS의 문서를 스캔하여 다른 질문에 대한 답을 찾을 수 없으므로 어쩌면 당신이 알고있을 것이라고 생각했습니다. 내부 내용 HTML 요소를 만들 수 있습니까? 내용 편집 가능한 텍스트 외에도 상자가있는 텍스트가 필요합니다. –