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

Question

Question

Prevent user clicking next tab

asked on October 11, 2022

Further to this post -

Hide Next Button in Pagination Until Required Fields are Completed - Laserfiche Answers

I am trying to prevent a user from being able to click on the next tab until all fields are validated.

I can hide all the tabs, but would prefer to disable them.

0 0

Answer

SELECTED ANSWER
replied on October 11, 2022 Show version history

This is a bit messier than I would normally like, but there weren't many options since the tabs are not input elements that can just be disabled.

Instead, I wrote a couple of scripts that clone all the nav elements into hidden contains and strips the default handlers off the originals.

A new handler is added to the elements, which validates the active page, and if the page is valid, it will trigger a click event on the hidden clone.

The page validation script leverages the parsley validation already built into Forms, so no extra checks/messages are needed.

$(document).ready(function(){
  // create container for cloned nav tabs
  let container = $('<div style="display:none !important;"></div>');
  
  // pagination tabs
  $('.cf-pagination-tabs li').each(function(){
    // clone tab to hidden container
    var c = $(this).clone(true, true);
    container.append(c);
    
    // remove/replace event handlers
    $(this).off().on('click',function(){
      // get results of page validation
      if (pageValid()) {
        $(c).click(); // trigger click on hidden tab
        if ($(this).is('li')) $(this).addClass('active'); // make tab active
      }
    });
  });
  $('.cf-pagination-tabs').parent().append(container);
  
  // navigation buttons
  $('.cf-pagination-btn').each(function(){
    // create container for nav buttons
    var box = $('<div style="display:none !important;"></div>');
    
    $(this).find('input').each(function(){
      // clone button to hidden container
      var c = $(this).clone(true,true);
      box.append(c);
      
      // remove/replace event handlers
      $(this).off().on('click',function(e){
        if (pageValid()) $(c).click(); // trigger click on hidden btn
      });
    });
    
    $(this).append(box);
  });
  
});

// page validation function
function pageValid(){
  var valid = true; // default output
  
  // validate fields on active page
  $('.cf-page.active :input:not([readonly]):visible').each(function(){
    // show validation errors
    $(this).parsley().validate();
    
    // change output for invalid field if none detected
    if (valid && !$(this).parsley().isValid()) {
      $(this).focus(); // focus on first error
      valid = false; // flag error
    }
  });

  return valid;
}

Everything seemed to work as expected on my end.

1 0

Replies

replied on October 11, 2022 Show version history

In the next release of self-hosted Forms, the new form designer supports using field rule to hide the page tab and disable the next button. It does not support to disable the tab as the field rules to disable page will disable all the fields on the page instead of disable the page tab. 

1 0
replied on October 11, 2022

Which version of Forms are you using, and which form designer?

0 0
replied on October 11, 2022

Version 11 Classic Designer. 

0 0
SELECTED ANSWER
replied on October 11, 2022 Show version history

This is a bit messier than I would normally like, but there weren't many options since the tabs are not input elements that can just be disabled.

Instead, I wrote a couple of scripts that clone all the nav elements into hidden contains and strips the default handlers off the originals.

A new handler is added to the elements, which validates the active page, and if the page is valid, it will trigger a click event on the hidden clone.

The page validation script leverages the parsley validation already built into Forms, so no extra checks/messages are needed.

$(document).ready(function(){
  // create container for cloned nav tabs
  let container = $('<div style="display:none !important;"></div>');
  
  // pagination tabs
  $('.cf-pagination-tabs li').each(function(){
    // clone tab to hidden container
    var c = $(this).clone(true, true);
    container.append(c);
    
    // remove/replace event handlers
    $(this).off().on('click',function(){
      // get results of page validation
      if (pageValid()) {
        $(c).click(); // trigger click on hidden tab
        if ($(this).is('li')) $(this).addClass('active'); // make tab active
      }
    });
  });
  $('.cf-pagination-tabs').parent().append(container);
  
  // navigation buttons
  $('.cf-pagination-btn').each(function(){
    // create container for nav buttons
    var box = $('<div style="display:none !important;"></div>');
    
    $(this).find('input').each(function(){
      // clone button to hidden container
      var c = $(this).clone(true,true);
      box.append(c);
      
      // remove/replace event handlers
      $(this).off().on('click',function(e){
        if (pageValid()) $(c).click(); // trigger click on hidden btn
      });
    });
    
    $(this).append(box);
  });
  
});

// page validation function
function pageValid(){
  var valid = true; // default output
  
  // validate fields on active page
  $('.cf-page.active :input:not([readonly]):visible').each(function(){
    // show validation errors
    $(this).parsley().validate();
    
    // change output for invalid field if none detected
    if (valid && !$(this).parsley().isValid()) {
      $(this).focus(); // focus on first error
      valid = false; // flag error
    }
  });

  return valid;
}

Everything seemed to work as expected on my end.

1 0
replied on October 12, 2022

You are awesome, Jason. That works great. 

Another JavaScript to add to my bank of scripts.

Thanks!

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

Sign in to reply to this post.