Skip to content

Instantly share code, notes, and snippets.

@creover
Created December 21, 2017 21:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save creover/e2fd7020e6734730ff00246bb2b139b6 to your computer and use it in GitHub Desktop.
Save creover/e2fd7020e6734730ff00246bb2b139b6 to your computer and use it in GitHub Desktop.
Allows for the use of Signature fields in Conditional Logic
<?php
/**
* Plugin Name: Gravity Forms Signature Conditional Logic
* Plugin URI: http://www.ryanprejean.com/
* Description: Allows for the use of Signature fields in Conditional Logic
* Version: 1.1.0
* Author: Ryan Prejean
* Author URI: http://www.ryanprejean.com/
* License: GPL2
*/
add_action( 'plugins_loaded', array( 'GFCLSignatureFields', 'init' ));
class GFCLSignatureFields {
static $script_output = false;
static $applicable_fields = array();
public static function init() {
$class = __CLASS__;
new $class;
}
function __construct() {
// make sure we're running the required minimum version of Gravity Forms
if( ! property_exists( 'GFCommon', 'version' ) || ! version_compare( GFCommon::$version, '2.1.1', '>=' ) || ! class_exists( 'GFSignature' ) ) {
return;
}
// handles evaluating signature-based conditional logic
add_filter( 'gform_is_value_match', array( $this, 'is_value_match' ), 10, 6 );
add_filter( 'gform_admin_pre_render', array( $this, 'enqueue_admin_inline_scripts' ) );
add_filter( 'gform_pre_render', array( $this, 'enqueue_inline_script' ), 10, 2 );
add_filter( 'gform_field_css_class', array( $this, 'gfconfig_add_class'), 10, 3 );
add_action( 'gform_register_init_scripts', array( $this, 'add_logic_event_to_input' ) );
}
public function enqueue_admin_inline_scripts( $form ) {
add_filter( 'admin_footer', array( $this, 'allow_signature_fields_in_field_select' ) );
return $form;
}
/**
* Allow Signature fields to be selected in the field select for conditional logic UI.
*
* @param mixed $form
*/
function allow_signature_fields_in_field_select() {
?>
<script type="text/javascript">
if( window.gform ) {
// allow Signature fields in conditional logic field select
gform.addFilter( 'gform_is_conditional_logic_field', function( isConditionalLogicField, field ) {
// if GF already considers this a conditional field OR if the field type is 'signatue'
return isConditionalLogicField || GetInputType( field ) == 'signature';
} );
gform.addFilter('gform_conditional_logic_operators', function (operators, objectType, fieldId) {
targetField = GetFieldById(fieldId);
if (targetField && targetField['type'] == 'signature') {
operators = {"is":"is", "isnot":"isNot"};
}
return operators;
});
gform.addFilter('gform_conditional_logic_values_input', function (str, objectType, ruleIndex, selectedFieldId, selectedValue) {
targetField = GetFieldById(selectedFieldId);
if (targetField && targetField['type'] == 'signature') {
var dropdownId = objectType + '_rule_value_' + ruleIndex;
str = "<input type='text' readonly='readonly' placeholder='Signed' class='gfield_rule_select' id='" + dropdownId + "' name='" + dropdownId + "' value='Signed' onchange='SetRuleProperty(\"" + objectType + "\", " + ruleIndex + ", \"value\", jQuery(this).val());' onkeyup='SetRuleProperty(\"" + objectType + "\", " + ruleIndex + ", \"value\", jQuery(this).val());'>";
}
return str;
});
}
</script>
<?php
}
/**
* Add the click event that triggers the conditional logic check when the value of the signature field is changed.
*
* @param mixed $form
*/
function add_logic_event_to_input( $form ) {
$applicable_fields = self::get_applicable_signature_fields( $form );
if( empty( $applicable_fields ) )
return $form;
$logic_operaters = array();
// loop through fields and add applicable signature fields to array
foreach( $applicable_fields as &$field ) {
$field_id = 'field_' . $field['formId'] . '_' . $field['id'];
$logic_operaters[$field_id] = $field["conditionalLogicFields"];
}
ob_start();
?>
window['logic_operators'] = <?php echo json_encode($logic_operaters) ?>;
( function( $ ) {
var logic_operators = window['logic_operators'],
$inputs = $( ".gfcls-field" );
$inputs.click( function() {
var currentfieldID = $(this).attr('id');
gf_apply_rules(<?php echo $form['id']; ?>, logic_operators[currentfieldID]);
});
} )( jQuery );
jQuery(document).bind('gform_post_render', function(event, form_id, current_page){
var logic_operators = window['logic_operators'];
$( ".gfcls-field" ).each(function() {
var currentfieldID = $(this).attr('id');
gf_apply_rules(form_id, logic_operators[currentfieldID]);
});
});
<?php
$script = ob_get_clean();
GFFormDisplay::add_init_script( $form['id'], 'gform_signature_logic', GFFormDisplay::ON_PAGE_RENDER, $script );
}
/**
* Modify the front-end form object by:
* Adding the 'gfcls-field' class to all signature fields upon which conditional logic is dependent
*
* @param mixed $form
*/
function gfconfig_add_class( $classes, $field, $form ) {
$applicable_fields = self::get_applicable_signature_fields( $form );
if( empty( $applicable_fields ) )
return $classes;
$applicable_field_ids = wp_list_pluck( $applicable_fields, 'id' );
if( in_array( $field['id'], $applicable_field_ids ) )
$classes .= ' gfcls-field';
return $classes;
}
function enqueue_inline_script( $form ) {
if( ! self::has_applicable_signature_fields( $form ) || has_filter( 'wp_footer', array( $this, 'output_inline_script' ) ) ) {
return $form;
}
add_filter( 'wp_footer', array( $this, 'output_inline_script' ), 99 );
add_filter( 'gform_preview_footer', array( $this, 'output_inline_script' ) );
return $form;
}
function output_inline_script() {
?>
<script type="text/javascript">
gform.addFilter( 'gform_is_value_match', 'gcldfIsValueMatch' );
function gcldfIsValueMatch( isMatch, formId, rule ) {
var sourceField = jQuery('#input_' + formId + '_' + rule.fieldId + '_data'),
image = jQuery('#input_' + formId + '_' + rule.fieldId + '_signature_filename');
if( ! sourceField.parents( 'li.gfield' ).hasClass( 'gfcls-field' ) ) {
return isMatch;
}
var ruleValue = 'Signed',
fieldValue = sourceField.val() || image.val() ? 'Signed' : 'Unsigned';
// must be strings for GF
isMatch = gf_matches_operation( fieldValue , ruleValue, rule.operator );
return isMatch;
}
</script>
<?php
}
function is_value_match( $is_match, $field_value, $target_value, $operation, $source_field, $rule ) {
if( GFFormsModel::get_input_type( $source_field ) != 'signature' ) {
return $is_match;
}
$id = $source_field['id'];
$form_id = $source_field['formId'];
$field_id = 'input_' . $form_id . "_$id";
$signature_filename = ! empty( $field_value ) ? $field_value : rgpost( "{$field_id}_signature_filename" );
$value = ! empty( $signature_filename ) ? 'Signed' : 'Unsigned';
$is_match = GFFormsModel::matches_operation( $value, $target_value, $operation);
return $is_match;
}
// HELPERS
/**
* Search through each fields conditional logic and look for signature fields.
*
* @param mixed $form
*/
public static function get_applicable_signature_fields( $form ) {
$form_id = is_array( $form ) ? $form['id'] : $form;
if( isset( self::$applicable_fields[$form_id] ) )
return self::$applicable_fields[$form_id];
if( ! is_array( $form ) )
$form = GFFormsModel::get_form_meta( $form_id );
self::$applicable_fields[$form_id] = self::get_applicable_fields_recursive( $form );
return self::$applicable_fields[$form_id];
}
public static function get_applicable_fields_recursive( $object, $form = false, $applicable_fields = array() ) {
// if no $form is provided, assume that the $object is the form object
if( ! $form )
$form = $object;
foreach( $object as $prop => $value ) {
if( $prop && $prop == 'conditionalLogic' && ! empty( $value ) ) {
foreach( $object[$prop]['rules'] as $rule ) {
$ruleField = RGFormsModel::get_field( $form, $rule['fieldId'] );
if( GFFormsModel::get_input_type( $ruleField ) == 'signature' ) {
$applicable_fields[] = $ruleField;
}
}
} else if( is_array( $value ) || is_a( $value, 'GF_Field' ) ) {
$applicable_fields = self::get_applicable_fields_recursive( $value, $form, $applicable_fields );
}
}
return $applicable_fields;
}
public static function has_applicable_signature_fields( $form ) {
$applicable_fields = self::get_applicable_signature_fields( $form );
return !empty( $applicable_fields );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment