WordPress custom post type save radio input meta

I have created a custom post type within a wordpress plugin. Within the custom post type, is some custom metaboxes – in my custom metaboxes I have a radio input.

The issue I am having is saving the choice of this radio input to the database. Whenever I hit save, it forget the selection.

Read More

Here is my code for my metaboxes:

function render_meta_boxes( $post ) {

    $meta = get_post_custom( $post->ID );
    $name = ! isset( $meta['singer_name'][0] ) ? '' : $meta['singer_name'][0];
    $tagline = ! isset( $meta['singer_tagline'][0] ) ? '' : $meta['singer_tagline'][0];
    $bio = ! isset( $meta['singer_bio'][0] ) ? '' : $meta['singer_bio'][0];
    $gender = ! isset( $meta['singer_gender'][0] ) ? '' : $meta['singer_gender'][0];

    wp_nonce_field( basename( __FILE__ ), 'singer_profile' ); 
?>

    <table class="form-table">

        <tr>
            <td class="singers_meta_box_td" colspan="2">
                <label for="singer_name"><?php _e( 'Singer Name', 'singers_post_type' ); ?>
                </label>
            </td>
            <td colspan="4">
                <input type="text" name="singer_name" class="regular-text" value="<?php echo $name; ?>">
            </td>
        </tr>

        <tr>
            <td class="singers_meta_box_td" colspan="2">
                <label for="singer_tagline"><?php _e( 'Singer Tagline', 'singers_post_type' ); ?>
                </label>
            </td>
            <td colspan="4">
                <input type="text" name="singer_tagline" class="regular-text" value="<?php echo $tagline; ?>">
            </td>
        </tr>

        <tr>
            <td class="singers_meta_box_td" colspan="2">
                <label for="singer_bio"><?php _e( 'Singer Bio', 'singers_post_type' ); ?>
                </label>
            </td>
            <td colspan="4">
                <textarea rows="10" style="width:25em;" name="singer_bio" class="regular-text"><?php echo $bio; ?></textarea>
            </td>
        </tr>

        <tr>
            <td class="singers_meta_box_td" colspan="2">
                <label for="singer_gender"><?php _e( 'Gender', 'singers_post_type' ); ?>
                </label>
            </td>
            <td colspan="4">
                <input type="radio" name="singer_gender" value="male"> Male<br>
                <input type="radio" name="singer_gender" value="female"> Female
            </td>
        </tr>

    </table>

<?php }

/**
* Save metaboxes
*
* @since 0.1.0
*/
function save_meta_boxes( $post_id ) {

    global $post;

    // Verify nonce
    if ( !isset( $_POST['singer_profile'] ) || !wp_verify_nonce( $_POST['singer_profile'], basename(__FILE__) ) ) {
        return $post_id;
    }

    // Check Autosave
    if ( (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) || ( defined('DOING_AJAX') && DOING_AJAX) || isset($_REQUEST['bulk_edit']) ) {
        return $post_id;
    }

    // Don't save if only a revision
    if ( isset( $post->post_type ) && $post->post_type == 'revision' ) {
        return $post_id;
    }

    // Check permissions
    if ( !current_user_can( 'edit_post', $post->ID ) ) {
        return $post_id;
    }

    $meta['singer_name'] = ( isset( $_POST['singer_name'] ) ? esc_textarea( $_POST['singer_name'] ) : '' );

    $meta['singer_bio'] = ( isset( $_POST['singer_bio'] ) ? esc_textarea( $_POST['singer_bio'] ) : '' );

    $meta['singer_tagline'] = ( isset( $_POST['singer_tagline'] ) ? esc_textarea( $_POST['singer_tagline'] ) : '' );

    $meta['singer_gender'] = ( isset( $_POST['singer_gender'] ) ? sanitize_html_class( $_POST['singer_gender'] ) : '' );

    foreach ( $meta as $key => $value ) {
        update_post_meta( $post->ID, $key, $value );
    }
}

You can see the radio inputs are just male and female options, and then at the bottom of the script is where the saving is handled. I can’t figure out how to make the choice save though.

Related posts

1 comment

  1. Ok, so first of all you didn’t add

    add_action('save_post', 'save_meta_boxes');
    

    But I’m assuming you have that, since other options (by your account) should be saved.

    Next I’d write my variables in the metabox like this:

    $meta = get_post_custom( $post->ID );
    $name = (isset($meta['singer_name'][0]) && $meta['singer_name'][0] != '') ? $meta['singer_name'][0] : '';
    $tagline = (isset($meta['singer_tagline'][0]) && $meta['singer_tagline'][0] != '') ? $meta['singer_tagline'][0] : '';
    $bio = (isset($meta['singer_bio'][0]) && $meta['singer_bio'][0] != '') ? $meta['singer_bio'][0] : '';
    $gender = (isset($meta['singer_gender'][0]) && $meta['singer_gender'][0] != '') ? $meta['singer_gender'][0] : '';
    

    I find it to be more foolproof.

    What you need is a value to pull from the database to see if your radio option (and the same thing goes for checkbox) is selected/checked. So inside your render_meta_boxes() function, after the post custom variables add:

    $value = get_post_meta( $post->ID, 'gender-select', true );
    

    Now your radio inputs must look like

    <td colspan="4">
        <input type="radio" name="singer_gender" value="male" <?php checked( $value, 'male' ); ?>> Male<br>
        <input type="radio" name="singer_gender" value="female" <?php checked( $value, 'female' ); ?>> Female
    </td>
    

    Here you’ll check if the value in the post meta is male or female, and according to that you’ll have that radio button checked.

    Last but not the least, your save function should have a $post as an argument, not $post_id:

    function save_meta_boxes( $post ) {
    
        global $post;
        $post_id = $post->ID;
        ...
    }
    

    You should remove the $meta['singer_gender'] from the save box since that does nothing. Instead use:

    $gender_meta_value = ( isset( $_POST['singer_gender'] ) ? sanitize_html_class( $_POST['singer_gender'] ) : '' );
    update_post_meta( $post_id, 'gender-select', $gender_meta_value );
    

    Your gender-select is the value in the post meta that will be later pulled in the $value variable from which you’ll preform the check.

    And that’s it

Comments are closed.