Add metabox with key-value custom fields dynamically added by user
<?php
//usage
$tribe_events_miscinfo = get_post_meta(get_the_ID(), 'tribe_events_miscinfo', true);
if ($tribe_events_miscinfo) {
foreach ($tribe_events_miscinfo as $k => $v) {
echo '<dt>'.$v['title'].'</dt>';
echo '<dd';
if ($v['tooltip']) {
echo ' title="'.$v['tooltip'].'"';
}
echo '>'.$v['content'];
echo '</dd>';
}
}
<?php
//Add metabox with dynamically added key-value (with more values possible) custom fields
//Based on http://wordpress.stackexchange.com/questions/19838/create-more-meta-boxes-as-needed/19852#19852
// Caution, there're 2 set of options below
//Variables used in the following functions should be mentioned in the 'global' statement of each of them appropriately
//=======Options 1=======
$dmb_post_type = 'tribe_events';
$dmb_metabox_label = 'Other information';
$dmb_cf_name = 'tribe_events_miscinfo';
// Add actions, initialise functions
add_action( 'add_meta_boxes', 'dynamic_add_custom_box' );
add_action( 'save_post', 'dynamic_save_postdata' );
//Function to add a meta box
function dynamic_add_custom_box() {
global $dmb_post_type, $dmb_metabox_label;
add_meta_box('dynamic_sectionid', $dmb_metabox_label, 'dynamic_inner_custom_box', $dmb_post_type);
}
//Function that defines metabox contents
function dynamic_inner_custom_box() {
//=======Options 2=======
$dmb_label_addnew = 'Add more';
$dmb_label_remove = 'Remove';
$dmb_key_name = 'title';
$dmb_value_name = 'content';
$dmb_value2_name = 'tooltip';
$dmb_key_label = 'Title of element';
$dmb_value_label = 'Content of element';
$dmb_value2_label = 'Tooltip on element';
global $post;
global $dmb_cf_name;
// Use nonce for verification
wp_nonce_field( plugin_basename( __FILE__ ), 'dynamicMeta_noncename' );
//OPTIONAL - if using a date field
//Load admin scripts & styles for JS datepicker via the class from Meta Box plugin. This requires Meta Box plugin by Rilwis installed http://x.co/1YgqA
// $loadJqUIfromMetaboxPlugin = new RWMB_Date_Field();
// $loadJqUIfromMetaboxPlugin->admin_enqueue_scripts();
?>
<div id="dynamic_inner_custom_box">
<?php
$dmb_items = get_post_meta($post->ID,$dmb_cf_name,true);
$c = 0;
if ( is_array($dmb_items) && count( $dmb_items ) > 0 ) {
foreach( $dmb_items as $dmb_item ) {
if ( isset( $dmb_item[$dmb_key_name] ) || isset( $dmb_item[$dmb_value_name] ) ) {
printf( '<p class="dmb_parent"><label for=""%6$s[%1$s][%4$s]">%8$s</label> <input type="text" name="%6$s[%1$s][%4$s]" id="%6$s[%1$s][%4$s]" value="%2$s"> <label for="%6$s[%1$s][%5$s]">%9$s</label> <input id="%6$s[%1$s][%5$s]" type="text" name="%6$s[%1$s][%5$s]" value="%3$s"> <label for="%6$s[%1$s][%10$s]">%11$s</label> <input type="text" id="%6$s[%1$s][%10$s]" name="%6$s[%1$s][%10$s]" value="%12$s"> <a href="#" class="remove">%7$s</a></p>',
/*1*/ $c,
/*2*/ $dmb_item[$dmb_key_name],
/*3*/ $dmb_item[$dmb_value_name],
/*4*/ $dmb_key_name,
/*5*/ $dmb_value_name,
/*6*/ $dmb_cf_name,
/*7*/ $dmb_label_remove,
/*8*/ $dmb_key_label,
/*9*/ $dmb_value_label,
/*10*/ $dmb_value2_name,
/*11*/ $dmb_value2_label,
/*12*/ $dmb_item[$dmb_value2_name]
);
$c = $c + 1;
}
}
}
?>
<span id="here"></span>
<a href="#" class="add button-secondary"><?php echo $dmb_label_addnew; ?></a>
<style type="text/css">
.dmb_parent {display: flex;}
.dmb_parent > * {flex:1 1 auto;}
.dmb_parent label {padding-right:5px; text-align: right;}
.dmb_parent .remove {padding-left: 5px;}
</style>
<script>
var $ =jQuery.noConflict();
$(document).ready(function() {
//OPTIONAL
//Add datepicker to an input
//$('body').on('focus',".choosedate", function(){ //Allows to init datepicker on non existing yet elements
// $(this).datepicker({ dateFormat: "dd.mm.yy" });
//});
var count = <?php echo $c; ?>;
$(".add").on('click',function(e) {
e.preventDefault();
count = count + 1;
$('#here').append('<p class="dmb_parent"><label for="<?php echo $dmb_cf_name; ?>['+count+'][<?php echo $dmb_key_name; ?>]"><?php echo $dmb_key_label; ?></label> <input type="text" id="<?php echo $dmb_cf_name; ?>['+count+'][<?php echo $dmb_key_name; ?>]" name="<?php echo $dmb_cf_name; ?>['+count+'][<?php echo $dmb_key_name; ?>]" value=""> <label for="<?php echo $dmb_cf_name; ?>['+count+'][<?php echo $dmb_value_name; ?>]"><?php echo $dmb_value_label; ?></label> <input type="text" name="<?php echo $dmb_cf_name; ?>['+count+'][<?php echo $dmb_value_name; ?>]" id="<?php echo $dmb_cf_name; ?>['+count+'][<?php echo $dmb_value_name; ?>]" value=""> <label for="<?php echo $dmb_cf_name; ?>['+count+'][<?php echo $dmb_value2_name; ?>]"><?php echo $dmb_value2_label; ?></label> <input type="text" name="<?php echo $dmb_cf_name; ?>['+count+'][<?php echo $dmb_value2_name; ?>]" id="<?php echo $dmb_cf_name; ?>['+count+'][<?php echo $dmb_value2_name; ?>]" value=""> <a href="#" class="remove"><?php echo $dmb_label_remove; ?></a></p>');
return false;
});
$("#dynamic_inner_custom_box").on('click', '.remove', function(e) {
e.preventDefault();
$(this).parent().remove();
});
});
</script>
</div><?php
}
/* When the post is saved, saves our custom data */
function dynamic_save_postdata( $post_id ) {
global $dmb_cf_name;
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
if ( !isset( $_POST['dynamicMeta_noncename'] ) )
return;
if ( !wp_verify_nonce( $_POST['dynamicMeta_noncename'], plugin_basename( __FILE__ ) ) )
return;
$data2post = $_POST[$dmb_cf_name];
update_post_meta($post_id,$dmb_cf_name,$data2post);
}