Collapse Populated Repeating Section?


Userlevel 6
Badge +15

Hi folks!

Using on-prem 2013. 

I'm wondering if you've discovered a way to hide / show (collapse and expand) repeating sections with a pre-populated title for it?

The current need is to populate a repeating section with data from another 3, 4, or 5+ items (1 form = 1 repeating section), but we'd then like to collapse that so a user doesn't have to see all the data all at once, but has access to open and shut each one. 

Thanks for any ideas / guidance you may have.

Cheers!

rhia


6 replies

Userlevel 5
Badge +14

dynamic resizing of and/or within repeating section is painfull. I'd rather avoided that.

see eg. nmarples‌' post

https://community.nintex.com/message/67237-re-problem-with-tabs-and-repeating-sections?commentID=67237#comment-67237 

Userlevel 5
Badge +14

I don't have any solid answers, but I do have vague beginnings. 

Assuming that you're using Classic Forms (If you're not using Classic Forms, please ignore most of this), resizing things can quickly become a terrible nightmare of eldritch horror. 

That being said, the following code will make life a little easier:

NWF.FormFiller.Events.RegisterControlShowHidePropagating(function() {  
  outerDiv.data("outerDivHeight", outerDiv.height());
});

NWF.FormFiller.Events.RegisterControlShowHidePropagated(function() { 
  if (arguments[0].data("RepositionControls") === true && outerDiv.data("outerDivHeight") !== outerDiv.height()) {
    outerDiv.outerHeight(outerDiv.height());
    outerDiv.data("outerDivHeight", outerDiv.height());
  }
});

NWF.FormFiller.Events.RegisterControlHeightChangePropagated(function() {
  outerDiv.outerHeight(outerDiv.height());
});‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Because the native Nintex code resizes the canvas incorrectly, this will ensure that it is correctly re-re-sized afterwards for any change to the canvas (which makes life WAAAAAY easier on the math side of things). 

If the heights of your rows are consistent and never change, you should always be able to get the 'real' height of your repeating section row from the hidden row located with the class ".nf-repeater-row-hidden". Otherwise it might be wise to store the height of the row on the actual row element using the jquery data object: 

NWF$(NWF$(".nf-repeater-row:visible")[x]).data("realRowHeight", NWF$(NWF$(".nf-repeater-row:visible")[x]).height());
// the should be replaced by the index of the row you're targeting
‍‍‍‍‍

jQuery as a few useful tools for toggling elements, but both the .toggle() and .slideToggle() are probably not suitable. Instead I would use .animate() (info can be found here: http://api.jquery.com/animate/) because you can drive it to a specific css state rather than just turning the element off completely. 

Something along the lines of: 

NWF$("#" + someRowID).animate({height:"25px"}, 500);‍‍‍

Would reduce the height of whichever Repeater Row element was being targeted down to 25px over the course of half a second (500ms).

This is important because using slideToggle() or .toggle() just completely hides the row along with its contents! Using animate allows you to have some type of visible portion of the element in question allowing you to do something like putting a richText made html button at the very top of your Repeating Row that will always be visible and allow the user to toggle the state of the row by clicking it (and subsequently firing an event). 

You can take that idea further by setting a class on the button to toggle so that it's easier to track which state the button / row is in. 

Off the top of my head putting all of these concepts together, this is how I would start... 

NWF.FormFiller.Events.RegisterControlShowHidePropagating(function() {  
  outerDiv.data("outerDivHeight", outerDiv.height());
});

NWF.FormFiller.Events.RegisterControlShowHidePropagated(function() { 
  if (arguments[0].data("RepositionControls") === true && outerDiv.data("outerDivHeight") !== outerDiv.height()) {
    outerDiv.outerHeight(outerDiv.height());
    outerDiv.data("outerDivHeight", outerDiv.height());
  }
});

NWF.FormFiller.Events.RegisterControlHeightChangePropagated(function() {
  outerDiv.outerHeight(outerDiv.height());
});‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

NWF.FormFiller.Events.RegisterBeforeReady(function() {
  "use strict";

  NWF$(".specialButtonClass").on("click", function(event) {

    // This is the BUTTON element
    var targetElement = NWF$(event.srcElement);

    // This is the ROW of the Reepating Section that the button
    // is sitting in.
    var thisRow = targetElement.closest(".nf-repeater-row");

    // This is an arbitrary height that the row can be collapsed to
    // and can be changed to your needs.
    var collapsedHeight = 25;

    // This is a placeholder to determine how much the row's height
    // has been changed.
    var heightChange = 0;

    // maybe we'll set the rowHeight data on the row in the on click event
    // if it hasn't already been set.
    if (thisRow.data("rowHeight") === undefined) {
      thisRow.data("rowHeight", thisRow.height());
    }

    if (targetElement.hasClass("collapsedState")) {
      // Expand The Row

      // Get the height difference. Positive height inidcates growing!
      heightChange = thisRow.data("rowHeight") - collapsedHeight;

      // Change the height of this row!
      thisRow.animate({
        height: thisRow.data("rowHeight")
      }, 500);

      // toggle the Class so that this works in reverse next time you click.
      targetElement.removeClass("collapsedState").addClass("expandedState");


    } else if (targetElement.hasClass("expandedState")) {
      // Shrink the row!

      // Get the height difference. negative height inidcates shrinking!
      heightChange = collapsedHeight - thisRow.data("rowHeight");

      // Change the height of this row!
      thisRow.animate({
        height: collapsedHeight
      }, 500);

      // toggle the Class so that this works in reverse next time you click.
      targetElement.removeClass("expandedState").addClass("collapsedState");
    }

    // Now we try to change the canvas...
    NWF.FormFiller.Resize.RepositionAndResizeOtherControlsAndFillerContainerHeight(thisRow, heightChange, heightChange, NWF$("#formFillerDiv"));
  });
});


NWF.FormFiller.Events.RegisterAfterReady(function() {
  "use strict";

  // click each button after the form is ready.
  // Or maybe do this else where... up to you!
  NWF$(".specialButtonClass").each(function(index, button){NWF$(button).trigger("click");});
});
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

(Note: you'll probably need to remove all of the comments from the code before throwing it in to the javascript portion of your form otherwise it'll get angry and reject it)

Please keep in mind that I haven't tested any of this and this is just spitballing. It just so happens that I recently had the need to resize a repeating row section / canvas for a new form that I'm making, so some of this stuff is fresh. 

You're probably going to run into horrible problems depending on the various things that can muck up development for multiple platforms / browsers, but this should at least give you an idea of what needs to happen. 

Turn back before it's too late! 

EDIT (2018-04-10): I have revised the code put inside of the RegisterControlShowHidePropagated / Propagating events as I found in a recent use case that this could resize the canvas when no actual resizing has occurred (as those "events" are fired no matter what). The new code simply adds some data to the outerDiv of the current scope and will reference it as a means to double check whether or not the form canvas was actually changed even if the control data indicates that is has been. 
Userlevel 5
Badge +14

ha! Just saw this after finishing up a reply! 

Userlevel 5
Badge +14

nice outline!

I did even not dare to think of whether it would be worth of it at all happy.png

 

Userlevel 5
Badge +14

was this ever useful? 

Userlevel 6
Badge +15

I haven't had a chance to test it yet! But I am sure it is useful. Will test soon!

Reply