Sunday, May 19, 2024
 Popular · Latest · Hot · Upcoming
94
rated 0 times [  96] [ 2]  / answers: 1 / hits: 15589  / 6 Years ago, mon, june 25, 2018, 12:00:00

While creating custom autocomplete component I stuck with this problem: I got a string and substring(first part of the string, the one that user enters in autocompete field), and I need to show that part in bold in results list.



But I cannot use str.replace like



    var re = new RegExp(find, 'g');
return str.replace(re, '<b>'+find+'</b>');


because it will return string and I need JSX.



So basically the problem is - I have JSX and I need to make some part of it in bold. I need a function that takes JSX and like inject <b> tag in it in special places



This is what I got so far



    boldJSX(str, find){
if(!find) return str;
return <span><b>{find}</b>{str.slice(find.length)}</span>
}

More From » reactjs

 Answers
39

First, you need to find and extract the appropriate substring (the string you are looking for) if exits in given list and make a custom string by extracting that substring as given below.



 //autoValue - value you are looking for
//main - item value
const val =
main.slice(0, main.indexOf(autoValue)) +
<b> +
autoValue +
</b> +
main.slice(
main.indexOf(autoValue) + autoValue.length,
main.length
);


Now, You have to use dangerouslySetInnerHTML for a span or any custom HTML component you are using for rendering each item in you auto-complete component.
Here is full example.



const items = [
React,
Angular,
Vue,
Node,
Express,
PHP,
Laravel,
Material,
CSS,
HTML
];

function ListItem(props) {
if (props.value.indexOf(props.autoValue) > -1 && props.autoValue.length > 0) {
const main = props.value;
const val =
main.slice(0, main.indexOf(props.autoValue)) +
<b> +
props.autoValue +
</b> +
main.slice(
main.indexOf(props.autoValue) + props.autoValue.length,
main.length
);

return (
<div>
<span dangerouslySetInnerHTML={{ __html: val }} />
<hr />
</div>
);
} else {
return (
<span>
{props.value}
<hr />
</span>
);
}
}

function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map(number => (
<ListItem
key={number.toString()}
value={number}
autoValue={props.autoValue}
/>
));
return <div>{listItems}</div>;
}

class App extends Component {
constructor(props) {
super(props);
this.state = {
inputValue:
};

this.update = this.update.bind(this);
}

update(e) {
e.preventDefault();
this.setState({ inputValue: e.target.value });
}

render() {
return (
<div>
<input
type=text
onChange={this.update}
name=inputValue
value={this.state.inputValue}
/>
<NumberList numbers={items} autoValue={this.state.inputValue} />
<span> {this.state.inputValue} </span>
</div>
);
}
}

export default App;


Working Example. https://codesandbox.io/s/n9n65wqj5j


[#54122] Thursday, June 21, 2018, 6 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
josuea

Total Points: 609
Total Questions: 121
Total Answers: 104

Location: South Georgia
Member since Fri, Nov 13, 2020
4 Years ago
;