spivurno
2/21/2015 - 11:43 PM

Ounce of Talent // Gravity Forms // Bump Quantity Up Depending on Whether a Field is Checked

Ounce of Talent // Gravity Forms // Bump Quantity Up Depending on Whether a Field is Checked

<?php
/**
 * Ounce of Talent // Gravity Forms // Bump Quantity Up Depending on Whether a Field is Checked
 *
 * A brief description about this snippet and the functionality it provides. Might also include basic usage instructions if applicable.
 *
 * @version	  1.0
 * @author    David Smith <david@gravitywiz.com>
 * @license   GPL-2.0+
 * @link      http://gravitywiz.com/...
 */
class TT_GF_Quantity_Bump {

    protected static $is_script_output = false;

    public function __construct( $args = array() ) {

        // set our default arguments, parse against the provided arguments, and store for use throughout the class
        $this->_args = wp_parse_args( $args, array(
            'form_id'         => false,
	        'source_input_id' => false,
            'target_input_id' => false
        ) );

        // do version check in the init to make sure if GF is going to be loaded, it is already loaded
        add_action( 'init', array( $this, 'init' ) );

    }

    function init() {

        // make sure we're running the required minimum version of Gravity Forms
        if( ! property_exists( 'GFCommon', 'version' ) || ! version_compare( GFCommon::$version, '1.8', '>=' ) ) {
            return;
        }

        // time for hooks
        add_filter( 'gform_pre_render', array( $this, 'load_form_script' ) );
        add_filter( 'gform_register_init_scripts', array( $this, 'add_init_script' ) );

    }

    function load_form_script( $form ) {

        if( $this->is_applicable_form( $form ) && ! self::$is_script_output ) {
            $this->output_script();
        }

        return $form;
    }

    function output_script() {
        ?>

        <script type="text/javascript">

            ( function( $ ) {

                window.TTQuantityBump = function( args ) {

                    var self = this;

                    // copy all args to current object: (list expected props)
                    for( prop in args ) {
                        if( args.hasOwnProperty( prop ) )
                            self[prop] = args[prop];
                    }

                    self.init = function() {

	                    var sourceIdBits             = self.sourceInputId.split( '_' ),
		                    sourceInputGroupSelector = '#input_' + self.formId + '_' + sourceIdBits[2] + ' input[name="input_' + sourceIdBits[2] + '"]';

	                    $( document ).on( 'change', sourceInputGroupSelector, function() {
							self.bump();
	                    } );

                    };

	                self.bump = function() {

		                var $sourceInput  = $( self.sourceInputId ),
			                $targetInput  = $( self.targetInputId ),
			                isChecked     = $sourceInput.is( ':checked' ),
			                wasChecked    = $sourceInput.data( 'wasChecked' ),
			                hasChanged    = isChecked != wasChecked,
			                currentValue  = parseInt( $targetInput.val() ),
			                timeout       = null;

		                if( ! isChecked && ! wasChecked ) {
			                return;
		                } else if( ! hasChanged ) {
			                clearTimeout( timeout );
			                timeout = setTimeout( function() {
				               self.bump();
			                }, 100 );
			                return;
		                } else {
			                $sourceInput.data( 'wasChecked', isChecked );
		                }

		                if( ! currentValue || isNaN( currentValue ) || currentValue < 0 ) {
			                currentValue = 0;
		                }

		                var newValue = currentValue + ( $sourceInput.is( ':checked' ) && $sourceInput.is( ':visible' ) ? 1 : -1 );

		                if( newValue < 0 ) {
			                newValue = 0;
		                }

		                $targetInput.val( newValue );

	                };

                    self.init();

                }

            } )( jQuery );

        </script>

        <?php

        self::$is_script_output = true;

    }

    function add_init_script( $form ) {

        if( ! $this->is_applicable_form( $form ) ) {
            return;
        }

        $args = array(
            'formId'        => $this->_args['form_id'],
            'sourceInputId' => $this->_args['source_input_id'],
            'targetInputId' => $this->_args['target_input_id']
        );

        $script = 'new TTQuantityBump( ' . json_encode( $args ) . ' );';
        $slug   = implode( '_', array( 'tt_quantity_bump', $this->_args['form_id'], $this->_args['source_input_id'], $this->_args['target_input_id'] ) );

        GFFormDisplay::add_init_script( $this->_args['form_id'], $slug, GFFormDisplay::ON_PAGE_RENDER, $script );

    }

    function is_applicable_form( $form ) {

        $form_id = isset( $form['id'] ) ? $form['id'] : $form;

        return $form_id == $this->_args['form_id'];
    }

}

# Configuration

new TT_GF_Quantity_Bump( array(
	'form_id'         => 747,
	'source_input_id' => '#choice_747_10_0',
	'target_input_id' => '#ginput_quantity_747_7'
) );

new TT_GF_Quantity_Bump( array(
	'form_id'         => 747,
	'source_input_id' => '#choice_747_10_1',
	'target_input_id' => '#ginput_quantity_747_13'
) );

new TT_GF_Quantity_Bump( array(
	'form_id'         => 747,
	'source_input_id' => '#choice_747_12_0',
	'target_input_id' => '#ginput_quantity_747_7'
) );

new TT_GF_Quantity_Bump( array(
	'form_id'         => 747,
	'source_input_id' => '#choice_747_12_1',
	'target_input_id' => '#ginput_quantity_747_13'
) );