GDT
GDT

Reputation: 314

Dynamically Create Wordpress Metabox

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!

Upvotes: 1

Views: 2607

Answers (2)

GDT
GDT

Reputation: 314

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');
    }

});

Upvotes: 1

janw
janw

Reputation: 6662

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.

Upvotes: 0

Related Questions