If you are interested in a somewhat dynamic accordion, that can be added to (almost) any dynaform, this is one of the options. It hides the dynaform rows (instead of fields) and works even if you have subforms in your dynaform. I recommend navigating through subforms by tabs. For tabs navigation, see this nice example by 'dipo majekodunmi
https://medium.com/dipolediamond/how-to ... 529d4e514
Back to the accordion. First, insert panels in the dynaform on places according to your choice. The javascript below works with classes solely, so there is no need for specifically naming the panels.
In each of the panels you inserted, click edit and write this html code:
Code: Select all<button class="accordion" style="background-color:lightblue;">Section 1</button>
Styling of the panels is up to you, it suffice if you add the css in the first panel only (since we define the accordion class in the first panel). As an example of CSS, this worked for me quite nicely with the PM interface. just remember to include the css in the style/style tags in the html of the first panel:
Code: Select all<style>
.accordion {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
text-align: left;
border: none;
outline: none;
transition: 0.4s;
}
.accordion:after {
content: '\02795'; /* Unicode character for "plus" sign (+) */
font-size: 13px;
color: #777;
float: right;
margin-left: 5px;
}
.activated:after {
content: "\2796"; /* Unicode character for "minus" sign (-) */
}
</style>
After that, in the javascript section of the dynaform, put the following:
Code: Select all//----------------------------
//Accordion Navigation
//----------------------------
function next(event){
event.preventDefault();
var myCollection = $('.accordion'); //get the collection of all elements with class accordion
var clickedButtonIndex = myCollection.index($(event.target)); //find the index of the button that was clicked in the accordion collection
var clickedButtonObject = myCollection.eq(clickedButtonIndex)[0]; //temporarily store the clicked button as object. We will assign the "activated" lass later
var firstPanel = myCollection.eq(clickedButtonIndex).parent().parent(); //find the panel in which the button (accordion) was clicked
var nextButtonIndex = (clickedButtonIndex + 1) % myCollection.length; //get the index of the next accordion (button) in the accorion collection
var nextPanel = myCollection.eq(nextButtonIndex).parent().parent(); //get the panel in which the next accordion button is located
var list1 = $('.pmdynaform-field'); //get the collection of dynaform rows
var firstRow = list1.index(firstPanel)+1; //get the first row of the active accordion section. Add 1 to exclude the accordion panel itself
var lastRow = list1.index(nextPanel)-1; //get the last row and subtract 1 to exlude the second accordion panel
if (clickedButtonObject.classList.contains("activated")){ //check if the accordion is active already
for (i = firstRow; i < lastRow;i++){ //hide the rows between the two accordions if the accordion was active
list1[i].style.display = 'none';
$(clickedButtonObject).removeClass("activated");
}
} else {
for (i = firstRow; i < lastRow;i++){ //hide the rows between the two accordions if the accordion was inactive
list1[i].style.display = 'block';
$(clickedButtonObject).addClass("activated");
}
}}
$('.accordion').click(next); //assign event to all elements with class "accordion" and call the function
Now, we need something which will hide the rows in the dynaform immediately after the dynaform is loaded/displayed. To do this, add the following js after the last line of the code:
Code: Select allfunction HideAll(){
var a;
var i;
var aForms = $('.form-horizontal'); //get the collection of dynaform forms and subforms
for (a = 1;a<aForms.length;a++){ //[b]CHANGE [/b]this to a=0 in case there are no subforms in your dynaform
var subCol = $('.accordion',aForms[a]);
if (subCol.length > 0 && typeof(subCol) != "undefined") {//check if there are any accordions in the subform
var aRows = $('.pmdynaform-field', aForms[a]) //get the subcollection of all rows within the subform
//console.log(aRows);
for (i = 0;i < aRows.length;i++){
if ($(aRows[i]).children().children('.accordion').length>0) {
console.log(aRows[i]);
//console.log(aForms[a].(aRows[i]));
aRows[i].style.display = 'block';
aRows[i-1].style.display = 'block';
} else {
aRows[i].style.display = 'none';
}
if ($(aRows[i]).children().children('.accordion.last').length>0) {
aRows[i].style.display = 'none';
aRows[i-1].style.display = 'none';
}}}}}
HideAll(); //call the function at dynaform startup
This is how it looks like in the preview:
Edit:
I forgot to mention that you need to create a closing panel at the end of each subforms. In this panel, you insert this html:
Code: Select all<button class="accordion last">Always Hidden</button>
This panel makes sure that also the last accordion expands/collapses correctly.