You are viewing limited content. For full access, please sign in.

Question

Question

Required fields error message

asked on March 23, 2016

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.

1 0

Answer

SELECTED ANSWER
replied on March 24, 2016 Show version history

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
//****************************

 

1 0
replied on March 28, 2016

What I did notice is that my Save as Draft button no longer works.

0 0
replied on March 28, 2016

Can you tell me a little about what you're seeing when trying to Save as Draft?

Are there any javascript errors being reported?

0 0
replied on March 28, 2016

It does nothing. When I click the button nothing happens. No errors.

0 0
replied on March 28, 2016

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?

1 0
replied on March 28, 2016

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. 

0 0
replied on March 28, 2016

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'));
    }

 

1 0
replied on March 28, 2016

Awesome!!!!!!!! You are awesome!

0 0

Replies

You are not allowed to reply in this post.
You are not allowed to follow up in this post.

Sign in to reply to this post.