Expand my Community achievements bar.

SOLVED

Question regarding dynamically flowing forms layout

Avatar

Level 3

I am new to using AEM Forms and somewhat of a learning curve from just regular PDF forms, and I need some assistance with subforms design.

I tried using the AEM conversion tool for my forms, but ended up manually recreating most of it, because of the dynamic expansion that we are trying to achieve.

I have 13 different groups of questions, which I have made each question its own subform. 

 

My problem is two fold:

 

1.  On the last page of the form in the original design, I had 2 "overall score" fields, which were placed in the bottom of the page and centered on the same line, and I want to try to keep that same design, but if I don't add those fields into the subform above it, if the fields grow to big, the text doesn't shift the rest of the form down, so I tried putting the "overall scores" fields in its own subform, same result, and the only way i can seem to get it to work is adding those fields into the subform above, and I had added t top margin to space it out from the above field, but i do not like the top down look for those fields, any suggestions?

 

2. Each subform i have seems to overwrite the next subform, if the fields expand enough, and not push the content down, like i want it to.  I read that I need to put everything into a single subform in order to achive this goal, is that correct?  If i do that though, all of the fields will be compacted in the top down format and not appear correct.  So, if I have to do that, how do i keep the layout the same, with achieving text expansion for my fields?

1 Accepted Solution

Avatar

Correct answer by
Level 10

For dynamically growing forms, you need to use a flowing layout. Here a rough sketch how.

If an object like a text fields can grow, then all objects in the hierachy above it must be set to be flowed and growable too to avoid overlapping.

 

form1

   masterpages

      masterpage1

      …

bodypage (flowed to-bottom, allows page breaks)

    subform1 (flowed)

        textfield1 (growable)

        …

    subform2 (postioned)

        textfield2 (fixed size)

    …

 

 

For your other problem with the overall score, please share the form or at least a few screenshots.

View solution in original post

6 Replies

Avatar

Correct answer by
Level 10

For dynamically growing forms, you need to use a flowing layout. Here a rough sketch how.

If an object like a text fields can grow, then all objects in the hierachy above it must be set to be flowed and growable too to avoid overlapping.

 

form1

   masterpages

      masterpage1

      …

bodypage (flowed to-bottom, allows page breaks)

    subform1 (flowed)

        textfield1 (growable)

        …

    subform2 (postioned)

        textfield2 (fixed size)

    …

 

 

For your other problem with the overall score, please share the form or at least a few screenshots.

Avatar

Level 3

Great thanks as I had both subforms on each page flowed but that's helpful.

 

here is the screenshot of how the form looks right now.  So to preface this to do some layout spacing, i added margins to the top of a lot of the fields:

commalliance_0-1643815038270.png

this is what the original form looked like:

commalliance_1-1643815158079.png

 

Also, would you happen to be good at coding?  Because I cannot seem to get two codes modified to AEM forms to use correctly:

 

overall score:

// Initialize variables

var i, v, num = 0, sum = 0;

// Loop through the input fields

for (i = 1; i <= 13; i++) {

  v = +getField("A" + i).value;

  if (v !== 0) {

  // increment the non-blank/zero field counter

  num++;

  // add the field value to the running total

  sum += v;

  }

}

// Calculate the average

if (num) {

  event.value = sum / num;

} else {

  // All fields are empty, so set to blank

  event.value = "";

}

event.value = (event.value - 0.005).toFixed(2);
if (event.value <= 0) event.value = "";

Overall final score :

event.value = (this.getField("Overall Score2").value - 0.005).toFixed(2);

if (event.value <= 0) event.value = "";

Avatar

Level 10

The scripting syntax is different to that in Acrobat and there are two different scriting languages: FormCalc and JavaScript. Each of them has its benefits. 

 

For your average field you can use a combination of both. Put this JavaScript in the calculate event. It filters for all dropdown lists in the current row with a value other than "0".

// Generic function to calculate average value from all dropdowns set to other than 0
var oNodes = this.parent.resolveNodes("#field.[Exists($.ui.#choiceList) eq 1 and $ ne 0]"),
	l = oNodes.length,
	i = 0, t = 0, 
	nAvg = null;
for (i; i < l; i += 1)  {
	t += parseInt(oNodes.item(i).rawValue, 10);
}

if (t > 0) {
	nAvg = t / l; 
}
this.rawValue = nAvg !== null ? nAvg.toFixed(2) : nAvg;

Avatar

Level 3

Thanks for the script, so I did add that to that field for the javascript calculate event, and then tried it in the preview and when the drop down fields changed, that field remained blank, am I doing something wrong?

 

Ok, so after reading the script and your reply, I wanted to clear, in the "Average score" fields of each row, I am using formcalc to calculate the average of each row, which works perfectly.


but needed a formula, to average all of the "average score fields" but filter out any of the average score fields that are 0, so the calculation is correct.

So I've tried a few variations of my original script, but none of them seem to work, and not sure why?

Avatar

Level 10

The total average can be calculated the same way as shown above. You only need the set a different filter for the fields you're after.

 

// Generic function to calculate average from numeric fields.
// If filters for any subform under pmp and any nested subform within which then includes a object Table1 which contains an object Row1 with a numeric field with a value greater than 0.
var oNodes = pmp.resolveNodes('#subform[*].#subform[*].Table1.Row1.#field.[Exists($.ui.#numericEdit) eq 1 and $ gt 0]'),
	l = oNodes.length,
	i = 0, t = 0, 
	nAvg = null;
	
for (i; i < l; i += 1)  {
	t += parseFloat(oNodes.item(i).rawValue);
}

if (t > 0) {
	nAvg = t / l; 
}
this.rawValue = nAvg !== null ? nAvg.toFixed(2) : nAvg;