Question T14125
Visible to All Users

Changing display mode breaks progress bar navigation

created a year ago

I have raised the issue in github as well. here is the url for more information

https://github.com/surveyjs/survey-library/issues/6653

Following is my scenario:-

  • Form designed with three pages with progress bar for navigating to different pages.
  • Initial load showing form in read only mode by setting mode property to display. Noticed the page navigation is working fine.
  • When user click on edit button(custom) the form mode is change to edit mode and user can enter data and submit.
  • Noticed when the mode of form changed to edit mode then:-
    1) The user automatically navigated back to first page. for e.g if you are on page 3 and click edit button then you get redirected to page1.
    2) The page navigation does not work any more. for e.g now if click page 2, page 3 then you do not redirect to that corresponding page.

Following is JSON

Code
{     "logoPosition": "right",     "pages": [      {       "name": "Personal Infomrmation",       "elements": [        {         "type": "panel",         "name": "panel1",         "elements": [          {           "type": "text",           "name": "firstName",           "title": "Enter Name"          }         ]        }       ],       "title": "Personal Information"      },      {       "name": "Address",       "elements": [        {         "type": "text",         "name": "address",         "title": "Enter Address"        }       ],       "title": "Address"      },      {       "name": "Nationality",       "elements": [        {         "type": "text",         "name": "nationality",         "title": "Current Nationality"        }       ],       "title": "Nationality"      }     ],     "showProgressBar": "top",     "progressBarType": "buttons"    };

and following is the react code

Code
class App extends Component {   constructor() {     super();     this.state = {mode: "display"};   }   render() {     const surveyModel = new Model(surveyJson);     surveyModel.mode =this.state.mode     return (<div>                 <h2>current mode is {this.state.mode} !</h2>                         <button onClick={() => this.changeDisplayMode("Edit")}>Edit</button>               <Survey model={surveyModel} />             </div>);   }   changeDisplayMode = (strMode) => {       this.setState({ mode: strMode });   } }

Answers approved by surveyjs Support

created a year ago

Hello Samit,
Thank you for the detailed explanation and the sample.

Currently, the surveyModel instance is created within the render method on each render cycle. This means that every time the component re-renders, a new surveyModel instance is created, and its mode property is set based on the current state.
However, this approach has a problem. When you update the state using this.setState({ mode: strMode }), the surveyModel instance does not automatically get updated to reflect the new mode because you're creating a new instance of the model on each render.

Please update the code as follows:

JavaScript
import React, { Component } from "react"; import { Model } from "survey-core"; import { Survey } from "survey-react-ui"; import "survey-core/defaultV2.min.css"; import "./index.css"; import { json } from "./json"; class SurveyComponent extends Component { constructor() { super(); this.state = { mode: "display" }; this.surveyModel = new Model(json); this.surveyModel.mode = this.state.mode; } changeDisplayMode = (strMode) => { this.setState({ mode: strMode }); this.surveyModel.mode = strMode; }; render() { return ( <div> <h2>current mode is {this.state.mode} !</h2> <button onClick={() => this.changeDisplayMode("Edit")}>Edit</button> <Survey model={this.surveyModel} /> </div> ); } } export default SurveyComponent;

View Demo

In the updated code, the surveyModel instance is created within the constructor of the component. This means that the instance is created only once, when the component is initialized. The mode property of the surveyModel instance is set based on the initial state.

Since the surveyModel instance is created only once and stored as a property of the component (this.surveyModel), updates to the mode property are directly reflected in the instance, and the reactivity works as expected.
By ensuring that the surveyModel instance is not recreated on every render cycle, the updated code maintains a consistent reference to the survey model, making the reactivity with the component's state effective.

Now, when a user enables the edit mode, a survey remains on the currently selected page, and navigation works correctly.
Clipboard-File-1.png
I hope this helps. Please let me know if you have any questions or require further assistance.