1

I've been searching for a couple of days and have found no information on how to allow an admin user to duplicate a metabox for a custom post type with a button click.

    add_meta_box(  
    'Presentation', // $id  
    'Presentation', // $title   
    'show_custom_presentation_meta_box', // $callback  
    'presentations', // $page  
    'normal', // $context  
    'high', // $priority
     $custom_presenter_meta_fields); // $callback_args  

Seeing as the add_meta_box function is called in add_meta_boxes action, i'm not sure if any variables could be stored that allow a loop to add the correct number of metaboxes after a user has saved a post with additional metaboxes.

I've implemented dynamic fields, when a user clicks a button an additional text field is added and saved when the post is updated.

I am not looking to duplicate the fields inside the metabox. I am looking to create a duplicate of the entire metabox when a + is clicked.

A point in the correct direction would be much appreciated. Thanks!

2
  • Can you clarify? Basicly you want to add a metabox with one field. But the user can click a + to insert a second field? And save both? Commented Jan 11, 2017 at 14:52
  • Not quite, I've been able to accomplish what you are describing. The metabox, I'd like to duplicate has about seven fields. I want an additional metabox, with the same 7 fields, when a user clicks a +. Commented Jan 11, 2017 at 14:56

2 Answers 2

1

One of the first steps I found to creating a dynamic metabox is to create the additional metabox you want duplicated on button click.

In a separate metabox, we require a field that will contain a count for the desired dynamic metaboxes. *Note this field can be hidden or visible.

dynamic metabox count

global $presenter_count;

add_meta_box(  
    'Meetings', // $id  
    'Meetings Info', // $title   
    'show_custom_meetings_meta_box', // $callback  
    'meetings', // $page  
    'normal', // $context  
    'high', // $priority
     $custom_meetings_meta_fields); // $callback_args          

$c = 0;
$count = get_post_meta($post_id, 'meetings_presenter_count', true);

while ( $c < $count) {

    $presenter_count = 0;

    add_meta_box(  
        'Presentation'.$c, // $id  
        'Presentation '.++$c, // $title   
        'show_custom_meetings_meta_box', // $callback  
        'meetings', // $page  
        'normal', // $context  
        'low', // $priority
         $custom_meetings_presenter_meta_fields); // $callback_args  
}

Inside the callback function that builds the fields we want to make sure we are calling the global variable we set up $presenter_count.

Each time the while loop executes, based off the meta_value from number of presentations field, presenter count increments, and this will set the correct array for our fields.

// Callback args for metabox
$custom_meetings_presenter_meta_fields = array(  
        array(  
            'label' => 'Presenter\'s Name',
            'desc'  => 'The presenter\'s prefix and name',
            'id'    => $prefix.'name',
            'type'  => 'presenter_name'
        ));

// Callback function
    function show_custom_meetings_meta_box($post, $custom_meetings_field) {  
global $custom_meetings_meta_fields, $custom_meetings_presenter_meta_fields, $post, $presenter_count;
// Use nonce for verification 

echo '<input type="hidden" name="custom_meta_box_nonce" value="'.wp_create_nonce(basename(__FILE__)).'" />'; 
    // Begin the field table and loop 
    echo '<table class="form-table">';  
    foreach ($custom_meetings_field['args'] as $field) {  
        // get value of this field if it exists for this post  
        $meta = get_post_meta($post->ID, $field['id'], true);  
        // begin a table row with  
        echo '<tr> 
                <th><label for="'.$field['id'].'">'.$field['label'].'</label></th> 
                <td>';  
                switch($field['type']) {  
                    // Presenter Name
                    case 'presenter_name':  

                        $c = $presenter_count;

                        echo '<input type="text" name="'.$field['id'].'['.$c.']" id="'.$field['id'].'-'.$c.'" value="'.$meta[$c].'" size="30" /> 
                            <br /><span class="description">'.$field['desc'].'</span>';  

                    break; 
                } //end switch  
        echo '</td></tr>';  

        }

    } // end foreach  
    echo '</table>'; // end table  
}  

we also need to set up a button for the user to add metabox on command.

enter image description here

The code behind the button:

jQuery('.add-presentation').on('click', function(){
    var c  = jQuery('#meetings_presenter_count').val(); // get presenter count
    var pc = 0;
    if ( c != '' ) {
        pc = c + 1;
        // write a condition that allows for one presenter to exist
        jQuery('#Presentation'+pc).after('Insert Metabox');
        jQuery('#meetings_presenter_count').val(pc); // Increment presenter count
    }else{ // If no presenter box exists make count = 1
        jQuery('#meetings_presenter_count').val('1');
        jQuery('#Meetings').after('Insert Metabox');
    }

});
Sign up to request clarification or add additional context in comments.

Comments

0

I can't provide a full answer here but can give pointers.

To duplicate the metabox you will need to add javascript.

  1. On all input fields make sure the name="" field are prefixed like name="1_text" name="1_firstname"
  2. Select the first metabox with jquery.
  3. Duplicate it. Change the name attributes with a +1 name="2_text" name="2_firstname" Also up the ID of the box in total in your example 'Presentation', // $id
  4. When saving detect these different names and save them as you like.
  5. On loading the edit-page detect the number of boxes and foreach add_meta_box with the correct numbers

Edit. Point 1 could also be done with an array notations:

<input type="text" name="text[1]" />
<input type="text" name="firstname[1]" />

Which is easier when saving. And probably easier to fill when loading.

3 Comments

Thanks! I working on this now. I'll post if I get the solution. Thank you janw!
If my hints lead to the solution please accept the answer. Still you could also add your own answer.
I am using array's for the names. Right now i'm working on saving the data. It looks like I may need to create an array to contain each post ID and number of metaboxes in the post so each can be saved and loaded correctly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.