Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Please help me understand how to make Multicheck type for metabox. Search for all internet and nothing. Thanks.


UPDATE

@Jan I have a headache from this function. I dont know whats wrong.I'm trying your method but nothing, then I'm trying get_posts but with this method I have too many troubles. With your method I get this error before content:

Warning: urldecode() expects parameter 1 to be string, array given in Z:\home\mysite.net\www\wp-includes\query.php on line 1878

Here is my code:

<?php
        $catids = get_post_meta($post->ID,'_mtb_multicheck',false);
        $limit = 10;
        query_posts( array('posts_per_page' => $limit, 'cat' => $catids, 'paged' => get_query_var('paged') ) );
    ?>
<?php if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>

        <!-- Content-->

<?php endwhile; ?>  
            <?php pagination(); ?>
<?php else : ?>
            <!--Error message here-->

<?php endif; ?>

I want to know what my vatiables return. Make this:

query_posts( array('posts_per_page' => $limit, 'cat' => print_r($catids), 'paged' => get_query_var('paged') ) );

and get this on my page:

Array ( [0] => 5 [1] => 5 [2] => 3 )

I think it's my query_posts printed, not $catids. It's a big, big trouble. I feel myself like a nerd. Please help me.

share|improve this question
    
@Denis: Your question is not very clear. Do you mean a series of checkboxes by "multicheck"? And are you talking about adding a new metabox, like on the post edit screen? –  Jan Fabry Dec 1 '10 at 8:40
    
Yes Jan, I want to add a series of checkboxes like on the post edit screen. I make metabox by this tutorial deluxeblogtips.com/2010/05/howto-meta-box-wordpress.html , but they doesn't include type multicheck. –  Denis Belousov Dec 1 '10 at 13:04
    
@Denis: That code seems to include the checkbox type, how is this different from a "multicheck"? Can you update your question with an mock-up (sketch) image? If you use @ before my name in a comment, like @Jan, I will get a notification and can reply sooner. –  Jan Fabry Dec 2 '10 at 9:22
    
@Jan: Multicheck mean that you can check multiple item in one field, it's like category taxonomy where we can check several categories that include this post. We dont need to create checkbox for every category or another item we use array with items and multicheck help us check several items. –  Denis Belousov Dec 2 '10 at 13:07
    
@Jan: I make somthing like this but it's check only one checkbox not several: pastebin.com/TAKDe13u –  Denis Belousov Dec 2 '10 at 13:32
show 6 more comments

2 Answers 2

up vote 4 down vote accepted

The post metadata can store multiple values either as distinct entries in the postmeta table, or as one entry with the value as a serialized PHP array. The serialization may require less code, but the distinct entries allow faster querying later ("give me all posts that have at least option A of the multicheck checked").

I took the code you linked to and made the following changes to allow a "multicheck":

// in show():
// Line 254: replace it by:
$meta = get_post_meta($post->ID, $field['id'], 'multicheck' != $field['type'] /* If multicheck this can be multiple values */);
// Add the following to the switch:
case 'multicheck':
    foreach ( $field['options'] as $value => $name ) {
        // Append `[]` to the name to get multiple values
        // Use in_array() to check whether the current option should be checked
        echo '<input type="checkbox" name="', $field['id'], '[]" id="', $field['id'], '" value="', $value, '"', in_array( $value, $meta ) ? ' checked="checked"' : '', ' /> ', $name, '<br/>';
    }
    break;

// In save():
// Line 358: replace it by:
$old = get_post_meta($post_id, $name, 'multicheck' != $field['type'] /* If multicheck this can be multiple values */);
// Lines 409-413: Wrap them in an else-clause, and prepend them by:
if ( 'multicheck' == $field['type'] ) {
    // Do the saving in two steps: first get everything we don't have yet
    // Then get everything we should not have anymore
    if ( empty( $new ) ) {
        $new = array();
    }
    $aNewToAdd = array_diff( $new, $old );
    $aOldToDelete = array_diff( $old, $new );
    foreach ( $aNewToAdd as $newToAdd ) {
        add_post_meta( $post_id, $name, $newToAdd, false );
    }
    foreach ( $aOldToDelete as $oldToDelete ) {
        delete_post_meta( $post_id, $name, $oldToDelete );
    }
} else {
    // The original lines 409-413
}

Two extra changes to prevent PHP warnings when WP_DEBUG is enabled:

// Line 337:
if ( ! isset( $_POST['wp_meta_box_nonce'] ) || !wp_verify_nonce($_POST['wp_meta_box_nonce'], basename(__FILE__))) {
// Line 359:
$new = isset( $_POST[$field['id']] ) ? $_POST[$field['id']] : null;

With these changes, you can use a "multicheck" by defining it like this:

array(
    'name' => 'Multicheck',
    'id' => $prefix . 'multicheck',
    'type' => 'multicheck',
    'options' => array(
        'a' => 'Apple',
        'b' => 'Banana',
        'c' => 'Cherry',
    ),
)
share|improve this answer
    
@Jan: Thank you very much for this answer, it's a big work. One question: As I said above I'm test this function with list of categories. I'm try assign several categories to page and nothing happens, even one category doesn't accept. In my template I'm use $catid = get_post_meta($post->ID,'mtb_category',true); query_posts('cat='.$catid); Maybe you see whats wrong? Thank you! –  Denis Belousov Dec 7 '10 at 19:45
    
@Denis: The comments are not the best way to do this, maybe you can ask an additional question? Make sure to include all your code, and output of var_dump() along they way, so we know what is going on. –  Jan Fabry Dec 8 '10 at 13:01
    
@Jan: I check my database and see that my multicheck is saved separate. Looks now: imgur.com/dX76l.png Must be: imgur.com/m2KiI.png I think problem with metaboxes, not with templates. –  Denis Belousov Dec 9 '10 at 2:27
    
@Denis: That was intentional, that's why I meant with "distinct entries vs. one serialized entry". Your code should be $catids = get_post_meta( $post->ID, 'mtb_category', false); query_posts( array( 'cat' => $catids ) );. And maybe replace query_posts() with get_posts(). –  Jan Fabry Dec 9 '10 at 7:42
    
@Denis: I'm sorry, you should not use cat if you pass an array to query_posts(), but category__in. cat only accepts a comma-separated list of array ID's, but category__in accepts an array of category ID's, like we use here. –  Jan Fabry Dec 16 '10 at 10:45
show 2 more comments

@Jan I'm using the code you've provided and it's working, albeit with one problem. When I change the $meta = get_post_meta($post->ID, $field['id'], true); to what you've provided, it doesn't store the value. If I don't change it, I get the following error

Warning: in_array() [function.in-array]: Wrong datatype for second argument

Until I check one of the boxes. Any ideas?

share|improve this answer
    
Nevermind. Seems I had made some tweaks to the existing code prior that was conflicting. It's working now. –  Norcross Jan 18 '11 at 19:01
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.