Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Save Multiple Checkbox on METABOX WordPress

  • SOLVED

I have to save the ID of Custom Post Type "Autori", in custom field of post called "autore_id"

I need:
- multiple selection
- save the data in this way: example > '-18--21--22-' (these are the iDs of Custom post "Autori")

My problems:

1) doesn't save nothing
2) the slug of post change on saved and take the name of 1 autor random - amazing but is it
3) naturally not works



class Autori_Meta_Box {

public function __construct() {

if ( is_admin() ) {
add_action( 'load-post.php', array( $this, 'init_metabox' ) );
add_action( 'load-post-new.php', array( $this, 'init_metabox' ) );
}

}

public function init_metabox() {

add_action( 'add_meta_boxes', array( $this, 'add_metabox' ) );
add_action( 'save_post', array( $this, 'save_metabox' ), 10, 2 );

}

public function add_metabox() {

add_meta_box(
'autori_meta_box_id',
'Autori',
array( $this, 'autori_metabox' ),
'post',
'side',
'high'
);

}

public function autori_metabox( $post ) {

// Add nonce for security and authentication.
wp_nonce_field( 'autore_id_nonce_action', 'autore_id_nonce' );

// Retrieve an existing value from the database.
$autore_id = get_post_meta( $post->ID, 'autore_id[]', true );

global $post; // required
$args=array(
'post_type'=>'autori',
'post_per_page'=>-1,
'orderby'=> ID,
'order' => ASC

);
$custom_posts = get_posts($args);
foreach($custom_posts as $post) : setup_postdata($post);

echo '<p><label><input type="checkbox" name="autore_id[]" class="check_autori_field" value="' . get_the_ID() . '" ' . checked( $autore_id, 'checked' ) . '> ' . get_the_title() . '</label><p>';

endforeach;

wp_reset_postdata();
}

public function save_metabox( $post_id, $post ) {

// Add nonce for security and authentication.
$nonce_name = isset( $_POST['autore_id_nonce'] ) ? $_POST['autore_id_nonce'] : '';
$nonce_action = 'autore_id_nonce_action';

// Check if a nonce is set.
if ( ! isset( $nonce_name ) )
return;

// Check if a nonce is valid.
if ( ! wp_verify_nonce( $nonce_name, $nonce_action ) )
return;

// Check if the user has permissions to save data.
if ( ! current_user_can( 'edit_post', $post_id ) )
return;

// Check if it's not an autosave.
if ( wp_is_post_autosave( $post_id ) )
return;

// Check if it's not a revision.
if ( wp_is_post_revision( $post_id ) )
return;

// Sanitize user input.
//$autore_id_new = isset( $_POST[ 'autore_id[]' ] ) ? 'checked' : '';

// Update the meta field in the database.
//update_post_meta( $post_id, 'autore_id', $autore_id_new );

$autore_id_new = implode( "--", $_POST['autore_id'] );
update_post_meta( $post_id, 'autore_id', '-'.$autore_id_new.'-' );


}

}

new Autori_Meta_Box;

Answers (2)

2016-04-30

Bob answers:

First issue is at the code where you fetch value from database.
<strong>Wrong code</strong>
$autore_id = get_post_meta( $post->ID, 'autore_id[]', true );
<strong>Right Code</strong>
$autore_id = get_post_meta( $post->ID, 'autore_id', true );

Then the issue is with checked function.

Can you please explain why you need "--" around ID?
It makes it unnecessary complex.

you can add -- when you needed. the values can simply be ID of posts.


Bob comments:

<strong>Updated function autori_metabox</strong>

public function autori_metabox( $post ) {
// Add nonce for security and authentication.
wp_nonce_field( 'autore_id_nonce_action', 'autore_id_nonce' );
// Retrieve an existing value from the database.
$autore_id = get_post_meta( $post->ID, 'autore_id', true );
global $post; // required
$args=array(
'post_type'=>'autori',
'post_per_page'=>-1,
'orderby'=> ID,
'order' => ASC
);
$custom_posts = get_posts($args);

foreach($custom_posts as $post) : setup_postdata($post);
$checkid = "-".get_the_ID()."-";
$checked = "";
if(strpos($autore_id,$checkid) !== false )
$checked = 'checked="checked"';

echo '<p><label><input type="checkbox"
name="autore_id[]"
class="check_autori_field"
value="' . get_the_ID() . '" ' . $checked . '> ' . get_the_title() . '</label><p>';
endforeach;
wp_reset_postdata();
}


Manlio Ma comments:

Hi Bob, I need to include the ID in "-ID-", because when I build the single page for CPT Autore, I need to run a loop and check all post that contains the single ID.

If I don't do this... I will have this WRONG scenario custom_field = 1218181828 .... where all ids are close and it is difficult to identify only one ID

I hope you understand my bad english ;)

Now i tried your code and:

1) doesn't save nothing
2) the slug of post change on saved and take the name of 1 autor random - amazing but is it

<blockquote>before:
mydomain.com/post-title

After saving:
mydomain.com/autore</blockquote>


Bob comments:

you can save serialized array. There is no need to save it as string.


Bob comments:

Above code works fine in my localhost.

We can discuss it over skype: thevaghela


Bob comments:


// custom post: Autori
add_action( 'init', function() {
$labels = array(
'name' => 'Autori',
'singular_name' => 'Autore',
'add_new' => 'Aggiungi nuovo',
'add_new_item' => 'Aggiungi nuovo Autore',
'edit_item' => 'Modifica Autore',
'new_item' => 'Nuovo Autore',
'all_items' => 'Tutti gli Autori',
'view_item' => 'Vedi Autore',
'search_items' => 'Cerca Autore',
'not_found' => 'No Autore found',
'not_found_in_trash' => 'No Autore found in the Trash',
'parent_item_colon' => '',
'menu_name' => 'Autori'
);
$args = array(
'labels' => $labels,
'description' => 'Autori',
'public' => true,
'menu_position' => 23,
'menu_icon' => 'dashicons-businessman',
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt', 'comments' ),
'has_archive' => true,
);
register_post_type( 'Autori', $args );
});


class Autori_Meta_Box {

public function __construct() {

if ( is_admin() ) {
add_action( 'load-post.php', array( $this, 'init_metabox' ) );
add_action( 'load-post-new.php', array( $this, 'init_metabox' ) );
}

}

public function init_metabox() {

add_action( 'add_meta_boxes', array( $this, 'add_metabox' ) );
add_action( 'save_post', array( $this, 'save_metabox' ), 10, 2 );

}

public function add_metabox() {

add_meta_box(
'autori_meta_box_id',
'Autori',
array( $this, 'autori_metabox' ),
'post',
'side',
'high'
);

}



public function autori_metabox( $post ) {
// Add nonce for security and authentication.
wp_nonce_field( 'autore_id_nonce_action', 'autore_id_nonce' );
// Retrieve an existing value from the database.
$autore_id = get_post_meta( $post->ID, 'autore_id', true );
//print_r($autore_id);
global $post; // required
$args=array(
'post_type'=>'autori',
'post_per_page'=>-1,
'orderby'=> ID,
'order' => ASC
);
$custom_posts = get_posts($args);

foreach($custom_posts as $p) :
$checked = "";
if(is_array( $autore_id )){
if( in_array( $p->ID, $autore_id ) )
$checked = 'checked="checked"';
}

echo '<p><label><input type="checkbox"
name="autore_id[]"
class="check_autori_field"
value="' . $p->ID . '" ' . $checked . '> ' . $p->post_title . '</label><p>';
endforeach;
}

public function save_metabox( $post_id, $post ) {

// Add nonce for security and authentication.
$nonce_name = isset( $_POST['autore_id_nonce'] ) ? $_POST['autore_id_nonce'] : '';
$nonce_action = 'autore_id_nonce_action';

// Check if a nonce is set.
if ( ! isset( $nonce_name ) )
return;

// Check if a nonce is valid.
if ( ! wp_verify_nonce( $nonce_name, $nonce_action ) )
return;

// Check if the user has permissions to save data.
if ( ! current_user_can( 'edit_post', $post_id ) )
return;

// Check if it's not an autosave.
if ( wp_is_post_autosave( $post_id ) )
return;

// Check if it's not a revision.
if ( wp_is_post_revision( $post_id ) )
return;

$data = $_POST['autore_id'];
if($data)
update_post_meta( $post_id, 'autore_id', $data );


}

}

new Autori_Meta_Box;

2016-04-29

Andrea P answers:

if you are on a while loop with the_post(), you already have the post and you don't need to do get_post() again..
so this bit here

$id_autore = get_the_ID();
$autore = get_post($id_autore, ARRAY_A);
$slug_autore = $autore['post_name'];
$titolo_autore = $autore['post_title'];


should be like this:

global $post;
$id_autore = get_the_ID();
$slug_autore = $post->post_name;
$titolo_autore = get_the_title();


then I'm sorry but I can't understand what else is your problem..
are the selected checkbox correctly saved? the code seems being doing it..

do you want to save the value of the selected autori slug into another field other than the checkboxes?


Manlio Ma comments:

I want a normal Metabox with list (input-checkbox) with all "Autori".

Then I want save it. Just this. but my script does't save.

And if I check 2 autors, I need to save 2 values in the same custom field

Hope is clear, thank you very much