Skip to content

Advanced Progress Bar

Vijaivir Dhaliwal edited this page Nov 25, 2022 · 25 revisions

A custom progress bar can be added to the form to enhance the user experience and indicate the remaining steps within the form. More features have been added to advance the functionalities of the progress bar.

Features added

  • ability to perform validity checks on all the components ( e.g. input component) in each tab component
  • ability to indicate error colour in case the validity checks fail
  • each progress bar step has a title that corresponds with the title of each tab of the tab component

Type A: Progress Bar with Tab Component

This Progress Bar is designed to work with Tab Component, and with the Next and Previous Buttons

ap1

Step 1: Start by dragging an ‘HTML Component’ into the form builder.

Step 2: change the ‘HTML tag’ field from p to div, and in the ‘Display’ tag enter a unique and custom class name in the ‘CSS Class'. In this screenshot, we used healthStepper

ec495eda-f81c-423b-82f7-6f4a025ad090

Step 3: Copy the following code into the ‘Content’ section

<ol class="c-stepper">
    <li class="c-stepper__item active">
        <h3 class="c-stepper__title">Step 1</h3>
        <p class="c-stepper__desc">Facility Information</p>
    </li>
    <li class="c-stepper__item disabled">
        <h3 class="c-stepper__title">Step 2</h3>
        <p class="c-stepper__desc">Bed Occupancy</p>
    </li>
     <li class="c-stepper__item disabled">
        <h3 class="c-stepper__title">Step 3</h3>
        <p class="c-stepper__desc">Staffing Level</p>
    </li>
     <li class="c-stepper__item disabled">
        <h3 class="c-stepper__title">Step 4</h3>
        <p class="c-stepper__desc">Operating Level</p>
    </li>
    <!-- Other steps -->
</ol>

ap3

Step 4: Click on the ‘Logic’ tab and click on the ‘Add Logic’ button

ap4

Step 5: Enter any name as the 'Logic Name'

ap5

Step 6: In ‘Trigger' section, click on ‘Type’ dropdown menu, and select 'Javascript’

ap6

Step 7: Click “Add Action“ button

ap7

Step 8: Enter any name in “Action Name“

ap8

Step 9: In ‘Trigger' section, click on ‘Type’ dropdown menu, and select 'Javascript’

ap9

Step 10: Copy the following code into the ‘Text Area’ section

let cssId = 'myCss'; 
const head  = document.getElementsByTagName('head')[0];
if (!document.getElementById(cssId))
{
    const link  = document.createElement('link');
    link.id   = cssId;
    link.rel  = 'stylesheet';
    link.type = 'text/css';
    link.href = 'https://timisenco2015.github.io/formulator.github.com/css/chefsCustom.css';
    link.media = 'all';
    head.appendChild(link);
    
    const script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'https://cdn.form.io/formiojs/formio.full.min.js';    
    head.appendChild(script);
}

ap10

Step 11: Click on ‘Save Logic’ and then ‘Save’ the component.

Step 12: Next, add a ‘Tabs’ component from the ‘Advanced Fields’ into the builder

Step 13: Enter a unique name in the label field.

ap11

Step 14: Add as many tabs as you want and details for each tab added

ap12

Step 15: Under the ‘Logic’ tab, click on the ‘Add Logic’ button and add any ‘Logic Name’

ap13

Step 16: Under 'Logic Name', enter any name. Under ‘Trigger', select ‘Type’ dropdown menu, and select 'Event’

ap14

Step 17: enter “change“ in the “Event Name“ field and click on “Add Action“ button

ap15

Step 18: Click on the “Add Action“ Button

ap16

Step 19: enter any name in the “Action Name“ field, select the “Type“ dropdown menu, and select the “Custom Action“

ap17

Step 20: paste the following code into the “Custom Action (Javascript)“ field

const { root} = instance;
root.setPristine(false);

const comp = root ? root.getComponent('data') : null;
const index = comp.currentTab;

const progressStepper = document.querySelectorAll(".healthStepper ol li");
leftOfIndex(index);

rightOfIndex(index, progressStepper.length)
progressStepper[index].classList.remove('errors');
progressStepper[index].classList.remove('disabled');
progressStepper[index].classList.add('active');
progressStepper[index].classList.remove('completed');


function leftOfIndex(index){
  for(let i=0; i<index; i++) {
    if(i===0) {
      if(!validateFacilityInformationTabComponents()) {
        progressStepper[i].classList.remove('completed');
        progressStepper[i].classList.remove('disabled');
        progressStepper[i].classList.remove('active');
        progressStepper[i].classList.add('errors');
      } else {
        progressStepper[i].classList.remove('errors');
        progressStepper[i].classList.remove('disabled');
        progressStepper[i].classList.remove('active');
        progressStepper[i].classList.add('completed');
      } 
    } else {
      progressStepper[i].classList.remove('errors');
      progressStepper[i].classList.remove('disabled');
      progressStepper[i].classList.remove('active');
      progressStepper[i].classList.add('completed');
    }
  }
}
function rightOfIndex(index, endIndex){
  for (let i=(endIndex-1); i>index; i--){
    progressStepper[i].classList.remove('completed');
    progressStepper[i].classList.remove('errors');
    progressStepper[i].classList.remove('active');
    progressStepper[i].classList.add('disabled');
  }
}

function validateFacilityInformationTabComponents() {
  const firstNameComp = root.getComponent('firstName');
  const lastNameComp = root.getComponent('lastName');
  let isAllFieldValue = true;
  isAllFieldValue = firstNameComp.checkValidity();
  isAllFieldValue = lastNameComp.checkValidity();
  return isAllFieldValue;
}

ap18

Note:

  1. Change the ‘data' in the root.getComponent('data') to the name you entered in the “label” field of the Tab Component in Step 13

Type B: Progress Bar with any Layout Component

This Progress Bar is designed to work with any layout component and with the Next and Previous Buttons. Its functionality has been developed almost similarly to Formio Wizard. You switch between each layout using the Previous and Next buttons. It uses the hide attribute of each layout by setting it to true or false and using the triggerRedraw function to redraw the component to the screen.

ap2

Clone this wiki locally