Skip to content

Instantly share code, notes, and snippets.

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 Oliviercreativ/1f62ca7e4bf2048fc3d43fa5ee7f2ecf to your computer and use it in GitHub Desktop.
Save Oliviercreativ/1f62ca7e4bf2048fc3d43fa5ee7f2ecf to your computer and use it in GitHub Desktop.
Gravity Wiz // Gravity Forms // Dynamic Select (for Categories, Taxonomies and more)
<?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 <david@gravitywiz.com>
* @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' => '&#8617; ' . __( '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 .= ' &bull;';
}
$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