I had a project that I was working on a little while ago and the owners wanted to have a way for the users to see how they were progressing as they filled in a form. I devised a technique to render a progress meter that is advanced by filling *required* fields. I thought that it would be good to share this as a re-usable artifact with this community. Although this artifact has undergone some testing there may still be issues, if you choose to use it it is not supported by IBM.
The scenario that I am presenting you is a form that an applicant will fill out to earn a "badge" that demonstrates competency in a subject. Each page will show a progress meter that advances as the applicant fills out all the required fields. In the image below you can see the progress meter.
I have tried to construct it in such a way that it will be easy to implement in any form where you want to use it. There are 4 steps:
1. Add the RecursionFunctions.js to the application. Note: to add files, go to Settings...Files...
2. Add the ProgressMeter.js to the application.
3. Create an HTML object in your form where you want the progress meter to appear. You can create multiple HTML objects, one on each page of your form. After you create the object, enter "pbCustom1" as a custom CSS class name. This css class name is used by my code to make the progress meter perform its duty. Note: the css class name that you use here can be anything you want it to be.
4. In the onShow event of form add the following line of code:
//form object, css class, meter style,progress string, width, bgcolor, fgcolor, type (all, required,pages(not implemented))
app.getSharedData().pb(form, "pbCustom1", "custom",'Application Progress: %s%', '600', '', 'multi', 'all', 'F_RequestorName,F_RequestorEmail,F_1stApproverName,F_1stApproverEmail');
Now this line is where all the customization can be done for the progress meter. Let me describe the parameters:
1. form - this is the form UI object and it will always be form.
2. pbCustom1 - This is the custom class name that you assign to your HTML objects. This needs to be the same as what you define in step 3.
3. custom - This defines the style of the progress meter. You can use progress, meter or custom. Each one is a different meter implementation.
4. 'Application Progress: %s%' - This is the string that will be rendered inside of the progress meter. You can set any text that you like and the %s% will be replaced by the calculated progress percentage. This is only used if you specify the bar style as custom.
5. 600 - This is the width of the progress meter. This is only used if you specify the bar style as custom.
6. bgcolor - This is the background color to use for the progress meter. This is only used if you specify the bar style as custom.
7. fgcolor - This is the foreground color to use for the progress meter. This is only used if you specify the bar style as custom. I created a special style that will show the bar as yellow if less than 100% and then green once complete; to use this style specify "multi".
8. type - This must be set to all. I had some other ideas that the progress meter could be used to support some other scenarios which I have not had a chance to explore; perhaps in version 2.0.
9. items to omit - This is a comma separated list of the fields to omit from the progress meter calculation. This is helpful if you have some required fields that you don't want to include in the progress meter advancement.
That's it! So easy right?
Let's talk a bit about how it works.
2. For each item that is found, required or not, we add an onItemChange event handler. Inside this handler we check if the field is required, if it is then we update the progress meter. The reason that we attach this to every item is because even though that item may not be required right now, it might become required as a result of a rule. We want to make sure that we capture all required fields!
3. There is also a delay in the onItemChange event handler because a field's state change from non-required to required is not immediate and occurs after the onItemChange event. This 1 second delay insure that the progress meter is updated properly every time.
4. All the onItemChange event handlers that are created are pushed into an array so that we can disconnect them when the form is destroyed. This is important because if you have a form with multiple stages, if you do not disconnect the events then you will end up with duplicated events!
Now for small forms this progress meter does not introduce any noticeable performance issues. It is important to note that all of the code that controls the progress meter are run client-side. I could imagine that you could build a form that might not play nicely with this implementation. You will have to be the judge of that - please make sure you test how the form behaves after adding the progress meter code.
I hope that you like what I have built and that you find it helpful. If you do have any suggestions or encounter any issues, definitely let me know. I did encounter a few defects as I created this and the team is working on addressing those for a future release.