Asking a Question
I'm just wondering how to reset a survey once it's done. I'm using the react version (1.1.12). I have a survey that I want to use multiple times on a single page. I just need to know how to reset the form.
When the form is completed, it shows the completion html (or nothing, if I specify showCompletedPage={false}).
My desired behavior is that once the user completes a survey, the survey resets to its original blank state and the user can fill it out again.
P.S. Thanks for building survey.js, it's really nice. I especially like the survey creator website. All around well done!
survey.clear();
survey.render();
Was discussed here - https://github.com/surveyjs/survey-library/issues/816
Does that survey variable come from a React ref?
When I use a react ref, the render() function does work (The survey is coming back, yay!), but clear() is having no effect (The values are all still present in the survey fields).
Here is my code:
import React from 'react'
import { Survey as SurveyReact } from 'survey-react'
import Container from 'react-bootstrap/Container'
type TProps<TSurveyResult> = {
json: Object
onComplete: (json: TSurveyResult) => void
}
export default class Survey<TSurveyResult> extends React.Component<TProps<TSurveyResult>, {}> {
private survey = React.createRef<SurveyReact>()
private onComplete = (resp: { data: TSurveyResult }) => {
const surveyJson = resp.data
// Property 'survey' is protected and only accessible
// within class 'Survey' and its subclasses.
// However, this is how you access survey, as per
// https://github.com/surveyjs/survey-library/issues/1855.
// @ts-ignore
this.survey.current.survey.clear()
// @ts-ignore
this.survey.current.survey.render()
this.props.onComplete(surveyJson)
}
render() {
return (
<Container>
<SurveyReact
ref={this.survey}
showCompletedPage={false}
json={this.props.json}
onComplete={this.onComplete}
/>
</Container>
)
}
}
I'd like to bump this, it's still causing issues for me and my product. How can I clear the survey in React?
Been a couple months now, any word?
I'm sorry. Missed that.
In react we can do it in react way (I hope :-) )
Here is the code sandbox sample - https://codesandbox.io/s/surveyjs-react-example-show-react-component-on-complete-njnre
We render survey as component, subscribe on complete event, update the state and show survey again. React re-renders survey by it's natural way. Does it fit your needs?
For ease of commenting I'll paste your code here:
import React from "react";
import ReactDOM from "react-dom";
import * as Survey from "survey-react";
import "./styles.css";
import "survey-react/survey.css";
class SurveyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { surveyInstanceNo: this.surveyInstanceNo };
this.onCompleteComponent = this.onCompleteComponent.bind(this);
}
surveyInstanceNo = 0;
json = {
pages: [
{
name: "page1",
elements: [
{
type: "checkbox",
name: "q1",
choices: [1, 2, 3]
}
]
}
]
};
onCompleteComponent(survey) {
this.setState({ surveyInstanceNo: ++this.surveyInstanceNo });
alert(
"Lets take survey again!\n Survey result=" + JSON.stringify(survey.data)
);
}
render() {
return (
<Survey.Survey json={this.json} onComplete={this.onCompleteComponent} />
);
}
}
function App() {
return (
<div className="App">
<h1>SurveyJS react example</h1>
<SurveyComponent />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
So it looks to me like the version you're using (1.0.58, why did you choose one different from the one I'm asking about?) _automatically clears the survey on complete_, and you're using a state variable of surveyInstanceNo (which you also have duplicated on the class prototype) as a hack to force a rerender. Let me ask you this then -- what happens if the component rerenders for a different reason while the user is taking the survey? Will their progress get wiped out? This kind of seems like it's half a controlled component and half not, which might lead to the situation I've described as being a bug. And that situation's existence leaves my question standing.
Yes, I'm asking for an imperative solution for a declarative framework, but it is still written in the docs, and I still need the answer.
Did you ever find a solution to this?
@Aaronik You have to have a survey model as a class property:
this.model = new Survey.Model(this.json);
and then you can use it in the render
return (<Survey.Survey model={this.model} onComplete={this.onCompleteComponent}/>);
To reset the model, you have to do: this.model.clear(); and then change the state. You can have numberOfTakenSurveys in the state. Changing the state, will trigger the render() function and your clean survey will be rendered.
PS: The current version is 1.8.1
Thank you,
Andrew