surveyjs / survey-library

Free JavaScript form builder library with integration for React, Angular, Vue, jQuery, and Knockout.
https://surveyjs.io/form-library
MIT License
4.01k stars 782 forks source link

Next button is not transformed to Finish when trigger function is met #8301

Closed kasar-NTT closed 2 hours ago

kasar-NTT commented 1 month ago

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

Bug

What is the current behavior?

We initialize a new SurveyModel with a JSON of a multi-page questionnaire that contains a trigger to "complete" it, before the end of the pages. Then we mergeData to that model where the the condition of trigger is met.

In that case the button label remains "Next" where it should be "Finish" . In case the user clicks the "Next" button (where it should say "Finish") the questionnaire is finished

What is the expected behavior?

The button should say Finish instead of Next

How would you reproduce the current behavior (if this is a bug)?

Load the codesanbox url provided below

Provide the test code and the tested page URL (if applicable)

Tested page URL: https://codesandbox.io/p/sandbox/surveyjs-angular-forked-d4l2j8?file=%2Fsrc%2Fapp%2Fcomponents%2Fsurvey.component.ts%3A15%2C3-25%2C4

Test code

`json.ts`
export const json = {
  triggers: [
    {
      type: "complete",
      expression: "{exit1-test} = 'Yes'",
    },
    {
      type: "complete",
      expression: "{exit2} = 'Yes'",
    },
  ],
  pages: [
    {
      title: "What operating system do you use?",
      elements: [
        {
          type: "checkbox",
          name: "opSystem",
          title: "OS",
          showOtherItem: true,
          choices: ["Windows", "Linux", "Macintosh OSX"],
        },
        {
          type: "radiogroup",
          name: "exit1-test",
          title: "Do you want to finish the survey?",
          choices: ["Yes", "No"],
          colCount: 0,
        },
      ],
    },
    {
      title: "What language(s) are you currently using?",
      elements: [
        {
          type: "checkbox",
          name: "langs",
          title: "Please select from the list",
          colCount: 4,
          choices: [
            "Javascript",
            "Java",
            "Python",
            "CSS",
            "PHP",
            "Ruby",
            "C++",
            "C",
            "Shell",
            "C#",
            "Objective-C",
            "R",
            "VimL",
            "Go",
            "Perl",
            "CoffeeScript",
            "TeX",
            "Swift",
            "Scala",
            "Emacs Lisp",
            "Haskell",
            "Lua",
            "Clojure",
            "Matlab",
            "Arduino",
            "Makefile",
            "Groovy",
            "Puppet",
            "Rust",
            "PowerShell",
          ],
        },
        {
          type: "radiogroup",
          name: "exit2",
          title: "Do you want to finish the survey?",
          choices: ["Yes", "No"],
          colCount: 0,
        },
      ],
    },
    {
      title: "Please enter your name and e-mail",
      elements: [
        {
          type: "text",
          name: "name",
          title: "Name:",
        },
        {
          type: "text",
          name: "email",
          title: "Your e-mail",
        },
      ],
    },
  ],
};

`survey.component.ts`

import { Component, OnInit } from "@angular/core";
import { Model } from "survey-core";
import { json } from "./json";

@Component({
  // tslint:disable-next-line:component-selector
  selector: "component-survey",
  templateUrl: "./survey.component.html",
  styleUrls: ["./survey.component.css"],
})
export class SurveyComponent implements OnInit {
  model: Model;
  ngOnInit() {
    const survey = new Model(json);
    survey.mergeData({
      "exit1-test": "Yes",
    });

    survey.onComplete.add((sender, options) => {
      console.log(JSON.stringify(sender.data, null, 3));
    });
    this.model = survey;
  }
}

Specify your

Screenshots

Initial Stage:

image

After clicking to No and then Yes again

image

andrewtelnov commented 1 month ago

@kasar-NTT To implement this, we would have to run "complete" triggers and check if they are going to be executed or not on every value change. Since some developers may use custom function in "complete" trigger expressions, including async function with requests on servers, this functionality should be optional.

Thank you, Andrew

kasar-NTT commented 1 month ago

@andrewtelnov is there any way to manually/programmatically call the check of the triggers?

andrewtelnov commented 1 month ago

@kasar-NTT You can get the list of triggers as: survey.triggers. Every trigger has getType() function, as all SurveyJS objects. You can use survey.runExpression(expression) function. It should return true for your complete trigger. You can use survey.onValueChanged event to handle any value change for all questions. Please refer to our survey API for more information.

Thank you, Andrew