JavaScript data structure for highlighting words in a string

I have a line

const string = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent tristique elit in volutpat iaculis. Proin a tincidunt turpis, et condimentum libero. Duis convallis nulla eu mattis porta. Nulla facilisi. Proin nec viverra orci. Nunc aliquam enim orci, ut dictum ipsum auctor ut. Quisque consectetur vestibulum tortor, mollis hendrerit velit hendrerit vel. In hac habitasse platea dictumst. Morbi volutpat lectus purus, eu sagittis odio viverra in. Phasellus vel volutpat felis. Proin a metus sit amet ipsum congue faucibus nec faucibus nisl. Aenean eu nisl ac velit dapibus vulputate non efficitur urna. Phasellus laoreet suscipit dictum. Curabitur sit amet justo at nisi dictum dapibus." 

I want to be able to select a sequence of words and show a tooltip when hovering over words.

What data structure will it look for?

I guess it should be something like

 id, wordIndexStart, wordIndexEnd, note ======================================= 1, 0, 5, Some note 

to highlight the first 6 words, giving me something like

Lorem ipsum dolor sit amet, consectetur adipiscing elit. The faithful tristic elite in volutpat iaculis (...)

but how do I return this line with this selected text in React or something similar?

I usually print my text with

 <p>{string}</p> 

but I think it should be something like

 <p>{string.split(" ").map(word => <span>{word}).join(" ")</p> 

but how do I create a <span> around, for example, the first 6 words?

+5
source share
3 answers

How about this:

 const rules = { start: 0, end: 5, tooltip: "Some note" }; const Highlight = ({ words }) => { const portion = words.split(" ").slice(rules.start, rules.end).join(" "); const rest = words.split(" ").slice(rules.end).join(" "); return ( <span> <span className="highlight">{portion}</span> <span className="standard">{rest}</span> </span> ); }; const App = () => { const sentence = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent tristique elit in volutpat iaculis.'; return ( <div> <Highlight words={sentence} /> </div> )} ; ReactDOM.render(<App />, document.getElementById("root")); 
 .highlight { font-weight: bold; color: red; } .standard { color: grey; } 
  <div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
+1
source

I would suggest including the phrase that you intend to highlight. I'm not sure why you want an identifier inside your data structure, it may make sense in the database, but in the view, of course, they do not have to be included.

 { phrase: string, note: string } 

This is all you need to parse the input sentence for the phrase, and if so, replace it with an element that will show a note when you hover.

As for the implementation, finding a phrase is as easy as taking an index, sentence.indexOf(phrase) , and then using this index sentence.substr(0,index) + note + sentence.substr(index+phrase.length) to convert suggestions with your created html supporting note. Since most of this implementation will depend on how the note is created, maintained or connected, I will leave this part open for you to decide.

0
source

When using React, you will want to move the selection logic outside of the render function

stateShape:

 { content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent tristique elit in volutpat iaculis. Proin a tincidunt turpis, et condimentum libero. Duis convallis nulla eu mattis porta. Nulla facilisi. Proin nec viverra orci. Nunc aliquam enim orci, ut dictum ipsum auctor ut. Quisque consectetur vestibulum tortor, mollis hendrerit velit hendrerit vel. In hac habitasse platea dictumst. Morbi volutpat lectus purus, eu sagittis odio viverra in. Phasellus vel volutpat felis. Proin a metus sit amet ipsum congue faucibus nec faucibus nisl. Aenean eu nisl ac velit dapibus vulputate non efficitur urna. Phasellus laoreet suscipit dictum. Curabitur sit amet justo at nisi dictum dapibus.", highlights: [{ id: 1, wordIndexStart: 0, wordIndexEnd: 5, note: "Some note" }, { id: 2, wordIndexStart: 6, wordIndexEnd: 10, note: "Some other note" }] } 

connected component of mapStateToProps:

 function mapStateToProps(state, ownProps) { const { content, highlights } = state; // Move this logic to ReSelect? https://github.com/reactjs/reselect const words = content.split(" "); const wordsWithHighlights = words.map((word, index) => { const highlightStart = highlights.find((highlightItem) => { return highlightItem.wordIndexStart == index; }); if (highlightStart) { return `<span title=${highlightStart.note}>${word}`; } const highlightEnd = highlights.find((highlightItem) => { return highlightItem.wordIndexEnd == index; }); if (highlightEnd) { return `${word}</span>`; } return word; }); return { content: wordsWithHighlights.join(" ") }; } 

and then the render function:

 render() { const { content } = this.props; return ( <p dangerouslySetInnerHTML={{ __html: content }} /> ) } 

As @jordan pointed out, you cannot add HTML as a string in React, and according to this answer, you can use the dangerouslySetInnerHTML attribute as above

-2
source

Source: https://habr.com/ru/post/1275474/


All Articles