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:

Read More

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.

Related posts

Leave a Reply

1 comment

  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) )