Question T4692
Visible to All Users

Dynamic Panel Nesting Depth & Parent

created 5 years ago

Hello,

I am writing a custom widget and when in design mode, I need to know how to traverse nested dynamic panels.

The panel model doesn't have a parent value (object nor id) and the depth value shows zero despite multiple nested panels. I have tried the "onAfterRenderPanel" but still can't access the parent value (e.g. page -> panel -> panel -> panel -> custom widget).

I may find an alternate way of doing this but any help would be greatly appreciated.

Regards
Chris

Answers approved by surveyjs Support

created 5 years ago (modified 5 years ago)

Hello Chris,
I would write the code in this way:

JavaScript
function getElementName(el) { return !!el ? el.name : '<empty>'; } function onSave() { console.clear(); var pages = creator.survey.pages; pages.forEach(p => { setParentRecursive(p); }); } function setParentRecursive(parentEl) { var elements = parentEl.elements; if (!elements && !!parentEl.template) { elements = parentEl.template.elements; } if (!!elements) { elements.forEach(el => { el.parentElement = parentEl; el.grandParentElement = parentEl.parentElement; console.log( 'name: ' + getElementName(el) + ', parent: ' + getElementName(el.parentElement) + ', grandparentname: ' + getElementName(el.grandParentElement) ); setParentRecursive(el); }); } }

Here is the example.

Thank you,
Andrew
SurveyJS Team

    Show previous comments (3)

      Hello Chris!
      Sorry, did you solve the issue?

      Thank you,
      Andrew
      SurveyJS Team

        Hello Andrew,

        Yes. I have now resolved this.

        Many thanks
        Chris

          Great!

          Andrew
          SurveyJS Team

          created 5 years ago

          Hello Chris,

          Could you please share with us a plunker or your code? Do you have the same issue with the standard question? I am sorry, I re-read your message several times but did not get the issue.

          Thank you,
          Andrew
          SurveyJS Team

            Show previous comments (4)

              Hello Andrew,

              I am sorry to come back to you with this, but I getting spurious results when using the property ‘data.data’ on nested dynamic panels in order to obtain the parent dynamic panel.

              Please see the JSON below…

              {
              "title": "Dynamic Panel Bug",
              "pages": [
                {
                 "name": "P1",
                 "elements": [
                  {
                   "type": "lookup",
                   "name": "Page 1 Q1"
                  },
                  {
                   "type": "paneldynamic",
                   "name": "Panel 1",
                   "templateElements": [
                    {
                     "type": "lookup",
                     "name": "Page 1 Q2"
                    },
                    {
                     "type": "paneldynamic",
                     "name": "Panel 2",
                     "templateElements": [
                      {
                       "type": "lookup",
                       "name": "Page 1 Q3"
                      },
                      {
                       "type": "paneldynamic",
                       "name": "Panel 3",
                       "templateElements": [
                        {
                         "type": "lookup",
                         "name": "Page 1 Q4"
                        }
                       ]
                      }
                     ]
                    }
                   ]
                  }
                 ]
                }
              ]
              }

              When I recurse the dynamic panels the ‘data.data.name’ for each are as follows:

              Panel 1 = undefined (correct)
              Panel 2 = Panel 1 (correct)
              Panel 3 = Panel 1 (incorrect, needs to be Panel 2)

              I want to be able to obtain the parent dynamic panel within a nested dynamic panel. Is there another way to do this?

              Kind regards
              Chris

                Hello Chris,
                It is hard to understand, what are you doing. Please fork this plunker, modify it, so I can see the issue and send us the link on updated plunker.

                Thank you,
                Andrew
                SurveyJS Team

                  Hello Andrew,

                  Thank you for your help and the plunker code.

                  The issue I have is with the creator (in design mode) not the viewer, sorry for not mentioning this.

                  The viewer works as expected but not the creator as it seems that there is a difference in the logic as the ‘data.data’ object is always the first dynamic panel.

                  I have enclosed my HTML and script files below.

                  Kind regards
                  Chris

                  My HTML file index.html is…

                  <!DOCTYPEhtml>
                  <htmllang="en">
                  <head>
                     <title>Single line text - Text question, jQuery Survey Library Example</title>

                  <metaname="viewport"content="width=device-width"/>
                     <scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
                     <scriptsrc="https://surveyjs.azureedge.net/1.7.23/survey.ko.min.js"></script>
                     <scriptsrc="https://surveyjs.azureedge.net/1.7.23/survey-creator.min.js"></script>
                     <scriptsrc="https://unpkg.com/jquery"></script>
                     <scriptsrc="https://surveyjs.azureedge.net/1.7.23/survey.jquery.js"></script>
                     <linkhref="https://surveyjs.azureedge.net/1.7.23/modern.css"type="text/css"rel="stylesheet"/>
                     <linkhref="https://surveyjs.azureedge.net/1.7.23/survey-creator.css"type="text/css"rel="stylesheet"/>

                  </head>
                  <body>

                  <divid="survey"></div>
                     <scripttype="text/javascript"src="./index.js"></script>

                  </body>
                  </html>

                  My script file index.js is…

                  Survey
                      .StylesManager
                      .applyTheme("modern");

                  var json = {
                  "title":"Dynamic Panel Bug",
                  "pages": [
                    {
                    "name":"P1",
                    "elements": [
                      {
                      "type":"text",
                      "name":"Page1Q1"
                      },
                      {
                      "type":"paneldynamic",
                      "name":"Panel1",
                       panelCount: 1,
                      "templateElements": [
                        {
                        "type":"text",
                        "name":"Page1Q2"
                        },
                        {
                        "type":"paneldynamic",
                        "name":"Panel2",
                         panelCount: 1,
                        "templateElements": [
                          {
                          "type":"text",
                          "name":"Page1Q3"
                          },
                          {
                          "type":"paneldynamic",
                          "name":"Panel3",
                           panelCount: 1,
                          "templateElements": [
                            {
                            "type":"text",
                            "name":"Page1Q4"
                            }
                           ]
                          }
                         ]
                        }
                       ]
                      }
                     ]
                    }
                  ]
                  };

                  var options = { showEmbededSurveyTab:true, generateValidJSON:true, questionTypes: ["text","checkbox","radiogroup","dropdown","paneldynamic","signaturepad"] };

                  var surveyCreator =newSurveyCreator.SurveyCreator("survey", options);
                  surveyCreator.text = JSON.stringify(json);
                  surveyCreator.saveSurveyFunc = onSave;

                  function onSave() {

                  var a = surveyCreator.survey.getAllQuestions(true);
                      setParents(a);

                  }

                  function setParents(a) {

                  console.clear();
                     this.setParentRecursive(a);

                  };

                  function setParentRecursive(a, n, p) {

                  a.forEach(q => {
                         let t = q.getType();
                         switch (t) {
                             case"panel":
                                 this.setParentRecursive(q.elements, n, p);
                                 break;
                             case"paneldynamic":
                                 if (q.data.data) {

                  console.log({ name: q.name, parent: q.data.data.name });

                  this.setParentRecursive(q.panels, q.name, q.data.data.name);
                                  }
                                 else {
                                     this.setParentRecursive(q.panels, q.name);
                                  }
                                 break;
                             case"lookup":
                                  q.parentname = n;
                                  q.grandparentname = p;
                                 break;
                          }
                      });

                  };

                  created 5 years ago (modified 5 years ago)

                  Hello,

                  You can use data property. For example, if you use nested PanelDynamic, you can refer to parent PanelDynamic via data.data or to parent Panel via data.panel.

                  Thanks,
                  Dmitry
                  SurveyJS Team

                    Comments (1)

                      Hello,

                      Thank you for your prompt response.

                      This doesn’t seem to work correctly for what I need to happen.

                      I am finding that when I have paneldynamic panel embedded with paneldynamic panels, the ‘data’data’ doesn’t always refer to the parent panel depending whether the parent panel has questions before the embedded child panel… examples are:

                      Page > Panel #1 > ( Panel #2 > ( Panel #3 > Widget #1 ), Panel #4 ))) (Panel #4 parent is Panel #3)
                      Page > Panel #1 > ( Panel #2 > ( Panel #3 > ( Panel #4, Widget #1 ))) (Panel #4 parent is Panel #1)
                      Page > Panel #1 > ( Panel #2 > ( Panel #3, Widget #1 > ( Panel #4, Widget #2 ))) (Panel #4 parent is Panel #3)
                      Page > Panel #1 > ( Panel #2 > ( Panel #3, > ( Panel #4, Widget #2 ), Widget #1 )) (Panel #4 parent is Panel #1, expecting parent to be Panel #3)

                      Can you confirm this is the correct logic?

                      Kind regards
                      Chris