Forked from spivurno/gw-gravity-forms-dynamic-select.php
Created
May 2, 2021 16:13
-
-
Save Oliviercreativ/1f62ca7e4bf2048fc3d43fa5ee7f2ecf to your computer and use it in GitHub Desktop.
Gravity Wiz // Gravity Forms // Dynamic Select (for Categories, Taxonomies and more)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Gravity Wiz // Gravity Forms // Dynamic Category Select | |
* | |
* Allows the user to drill down from a top level category to a child category. | |
* | |
* @version 1.0 | |
* @author David Smith <[email protected]> | |
* @license GPL-2.0+ | |
* @link http://gravitywiz.com/.../ | |
*/ | |
class GW_Dynamic_Select { | |
protected static $script_output; | |
public function __construct( $args ) { | |
$this->_args = wp_parse_args( $args, array( | |
'form_id' => false, | |
'field_id' => false, | |
'taxonomy' => 'category', | |
'query_args' => array() | |
) ); | |
extract( $this->_args ); // we want $form_id, $field_id | |
add_filter( "gform_pre_render_{$form_id}", array( $this, 'populate_choices' ) ); | |
add_filter( "gform_admin_pre_render_{$form_id}", array( $this, 'populate_choices' ) ); | |
add_filter( "gform_pre_render_{$form_id}", array( $this, 'load_form_script') ); | |
add_filter( "gform_register_init_scripts_{$form_id}", array( $this, 'add_init_script') ); | |
add_filter( "wp_ajax_gwds_get_child_choices_{$form_id}_{$field_id}", array( $this, 'ajax_get_child_choices' ) ); | |
add_filter( "wp_ajax_nopriv_gwds_get_child_choices_{$form_id}_{$field_id}", array( $this, 'ajax_get_child_choices' ) ); | |
} | |
public function load_form_script( $form ) { | |
if( self::$script_output ) | |
return $form; | |
?> | |
<script type="text/javascript"> | |
var GWDynSelect; | |
(function($){ | |
GWDynSelect = function( args ) { | |
var self = this; | |
// copy all args to current object: formId, fieldId | |
for( prop in args ) { | |
if( args.hasOwnProperty( prop ) ) | |
self[prop] = args[prop]; | |
} | |
self.init = function() { | |
self.elem = $( '#input_' + self.formId + '_' + self.fieldId ); | |
self.elem.change( function() { | |
var value = $( this ).val(); | |
if( $.inArray( value, self.childlessTerms ) != -1 ) | |
return; | |
var spinner = $( '<img src="' + self.spinnerUrl + '" style="position:relative;top:3px;left:3px;box-shadow:0 0 0;" />' ).insertAfter( self.elem ); | |
$.post( self.ajaxUrl, { | |
value: value, | |
action: 'gwds_get_child_choices_' + self.formId + '_' + self.fieldId | |
}, function( response ) { | |
spinner.remove(); | |
var terms = $.parseJSON( response ), | |
optionsMarkup = ''; | |
for( var i = 0; i < terms.length; i++ ) { | |
var selected = terms[i].isSelected == true ? 'selected="selected"' : ''; | |
optionsMarkup += '<option ' + selected + ' value="' + terms[i].value + '">' + terms[i].text + '</option>'; | |
} | |
self.elem.html( optionsMarkup ); | |
// auto-open drop down after repop | |
// http://stackoverflow.com/questions/19652085/open-dropdown-list-from-javascript-function | |
var event = document.createEvent( 'MouseEvents' ); | |
event.initMouseEvent( 'mousedown', true, true, window ); | |
self.elem[0].dispatchEvent( event ); | |
} ); | |
} ); | |
} | |
self.init(); | |
} | |
})(jQuery); | |
</script> | |
<?php | |
self::$script_output = true; | |
return $form; | |
} | |
public function add_init_script( $form ) { | |
$args = array( | |
'formId' => $this->_args['form_id'], | |
'fieldId' => $this->_args['field_id'], | |
'ajaxUrl' => admin_url( 'admin-ajax.php' ), | |
'spinnerUrl' => GFCommon::get_base_url() . '/images/spinner.gif', | |
'childlessTerms' => $this->get_childless_terms() | |
); | |
$script = '; new GWDynSelect( ' . json_encode( $args ) . ' );'; | |
$slug = "gw_dynamic_select_{$this->_args['form_id']}_{$this->_args['field_id']}"; | |
GFFormDisplay::add_init_script( $this->_args['form_id'], $slug, GFFormDisplay::ON_PAGE_RENDER, $script ); | |
} | |
public function populate_choices( $form ) { | |
foreach( $form['fields'] as &$field ) { | |
if( ! $this->is_applicable_field( $field ) ) { | |
continue; | |
} | |
if( current_filter() == "gform_admin_pre_render_{$form['id']}" ) { | |
$entry_id = rgget( 'lid' ); | |
if( $entry_id ) { | |
$entry = GFAPI::get_entry( $entry_id ); | |
$selected_value = GFFormsModel::get_lead_field_value( $entry, $field ); | |
} else { | |
$selected_value = false; | |
} | |
} else { | |
$selected_value = GFFormsModel::get_field_value( $field ); | |
} | |
$field['choices'] = $this->get_terms_as_choices( $selected_value ); | |
} | |
return $form; | |
} | |
public function ajax_get_child_choices() { | |
$selected_value = rgpost( 'value' ); | |
$choices = $this->get_terms_as_choices( $selected_value ); | |
die( json_encode( $choices ) ); | |
} | |
public function is_applicable_field( $field ) { | |
return $field['id'] == $this->_args['field_id']; | |
} | |
public function get_terms_as_choices( $selected_value ) { | |
if( $selected_value ) { | |
$selected_term = get_term( $selected_value, $this->_args['taxonomy'] ); | |
if( $this->is_childless_term( $selected_term->term_id ) ) { | |
$parent_id = $selected_term->parent; | |
} else { | |
$parent_id = $selected_term->term_id; | |
} | |
} else { | |
$parent_id = 0; | |
} | |
$terms = get_terms( $this->_args['taxonomy'], array_merge( | |
array( 'parent' => $parent_id ), | |
$this->_args['query_args'] | |
) ); | |
$choices = array(); | |
if( $parent_id > 0 ) { | |
$choices[] = array( | |
'text' => '↩ ' . __( 'Back' ), | |
'value' => '_gwds_back' | |
); | |
} | |
$choices[] = array( | |
'text' => __( 'Select a category...' ), | |
'value' => '', | |
'isSelected' => true | |
); | |
foreach( $terms as $term ) { | |
$has_children = ! $this->is_childless_term( $term->term_id ); | |
$label = $term->name; | |
if( $has_children ) { | |
$label .= ' •'; | |
} | |
$choice = array( | |
'text' => $label, | |
'value' => $term->term_id, | |
'isSelected' => $term->term_id == $selected_value, | |
'hasChildren' => $has_children | |
); | |
$choices[] = $choice; | |
} | |
return $choices; | |
} | |
public function get_childless_terms() { | |
$childless_terms = GFCache::get( 'gwds_get_childless_terms' ); | |
if( $childless_terms !== false ) | |
return $childless_terms; | |
$terms = get_terms( $this->_args['taxonomy'], array_merge( | |
array(), | |
$this->_args['query_args'] | |
) ); | |
if( is_wp_error( $terms ) ) { | |
return array(); | |
} | |
$childless_terms = array(); | |
$parent_terms = array_unique( wp_list_pluck( $terms, 'parent' ) ); | |
foreach( $terms as $term ) { | |
if( ! in_array( $term->term_id, $parent_terms ) ) | |
$childless_terms[] = $term->term_id; | |
} | |
GFCache::set( 'gwds_get_childless_terms', $childless_terms ); | |
return $childless_terms; | |
} | |
public function is_childless_term( $term_id ) { | |
return in_array( $term_id, $this->get_childless_terms() ); | |
} | |
} | |
# Configuration | |
new GW_Dynamic_Select( array( | |
'form_id' => 548, | |
'field_id' => 2, | |
'taxonomy' => 'gdoc_category', | |
'query_args' => array( | |
'hide_empty' => false | |
) | |
) ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment