Gravity Forms – Sticky List Multi-Page view solution

While investigating the Gravity Forms plugin for WordPress I installed a great little plugin called Gravity Forms Sticky List. Sticky List is an add-on for the WordPress plugin Gravity Forms that lets you list and edit entries from the front end.

The one thing that I really needed from Sticky List was the ability for users to view multi-page forms but I don’t always want these forms to be editable. Unfortunately this is still a function that the plugin author has planned for a future release. Editing the form works fine in Sticky List but read-only functionality is at present only partially implemented. At present you are only able to view the first page of the form and cannot navigate to subsequent pages.

Since there was no indication of when this functionality would be available I decide to see if I could implement it myself.  Below you will find my solution:

Functionality

  • Allows read-only navigation through all pages in a multi-page form
  • Updates the forms Progress Indicator if set to Progress Bar (See Note below)
  • Updates the classes used by the forms steps if Progress Indicator if set to Steps
  • Hides the datePicker icon beside date fields in both single and multi-page forms when in View mode.

NOTE:  When the Sticky List Progress Indicator option is set to show a Progress Bar, Gravity forms only writes the first page title to the page, so we can’t access other values as we navigate. This meant that I had to remove the name of the step from the Progress Bar title. I’m sure their will be a GF hook available that will allow this to be added back in but it’s not a priority for me.

Installation

There are 2 steps to the installation of this fix

  1. Add a single line of code to the file in gravity-forms-sticky-list/class-sticky-list.php (Note: This file will be overwritten if  you update the Sticky List plugin so you will need to re-do this step).
  2. Copy and paste my fix code into your child themes javascript file. (Note: It is important that your child theme is set to enqueue this script in the page footer to ensure that the Sticky List plugin is already loaded.)

Step 1

Find the following section of code in gravity-forms-sticky-list/class-sticky-list.php (line numbers are approximates)

<?php }

 if($_POST["mode"] == "view") { ?>
   $("#gform_<?php echo $form_id;?> :input").attr("disabled", true);
   $("#gform_submit_button_<?php echo $form_id;?>").css('display', 'none');
 
 <?php }

Insert the following code after the 3rd line of this code block

//Added hidden value for Multi-Page fix
thisForm.append('<input type="hidden" name="mode" value="view" />');

Your code should now look like this:

 
<?php }

 if($_POST["mode"] == "view") { ?>
   $("#gform_<?php echo $form_id;?> :input").attr("disabled", true);
   $("#gform_submit_button_<?php echo $form_id;?>").css('display', 'none');
   //Added hidden value for Multi-Page fix
   thisForm.append('<input type="hidden" name="mode" value="view" />');
 
 <?php } 

Step 2

Copy the following code into your Child Theme’s javascript file

jQuery(document).ready(function($) {
  function hideDatePicker(){
    // Hide any datepicker icons
    if($('.ginput_container_date input').length){
      $('.ginput_container_date input').datepicker({
         beforeShow: function(input) {
          return false;
        }
      });
    }
  }

  function updateProgressBar(page_no, pageCount){
    //Update % progress and Step x of y title
    var percent = Math.round((page_no / pageCount * 100)) + '%';

    $('.gf_progressbar_percentage').css('width', percent);
    $('div.gf_progressbar_percentage > span').html(percent);
    $('.gf_progressbar_title').html('Step ' + page_no + ' of ' + pageCount);
  }

  function updateSteps(page_no, pageCount, direction){
    // add/ remove classes to progress steps
    var current_step_el =  $("div.gf_page_steps .gf_step_active");

    if(direction == 'next'){
      $(current_step_el).prev().removeClass( "gf_step_previous" );
      $(current_step_el).removeClass( "gf_step_active" ).addClass( "gf_step_completed gf_step_previous" );
      $(current_step_el).next().removeClass( "gf_step_next gf_step_pending" ).addClass( "gf_step_active" );
      if((current_step_el).nextAll().eq(1).hasClass("gf_step")){
        $(current_step_el).nextAll().eq(1).addClass( "gf_step_next" );
      }
    }
    else{
      if((current_step_el).prevAll().eq(1).hasClass("gf_step")){
        $(current_step_el).prevAll().eq(1).addClass( "gf_step_previous" );
      }
      $(current_step_el).prev().removeClass( "gf_step_completed gf_step_previous" ).addClass( "gf_step_active" );
      $(current_step_el).removeClass( "gf_step_active gf_step_completed" ).addClass( "gf_step_next gf_step_pending" );
      $(current_step_el).next().removeClass( "gf_step_next" );
    }
  }

  function sl_pagination() {
    // Get the mode - Tells us if we're on the Sticky List view or edit page
    // NOTE: This will only work if the hidden field (name=mode) is added to -
    //       the form in classs-sticky-list.php

    var mode = $('input[name=mode]').val();
    if(mode == 'view'){

      // Hide icons beside any datepickers in both single and multi page forms
      hideDatePicker();

      // Get the number of pages in multi-page form - length is 0 for single page
      var num_pages = $('.gform_page').length;

      if(num_pages > 0){
        //Remove un-wanted attributes from buttons
        $('.gform_next_button').removeAttr('disabled');
        $('.gform_next_button').removeAttr('onclick');

        $('.gform_previous_button').removeAttr('disabled');
        $('.gform_previous_button').removeAttr('onclick');
        // Final previous button has type submit, change it to ordinary button
        $('.gform_previous_button').attr('type', 'button');

         // Initialise the Step Title under progress bar
        if($('.gf_progressbar_title').length){
          /*
          NOTE: Need to remove name of step from title. When displaying progress bar
                Gravity forms only writes first page title to page, so can't access
                other values as we navigate.
                I'm sure their will be a GF hook available but it's not a priority for me.
           */
          $('.gf_progressbar_title').html('Step 1 of ' + num_pages);
        }

        //Loop through each page element
        $.each($('.gform_page'),function(i,val){
          /*
          Add new attribute: 'current_page'to element so we can update
          progress bar/steps as we track back and forward through pages
          */
          $(this).attr('page_no', i+1);

          //Get previous and next elements of current page
          var next_page = $(this).next();
          var next_button = $(this).find('.gform_next_button');
          var prev_page = $(this).prev();
          var prev_button = $(this).find('.gform_previous_button');

          //Keep a referenece to current page
          var this_page = this;
          //Hide and display pages as appropriate
          $(next_button).click(function() {
            $(next_page).css('display', 'block');
            $(this_page).css('display', 'none');
            //Update our progress
            next_page_no = $(next_page).attr('page_no');
            if ($(".gf_progressbar").length){
              updateProgressBar(next_page_no, num_pages);
            }
            else if ($(".gf_page_steps").length){
              updateSteps(next_page_no, num_pages, 'next');
            }
          });

          $(prev_button).click(function() {
            $(prev_page).css('display', 'block');
            $(this_page).css('display', 'none');
            //Update our progress
            next_page_no = $(prev_page).attr('page_no');
            if ($(".gf_progressbar").length){
              updateProgressBar(next_page_no, num_pages);
            }
            else if ($(".gf_page_steps").length){
              updateSteps(next_page_no, num_pages, 'prev');
            }
          });
        });
      }
    }
  };
  sl_pagination();
});

Feedback

It would be great to know how you get on. Please post a comment here or in my reply to this post in the WordPress support page for the Sticky List plugin.

Posted in Further Development, My Website development, Plugins and tagged , , .

Leave a Reply

Your email address will not be published. Required fields are marked *