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

Populating matrixdynamic rows/value #6843

Closed yellow-sunshine closed 10 months ago

yellow-sunshine commented 10 months ago

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

Bug, maybe a failure of my understanding which would turn this into a Question

What is the current behavior?

I am pulling data from a database and populating the survey with values. In my example, I am only trying to add one row to a matrixdynamic by hard coding it instead of getting it from DB. It adds a blank row to the matrixdynamic resulting in two rows each without data. Running setValue() on other text fields works as intended. The survey also does not load at the first question on the first page, it skips straight to the matrixdynamic on the second page where the row is added.

What is the expected behavior?

Each time I call addrow(), it should add a row to the matrixdynamic with the passed json data. The first "addrow()" performed should actually not add a row but it should fill out the current row that exists by default. It should not automatically go to the page where the row was added.

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

As a programmer: Create a survey with a matrixdynamic on the second page. Once the survey is created, add a row. As a user: just load the survey.

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

Tested page URL: https://www.brentrussell.com/projects/surveyjs-demo/

Test code You can view the source of the test page URL or read here:

<html>
   <head>
      <meta charset="UTF-8">
      <meta name="author" content="Brent Russell www.brentrussell.com">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Survey Demo</title>
      <!-- Font Awesome CSS -->
      <script src="https://kit.fontawesome.com/425dd88839.js" crossorigin="anonymous"></script>
      <!-- jQuery -->
      <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
      <script src="https://unpkg.com/inputmask@5.0.3/dist/inputmask.js"></script>
      <script src="https://unpkg.com/nouislider/dist/nouislider.min.js"></script>
      <!-- Default V2 theme -->
      <link href="https://unpkg.com/survey-jquery/defaultV2.min.css" type="text/css" rel="stylesheet">
      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
      <!-- Bootstrap JS -->
      <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
      <script type="text/javascript" src="https://unpkg.com/survey-jquery/survey.jquery.min.js"></script>
      <script src="https://unpkg.com/surveyjs-widgets@1.9.97/surveyjs-widgets.min.js"></script>
      <link rel="stylesheet" href="https://unpkg.com/nouislider/dist/nouislider.min.css" />
   </head>
   <body>
      <script>
         // Set forwarding page after application completion
      </script>
      <div class="container mt-8">
         <div class="row">
            <div class="col-md-12 mx-auto">
               <h2 class='SectionHeadings text-center'>Demo Form</h2>
               <div id='applicationContainer'></div>
            </div>
         </div>
      </div>
      <script>
         $(document).ready(function () {
             let survey;
             async function fetchSurveyJSON() {
                 try {
                     const response = await fetch('surveyjson.json');
                     const jsonData = await response.json();
                     const survey = new Survey.Model(jsonData);
                     survey.setValue('name', "Yellow Sunshine"); 
                     var licensesQuestion = survey.getQuestionByName('licenses');
                     licensesQuestion.addRow({'license_authority': "EPA", 'license_number': "EPA43459254", 'license_date': "2023-05-10",'status': 'Yes'});
                     survey.render('applicationContainer');
                 } catch (error) {
                     console.log('Error fetching or parsing the JSON data.');
                 }
             }
             fetchSurveyJSON();
         });
      </script>
   </body>
</html>

surveyjson.json:

{
  "showQuestionNumbers": false,
  "checkErrorsMode": "onValueChanged",
  "pages": [
    {
      "name": "page3",
      "title": "About You",
      "elements": [
        {
          "name": "name",
          "title": "Name",
          "description": "Can be a pseudonym, full legal name, or just your first name.",
          "type": "text",
          "isRequired": true,
          "validators": [
            {
              "type": "text",
              "minLength": 2,
              "maxLength": 60,
              "text": "Please enter your name"
            }
          ]
        }
      ]
    },
    {
      "name": "page5",
      "title":"License Information",
      "elements": [
        {
          "type": "matrixdynamic",
          "name": "licenses",
          "title": "Professional Licenses",
          "isRequired": true,
          "columns": [
            {
              "name": "license_authority",
              "title": "Licensing authority",
              "cellType": "text",
              "isRequired": true,
              "maxLength": 70
            },
            {
              "name": "license_number",
              "title": "License Number",
              "cellType": "text",
              "isRequired": true,
              "maxLength": 70
            },
            {
              "name": "license_date",
              "title": "Date",
              "isRequired": true,
              "cellType": "text",
              "inputType": "date",
              "startWithNewLine": true,
              "minValueExpression": "today(-29200)",
              "maxValueExpression": "today(-1)"
            },
            {
              "name": "status",
              "title": "Is Active?",
              "choices": [ "Yes", "No" ],
              "isRequired": true,
              "cellType": "radiogroup"
            }
          ],
          "detailPanelMode": "underRow",
          "rowCount": 1,
          "addRowText": "Add License",
          "removeRowText": "Remove License"
        }
      ]
    }
  ]
}

Specify your

JaneSjs commented 10 months ago

Hello @yellow-sunshine, Different SurveyJS questions have different value format. Dynamic Matrices receive an array of objects of the following structure:

[
   {
      columnName1: val1, 
      columnNameX: valX 
   }, 
   { 
      columnName1: val1,
      columnNameX: valX
   }
]

For the record: you can review the format of question values in the question.value property description.

If you wish to programmatically populate matrix row values, you can use the survey.setValue function as follows:

survey.setValue("licenses", [
      {
        license_authority: "EPA",
        license_number: "EPA43459254",
        license_date: "2023-05-10",
        status: "Yes"
      }
]);

To populate multiple question values, you can use the survey.data / survey.mergeData() API:

survey.data = {
      name: "Yellow Sunshine",
      licenses: [
        {
          license_authority: "EPA",
          license_number: "EPA43459254",
          license_date: "2023-05-10",
          status: "Yes"
        }
      ]
};

View Demo

For more information on how to populate question values, refer to the following guide: Populate Form Fields.

Should you have any further questions or require assistance, we are here to help.