Survey-library: How to reset / clear a survey so it can be taken multiple times?

Created on 7 Oct 2019  路  8Comments  路  Source: surveyjs/survey-library

Are you requesting a feature, reporting a bug or asking a question?

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.

What is the current behavior?

When the form is completed, it shows the completion html (or nothing, if I specify showCompletedPage={false}).

What is the expected behavior?

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!

question

All 8 comments

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Zucka picture Zucka  路  4Comments

AWIXOR picture AWIXOR  路  3Comments

wollerman picture wollerman  路  4Comments

testweird123 picture testweird123  路  4Comments

dmitrykurmanov picture dmitrykurmanov  路  3Comments