Append data-attributes to dropdown options

Hello all,

I have a dropdown that’s being populated with custom post type data, base on a variation of this code: https://docs.gravityforms.com/dynamically-populating-drop-down-or-radio-buttons-fields/

In our particular case this would result in a dropdown with 1000+ options so we’d ideally be able to provide the user with the ability to search within the dropdown via the “enhanced user interface” option in the field settings.

The issue I’m running into is that I cannot figure out how to attach addition information to each dropdown option, which we want to use to copy data to relevant fields after the user has made a selection.

Anyway, to be specific in this section of the snippet I’m wondering how I can define data attributes?

$choices[] = array(
    'text' => $post->post_title,
    'value' => $post->ID
);

Thank you in advance!

You can include the extra data using a custom key in the choice array. That will make it available to the methods used to generate field markup. You would then use the gform_field_choice_markup_pre_render filter to access that custom key and add the data attribute to the choice markup.

1 Like

Hi Corey,

This is also possible with our GP Populate Anything Perk. You can use Populate Anything to populate the choices of the dropdown field with the custom post type data and then use the field value object feature to populate the other relevant fields with the additional information of the selected dropdown option.

Best,

2 Likes

Hi Richard,

Thanks for your reply - I think this is the route I’ll want to take but I’m afraid I’m not fully understanding how to implement this.

If I understand correctly I can modify my $choices array like so:

$choices[] = array(
    'text' => $post->post_title . ' (' . get_post_meta( $id, 'wpsl_city', true ) . ', ' . get_post_meta( $id, 'wpsl_state', true ) . ')',
    'value' => $id,
    'data-number' => get_post_meta( $id, 'wpsl_number', true ),
    'data-city' => get_post_meta( $id, 'wpsl_city', true ),
    'data-state' => get_post_meta( $id, 'wpsl_state', true ),
    'data-country' => get_post_meta( $id, 'wpsl_country', true ),
    'data-zip' => get_post_meta( $id, 'wpsl_zip', true )
);

The text and value properties do display as intended and, assuming the data attributes are available, I need to figure out how to append them to each <option> element. Like so:

<option value="x" data-number="x" data-city="x" data-state="x" data-country="x" data-zip="x">x</option>

From here, I’ll use JavaScript to watch for user selection and then grab the values from the data attributes and copy them to their relevant fields.

How can I use the gform_field_choice_markup_pre_render filter to accomplish this? The documentation seems to assume you only want to modify one specific item, rather than all of them.

Thank you for bearing with me while I sort this out, it is much appreciated.

Hi Samuel,

Thank you for your recommendation. This may end up being what we choose to go forward with in the next phase, as we wrestle with some long-term plugin constraints.

Richard,

Prior to my last reply I had accidentally added a syntax error, so I apologize for the confusion. I am correctly able to modify the output for each option now, though I am still having trouble getting my custom data attributes to come through. I’ll just go ahead and paste in the full snippets to give you the full context.

add_filter( 'gform_pre_render_21_1', 'populate_posts' );
add_filter( 'gform_pre_validation_21_1', 'populate_posts' );
add_filter( 'gform_pre_submission_filter_21_1', 'populate_posts' );
add_filter( 'gform_admin_pre_render_21_1', 'populate_posts' );

function populate_posts( $form ) {
    foreach ( $form['fields'] as $field ) {
        if ( $field->type != 'select' || strpos( $field->cssClass, 'populate-posts' ) === false ) {
            continue;
        }

        $choices = array();
        
        $posts = get_posts( array(
            'post_type' => 'wpsl_stores',
            'order' => 'ASC',
            'numberposts' => '-1',
            'post_status' => 'publish',
        ) );

        foreach ( $posts as $post ) {
            $id = $post->ID;

            $choices[] = array(
                'text' => $post->post_title . ' (' . get_post_meta( $id, 'wpsl_city', true ) . ', ' . get_post_meta( $id, 'wpsl_state', true ) . ')',
                'value' => $id,
                'data-number' => get_post_meta( $id, 'wpsl_number', true ),
                'data-city' => get_post_meta( $id, 'wpsl_city', true ),
                'data-state' => get_post_meta( $id, 'wpsl_state', true ),
                'data-country' => get_post_meta( $id, 'wpsl_country', true ),
                'data-zip' => get_post_meta( $id, 'wpsl_zip', true )
            );
        }

        $field->placeholder = 'Choose one...';
        $field->choices = $choices;
    }

    return $form;
}

add_filter( 'gform_field_choice_markup_pre_render_21_1', function ( $choice_markup, $choice, $field, $value ) {
    if ( $field->get_input_type() == 'select' ) {
        $text = $choice['text'];
        $value = $choice['value'];
        $number = array_key_exists( 'data-number', $choice ) ? $choice['data-number'] : '';
        $city = array_key_exists( 'data-city', $choice ) ? $choice['data-city'] : '';
        $state = array_key_exists( 'data-state', $choice ) ? $choice['data-state'] : '';
        $country = array_key_exists( 'data-country', $choice ) ? $choice['data-country'] : '';
        $zip = array_key_exists( 'data-zip', $choice ) ? $choice['data-zip'] : '';

        $choice_markup = '<option value="' . $value . '" data-number="' . $number . '" data-city="' . $city . '" data-state="' . $state . '" data-country="' . $country . '" data-zip="' . $zip . '">' . $text . '</option>';
    }
  
    return $choice_markup;
}, 10, 4 );

These first four filters can’t be set at the level of field-specificity – only per form. You’ll need to remove the _1 from each filter name.

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.