Is there a way to create a popup to show what fields still needs to be completed?
When we use the pagination option our forms the user would like to see what fields still needs attention and not have to look back through every form.
Is there a way to create a popup to show what fields still needs to be completed?
When we use the pagination option our forms the user would like to see what fields still needs attention and not have to look back through every form.
Chynna,
I ran into this same issue working with paginated forms. I resolved it by writing some custom javascript that does a validation check each time the user attempts to go to the next "page" in the form.
The function is designed to treat every section as a new page so may need some customization for your implementation. It also has some advanced features we use, such as returning to the first incomplete page if the user is resuming a saved draft.
If you have any questions about it, let me know.
Code below.
CSS
.navbar { text-align:center; } .navbar div { padding-top: 8px; width: 150px; height: 40px; cursor: default; border-radius: 6px; background-color: #e5e5e5; text-align: center; margin: auto; border: 2px white solid; display:inline-block; } .navbutton.done { background-color: rgba(0, 128, 0, 0.7); } .navbutton.navitem:hover { cursor: pointer; background-color: rgba(43, 127, 216, 0.7); } .navbar .selected { background-color: #A0A0A0; } .cf-form {padding: 0px 10px 15px;} #cf-formtitle {margin-bottom:0px;} .pbutton {float: left} .nbutton {float: right} .draft-btn { float: right; margin-right: 10px; } .buttons { display: inline-block; width: 100%; text-align: center; margin-top: 20px; }
Javascript
//************************* // tabbedForm Function // Last Updated: 3/16/2016 //************************* $(document).ready(function () { // Only run if not on the Preview Page // The IsLocked input will be true on the Priview Page if ($('input[name=IsLocked]').val() == "False") { tabbedForm(); } }); function tabbedForm() { // This section configures the Navigation Bar and Buttons // Define the sections var section = []; var count = 1; $('.cf-section-block').find('h1:first').each( function() { section.push( { index: count, title: $(this).text() } ); count++; }); // Create Navigation Bar var navbar = '<div class="navbar">'; section.forEach(function(arrayItem) { navbar += '<div class="navbutton" navname="' + arrayItem.title + '">' + arrayItem.title + '</div>'; }); navbar += '</div>'; $(navbar).insertBefore('.cf-section-block:first'); $('.navbutton:first').addClass('navitem'); // Create the buttons section.forEach(function(arrayItem) { $('<div class="buttons"></div>').appendTo($('.cf-section-block').has('h1:first:contains(' + arrayItem.title + ')')); if (arrayItem.index > 1) { $('<input class="navitem pbutton" navname="' + section[(arrayItem.index - 2)].title + '" value="Previous: ' + section[(arrayItem.index - 2)].title + '" type="button">').appendTo($('.cf-section-block').has('h1:first:contains(' + arrayItem.title + ')').find('.buttons')); } if (arrayItem.index < section.length) { $('<input class="navitem nbutton" navname="' + section[(arrayItem.index)].title + '" value="Next: ' + section[(arrayItem.index)].title + '" type="button">').appendTo($('.cf-section-block').has('h1:first:contains(' + arrayItem.title + ')').find('.buttons')); } if (arrayItem.index == section.length) { $('<input type="button" class="checkRequired nbutton submitButton" name="action" value="Submit">').appendTo($('.cf-section-block').has('h1:first:contains(' + arrayItem.title + ')').find('.buttons')); } if ($('.btn-wrapper .draft-btn').val()) { $('<input class="draft-btn" data-toggle="modal" onclick="return false;" data-target="#draftPage" value="Save as Draft" type="button">').appendTo($('.cf-section-block').has('h1:first:contains(' + arrayItem.title + ')').find('.buttons')); } }); // Trigger for custom Submit Button $('div').on('click', '.submitButton', function() { window.onbeforeunload = function(e){}; //This clears any custom beforeUnload function. e.g. warning before leaving page $('.Submit').trigger('click'); }); // Controller for clicking tabs $('div .navbar, div .buttons').on('touchstart click', '.navitem', function (event) { var targetTab = $(this).attr('navname'); var currentTab = $('.selected').attr('navname'); var targetTabIndex = 0; var currentTabIndex = 0; var maxTabIndex = section.length; $(section).each(function(index, arrayItem) { if (arrayItem.title == targetTab) { targetTabIndex = arrayItem.index; } if (arrayItem.title == currentTab) { currentTabIndex = arrayItem.index; } }); // SAME TAB if (currentTabIndex == targetTabIndex) { return; } // NEXT TAB if (currentTabIndex < targetTabIndex) { var valid = true; $('[required], [aria-required]').filter(':visible').each(function() { var readOnly = false; if ($(this).prop('readonly')) { $(this).prop('readonly', false); readOnly = true; } if (!$(this).checkValidity()) { valid = false; } if (readOnly) { $(this).prop('readonly', true); $(this).find('.ws-error').show(); } }); if(!valid) { return; } } // PREVIOUS TAB OR VALID NEXT TAB SelectTab(this); }); // Select the first section initially or if resuming the first uncompleted section if (window.location.pathname.substr(0, 19) == '/Forms/form/resume/') { var lastDoneTab = $('.lastDone input').val(); var doneTabs = $('.navbutton[navname="' + lastDoneTab + '"]').prevAll(); doneTabs.each(function(index, tab) { $('.navbutton[navname="' + $(tab).attr('navname') + '"]').addClass('navitem done'); }); $('.navbutton[navname="' + lastDoneTab + '"]').addClass('navitem done'); $('.done:last').next().addClass('navitem'); $('.done:last').next().trigger('click'); } else { SelectTab($('.navitem:first')); } function SelectTab(tab){ var thisSection = $(tab).attr('navname'); $('.cf-section-block, .btn-wrapper').hide(); if (!$('.selected').hasClass('done')) { $('.selected').next('.navitem').removeClass('navitem'); } $('.navbar').find('.navitem').removeClass('selected'); $('.cf-section-block').has('h1:first:contains(' + thisSection + ')').show(); $('.navbutton:contains(' + thisSection + ')').addClass('selected'); $('.lastDone input').val($('.done').last().attr('navname')); $(section).each(function(index, arrayItem) { if (arrayItem.title == thisSection) { $('.navbutton[navname="' + arrayItem.title + '"]').addClass('navitem'); $('.navbutton[navname="' + arrayItem.title + '"]').next().addClass('navitem'); return false; } $('.navbutton[navname="' + arrayItem.title + '"]').addClass('done navitem'); }); $("html, body").animate({ scrollTop: 0 }, "fast"); } } //**************************** // End of tabbedForm Function //****************************
What I did notice is that my Save as Draft button no longer works.
Can you tell me a little about what you're seeing when trying to Save as Draft?
Are there any javascript errors being reported?
It does nothing. When I click the button nothing happens. No errors.
I just threw this code in a new form to test with (Forms v10). Everything worked as expected so I have a few more troubleshooting questions for you.
1. Were you testing the functionality within a preview or from the live version of the form?
2. Did the start event for your form (on the Process Modeler screen) have the Save as Draft functionality enabled?
3. Did you have additional Javascript that you are using with your form?
John,
I just did some testing and found the error. I did modify your script a little and I think a script I created didn't mesh well. I fixed the error and it works perfectly now. I figured it had to be something on my end because I applied it to another form and it worked great. Thanks again.
Excellent. Glad to hear you got it sorted out. In looking at it for you, I also made a small update to the code above. It just makes it so the "Save as Draft" button only shows up if the functionality is enabled in the Business Process Modeler.
If you want to add it to your form, here's the details.
Replace
$('<input class="draft-btn" data-toggle="modal" onclick="return false;" data-target="#draftPage" value="Save as Draft" type="button">').appendTo($('.cf-section-block').has('h1:first:contains(' + arrayItem.title + ')').find('.buttons'));
with:
if ($('.btn-wrapper .draft-btn').val()) { $('<input class="draft-btn" data-toggle="modal" onclick="return false;" data-target="#draftPage" value="Save as Draft" type="button">').appendTo($('.cf-section-block').has('h1:first:contains(' + arrayItem.title + ')').find('.buttons')); }
Awesome!!!!!!!! You are awesome!