Listing Pages With Checkboxes In a Metabox (and saving them)

Here is what I’m basically trying to accomplish:

  1. I have a custom post type called ‘quotes’
  2. I have a number of wordpress pages

What I am trying to do is this: each time when I create a new “QUOTES” post, I want to be able to choose on which page this quotes post is supposed to go. I’ve decided to do this by creating a new metabox on the “quotes” post page and listing in that metabox all the pages, with a checkbox in front of them:

pages listing metabox screenshot

All fine and well, but now I don’t know how to save these checkboxes.

Here is the function I use to print the content of the metabox:

function myplugin_inner_custom_box( $post ) {
    $custom = get_post_custom($post->ID);
    $checkfield = $custom["checkfield"][0];

    // Nonce to verify intention later
    wp_nonce_field( 'save_quote_meta', 'custom_nonce' ); 
    $pages = get_pages(); 

    foreach ( $pages as $page ) { ?>   
        <input type="checkbox" name="checkfield_<?php echo $page->ID; ?>" value="yes" <?php if ($checkfield == 'yes') { ?> checked <?php } ?> /> <?php echo $page->post_title; ?> <br>   
    <?php 
    } 
}

And here is the function I use to save them:

//save the meta box action
add_action( 'save_post', 'myplugin_meta_save' );

//save the meta box
function myplugin_meta_save()
{
    global $post;
    update_post_meta($post->ID, 'checkfield', $_POST['checkfield'] );
}

Obviously this doesn’t work – I am not sure how to save all those checkfields values.

1 Answer
1

You are using checkfield_<?php echo $page->ID; ?> as name for your input fields, then trying to save $_POST['checkfield'] which is not set.

You can do the same $pages loop on the myplugin_meta_save() function and then save the data for each page as separate meta_key input (checkfield_1, checkfield_5, etc), OR you can save all that data in a single meta_key which is checkfield in this case, and a little tweak to your code is needed to achieve that:

function myplugin_inner_custom_box( $post ) {
    // we store data as an array, we need to unserialize it
    $checkfield = maybe_unserialize( get_post_meta($post->ID, "checkfield", true) );

    // Nonce to verify intention later
    wp_nonce_field( 'save_quote_meta', 'custom_nonce' ); 

    $pages = get_pages(); 
    foreach ( $pages as $page ) { ?>
        <input id="page_<?php echo $page->ID; ?>" type="checkbox" name="checkfield[]" value="<?php echo $page->ID; ?>" <?php if ( in_array($page->ID, (array) $checkfield) ) { ?> checked <?php } ?>/> <label for="page_<?php echo $page->ID; ?>"><?php echo $page->post_title; ?></label> <br>
<?php 
    } 
}
//save the meta box action
add_action( 'save_post', 'myplugin_meta_save', 10, 2 );

//save the meta box
function myplugin_meta_save($post_id, $post)
{   
    if ( isset($_POST['checkfield']) ) { // if we get new data

        update_post_meta($post_id, "checkfield", $_POST['checkfield'] );

    }
}

Note that name="checkfield" in the input field is replaced with name="checkfield[]" which will make data stored as an array in $_POST['checkfield'] variable. Also the value attribute is changed from yes to $page->ID.

Update: Cast checkfield to array: if ( in_array($page->ID, (array) $checkfield) )

Leave a Comment