Thank you for reporting an issue, suggesting an enhancement, or asking a question. We appreciate your feedback - to help the team understand your
needs please complete the below template to ensure we have the details to help. Thanks!
Please check out the documentation to see if your question is already addressed there. This will help us ensure our documentation is up to date.
[ ] Enhancement
[x] Bug
[ ] Question
1.13.0-beta.892b624
focus not disappear
focus disappear after enter one symbol
basic setState usage
import * as React from 'react';
import { IHelloWorldProps } from './IHelloWorldProps';
import { RichText } from "@pnp/spfx-controls-react/lib/RichText";
export default class HelloWorld extends React.Component<IHelloWorldProps, { value: string }> {
constructor(props: IHelloWorldProps) {
super(props);
this.state = {
value: ''
};
}
private onChange = (value: string) => {
this.setState({ value });
return value;
}
public render(): React.ReactElement<IHelloWorldProps> {
return (
<div><RichText value={this.state.value} onChange={(text) => this.onChange(text)} /></div>
);
}
}
Thanks for reporting the issue @kirillstarlight. Can you provide more information? I've tried to reproduce the issue and cannot reproduce it.
What browser was this on?
@hugoabernier
chrome 73.0.3683.86
create spfx webpart from template
yo @microsoft/sharepoint
add sp beta lib as dependency
add rich text as i use it (implement onChange with setState)
run project
gulp serve
add webpart on page and try to change text in rich text editor
As you are storing the value back to the state of your web part, it will re-render the HTML. That is why you lose focus. You can also store the value as a private variable in your component. That will not trigger a re-render.
@estruyf thanks a lot
this helped me
As always great work guys, love working with these libraries (react controls, property pane controls and the pnpjs)!
I'd like to ask a question regarding this same issue. I am using the control as part of a form and am therefore storing the value in the parent state and propagating it down via props. This results in the loss of focus after each character input, which is quite problematic for obvious reasons. Storing the value as a private variable doesn't really help in this case, because the value must be updated in the parent component, any help would be greatly appreciated :)
@Katli95 Do you have a "Save" or "Complete" button? What I'm doing is saving to a class object and when the rich text field changes, I pass the property name along with it and save it in the class object.
Then when the user clicks on "Save", I loop through all the keys in the class object to my state object and then raise it to the parent.
` private handleChangeRichText = tileName => (newValue: string): string => {
this._temp[tileName] = newValue;
return newValue;
}
`
And on save:
` private _save(): void {
this.setState({
isUpdating: true,
}, () => {
let thingClone= _.cloneDeep(this.state.thing);
for (let key in this._temp) {
thingClone[key] = this._temp[key];
}
this.props.requestUpdateThing(thingClone)
.then(() => {
this.setState({
isUpdating: false,
}, () => {
this._closeModal();
});
});
});
}
`
Its a hack but we don't lose focus and everything updates when needed.
@Katli95
try this
i just save input value in variable of class
then pass it upper(to save in props of webpart (it doesnt matter)
on init it will take this value from props and works locally with that and also save it upper. componentShouldUpdate there need to away rerender of this component
i test it few days ago and all works fine
export default class Content extends React.Component<ITabContentProps> {
private value: string = this.props.value;
public shouldComponentUpdate(nextProps: ITabContentProps) {
return (this.props.value === nextProps.value);
}
private onChange = (text: string): string => {
this.value = text;
this.props.onChange!(text);
return text;
}
public render() {
return (
<div className="tabs-content__ctn" ref={x => this.container = x}>
{
this.props.isEdit ?
<RichText
value={this.value}
onChange={(text) => this.onChange(text)}
className="rte--read"
/>
:
(this.value ?
<p className={`tabs-content ql-editor cke_editable rte--read`} dangerouslySetInnerHTML={{ __html: this.props.value }} /> :
<React.Fragment />
)
}
</div>);
}
}
Thanks for the answers guys,
@kirillstarlight Your method worked for me. I duplicated the value in the constructor and used that as the value for the control and updated the state of the parent with onChange. This however feels fairly dirty and I'd much rather prefer some form of .focus() accessor for the control or have it support statefull components :/
(I tried getting the quill editor via reference and focusing that but it didn't work)
i.e.
// RichTextReference being a reference to this control
RichTextReference.getEditor().focus()
//Resulted in persisting the focus border around the control but didn't facilitate input
Hi Kiryl,
Can you please share the solution
@Katli95
try this
i just save input value in variable of class
then pass it upper(to save in props of webpart (it doesnt matter)
on init it will take this value from props and works locally with that and also save it upper. componentShouldUpdate there need to away rerender of this component
i test it few days ago and all works fineexport default class Content extends React.Component<ITabContentProps> { private value: string = this.props.value; public shouldComponentUpdate(nextProps: ITabContentProps) { return (this.props.value === nextProps.value); } private onChange = (text: string): string => { this.value = text; this.props.onChange!(text); return text; } public render() { return ( <div className="tabs-content__ctn" ref={x => this.container = x}> { this.props.isEdit ? <RichText value={this.value} onChange={(text) => this.onChange(text)} className="rte--read" /> : (this.value ? <p className={`tabs-content ql-editor cke_editable rte--read`} dangerouslySetInnerHTML={{ __html: this.props.value }} /> : <React.Fragment /> ) } </div>); } }
Hi Kiryl, I am trying to implement your solution, though facing issues to save richbox content in webpart. Can you please share how you are receiving richbox content in upper webpart though props in oninit method
As you are storing the value back to the state of your web part, it will re-render the HTML. That is why you lose focus. You can also store the value as a private variable in your component. That will not trigger a re-render.
@estruyf Thanks a lot for this!
Most helpful comment
As you are storing the value back to the state of your web part, it will re-render the HTML. That is why you lose focus. You can also store the value as a private variable in your component. That will not trigger a re-render.