Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Repeating Custom Fields in a Metabox
<?
/**
* Repeatable Custom Fields in a Metabox
* Author: Helen Hou-Sandi
*
* From a bespoke system, so currently not modular - will fix soon
* Note that this particular metadata is saved as one multidimensional array (serialized)
*/
function hhs_get_sample_options() {
$options = array (
'Option 1' => 'option1',
'Option 2' => 'option2',
'Option 3' => 'option3',
'Option 4' => 'option4',
);
return $options;
}
add_action('admin_init', 'hhs_add_meta_boxes', 1);
function hhs_add_meta_boxes() {
add_meta_box( 'repeatable-fields', 'Repeatable Fields', 'hhs_repeatable_meta_box_display', 'post', 'normal', 'default');
}
function hhs_repeatable_meta_box_display() {
global $post;
$repeatable_fields = get_post_meta($post->ID, 'repeatable_fields', true);
$options = hhs_get_sample_options();
wp_nonce_field( 'hhs_repeatable_meta_box_nonce', 'hhs_repeatable_meta_box_nonce' );
?>
<script type="text/javascript">
jQuery(document).ready(function( $ ){
$( '#add-row' ).on('click', function() {
var row = $( '.empty-row.screen-reader-text' ).clone(true);
row.removeClass( 'empty-row screen-reader-text' );
row.insertBefore( '#repeatable-fieldset-one tbody>tr:last' );
return false;
});
$( '.remove-row' ).on('click', function() {
$(this).parents('tr').remove();
return false;
});
});
</script>
<table id="repeatable-fieldset-one" width="100%">
<thead>
<tr>
<th width="40%">Name</th>
<th width="12%">Select</th>
<th width="40%">URL</th>
<th width="8%"></th>
</tr>
</thead>
<tbody>
<?php
if ( $repeatable_fields ) :
foreach ( $repeatable_fields as $field ) {
?>
<tr>
<td><input type="text" class="widefat" name="name[]" value="<?php if($field['name'] != '') echo esc_attr( $field['name'] ); ?>" /></td>
<td>
<select name="select[]">
<?php foreach ( $options as $label => $value ) : ?>
<option value="<?php echo $value; ?>"<?php selected( $field['select'], $value ); ?>><?php echo $label; ?></option>
<?php endforeach; ?>
</select>
</td>
<td><input type="text" class="widefat" name="url[]" value="<?php if ($field['url'] != '') echo esc_attr( $field['url'] ); else echo 'http://'; ?>" /></td>
<td><a class="button remove-row" href="#">Remove</a></td>
</tr>
<?php
}
else :
// show a blank one
?>
<tr>
<td><input type="text" class="widefat" name="name[]" /></td>
<td>
<select name="select[]">
<?php foreach ( $options as $label => $value ) : ?>
<option value="<?php echo $value; ?>"><?php echo $label; ?></option>
<?php endforeach; ?>
</select>
</td>
<td><input type="text" class="widefat" name="url[]" value="http://" /></td>
<td><a class="button remove-row" href="#">Remove</a></td>
</tr>
<?php endif; ?>
<!-- empty hidden one for jQuery -->
<tr class="empty-row screen-reader-text">
<td><input type="text" class="widefat" name="name[]" /></td>
<td>
<select name="select[]">
<?php foreach ( $options as $label => $value ) : ?>
<option value="<?php echo $value; ?>"><?php echo $label; ?></option>
<?php endforeach; ?>
</select>
</td>
<td><input type="text" class="widefat" name="url[]" value="http://" /></td>
<td><a class="button remove-row" href="#">Remove</a></td>
</tr>
</tbody>
</table>
<p><a id="add-row" class="button" href="#">Add another</a></p>
<?php
}
add_action('save_post', 'hhs_repeatable_meta_box_save');
function hhs_repeatable_meta_box_save($post_id) {
if ( ! isset( $_POST['hhs_repeatable_meta_box_nonce'] ) ||
! wp_verify_nonce( $_POST['hhs_repeatable_meta_box_nonce'], 'hhs_repeatable_meta_box_nonce' ) )
return;
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
return;
if (!current_user_can('edit_post', $post_id))
return;
$old = get_post_meta($post_id, 'repeatable_fields', true);
$new = array();
$options = hhs_get_sample_options();
$names = $_POST['name'];
$selects = $_POST['select'];
$urls = $_POST['url'];
$count = count( $names );
for ( $i = 0; $i < $count; $i++ ) {
if ( $names[$i] != '' ) :
$new[$i]['name'] = stripslashes( strip_tags( $names[$i] ) );
if ( in_array( $selects[$i], $options ) )
$new[$i]['select'] = $selects[$i];
else
$new[$i]['select'] = '';
if ( $urls[$i] == 'http://' )
$new[$i]['url'] = '';
else
$new[$i]['url'] = stripslashes( $urls[$i] ); // and however you want to sanitize
endif;
}
if ( !empty( $new ) && $new != $old )
update_post_meta( $post_id, 'repeatable_fields', $new );
elseif ( empty($new) && $old )
delete_post_meta( $post_id, 'repeatable_fields', $old );
}
?>
@markjaquith

This comment has been minimized.

Copy link

commented Jan 11, 2012

  • stripslashes() your $_POST values.
  • esc_attr() for anything that echoes in an HTML attribute. Especially on line 72!
@helen

This comment has been minimized.

Copy link
Owner Author

commented Jan 11, 2012

Yes, sir.

@da1nonly

This comment has been minimized.

Copy link

commented Mar 17, 2012

thanks for the code i was wondering, how can i add another custom fields so that i can save video and audio in two different custom fields

@oterox

This comment has been minimized.

Copy link

commented Jan 24, 2013

it would be possible to make the rows sortable?

@oterox

This comment has been minimized.

Copy link

commented Jan 24, 2013

forget it, i've done it :)

@lonerunner

This comment has been minimized.

Copy link

commented Feb 8, 2013

How to use radio buttons instead of select box ?

@developez

This comment has been minimized.

Copy link

commented Mar 13, 2013

Where I need to put the code? in functions.php?

@deemi

This comment has been minimized.

Copy link

commented Apr 18, 2014

Thanx alot its very helpful to me - just edit some code. :)

@reypm

This comment has been minimized.

Copy link

commented Jun 6, 2014

@helenhousandi how I use this approach in a plugin? I tried as this post show and can't get it to work, could any of the experts here give me some help?

@mchabros

This comment has been minimized.

Copy link

commented Jun 25, 2014

Hi, it's so great. I have a question. Do you know to implement group of input type checkbox to this solution? I want to want to be able to save more than one value for the same field. I appreciate any help. Thank you.

@ranawarez

This comment has been minimized.

Copy link

commented Jul 5, 2014

I like the results I see in the single.php file

@levipadre

This comment has been minimized.

Copy link

commented Nov 21, 2014

Hi,
Could you help me how can I unserialize the result?
I made my own filed and this is the result:
a:1:{i:0;a:1:{s:7:"address";s:6:"Russia";}}

Thanks,

@haltaction

This comment has been minimized.

Copy link

commented Dec 26, 2014

Try to use function get_post_meta( $post_id, $key) http://codex.wordpress.org/Function_Reference/get_post_meta

@Ld9Gupta

This comment has been minimized.

Copy link

commented Jul 17, 2015

hey i am writing all of the above code but there is no any response means there is no any meta box is created

@ghost

This comment has been minimized.

Copy link

commented Jul 22, 2015

What should I use in my template in order to display a certain field value in my webpage?

@unfinishedCode

This comment has been minimized.

Copy link

commented Aug 26, 2015

Awesome! Thanks for sharing this. It is very similar to what I needed. One of my repeating inputs, is repeating.

@ZaheerAbbasAghani

This comment has been minimized.

Copy link

commented Jan 9, 2016

how can i add repeatable fields in my code

__('Music Albums'), 'singular_label' => __('Music Album'), 'public' => true, 'show_ui' => true, 'capability_type' => 'post', 'hierarchical' => true, 'has_archive' => true, 'supports' => array('title', '', 'thumbnail'), 'rewrite' => array('slug' => 'musicalbums', 'with_front' => false), ); //Register type and custom taxonomy for type. register_post_type( 'musicalbums' , $args ); register_taxonomy("business-type", array("musicalbums"), array("hierarchical" => true, "label" => "Album Types", "singular_label" => "Album Type", "rewrite" => true, "slug" => 'album-type')); add_action("admin_init", "music_albums_add_meta"); function music_albums_add_meta(){ add_meta_box("musicalbum-meta", "Tracks", "Music_albums_meta_options", "musicalbums", "normal", "high"); } function Music_albums_meta_options(){ global $post; if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id; $custom = get_post_custom($post->ID); $upload_track = $custom["upload_track"][0]; $tracktitle = $custom["tracktitle"][0]; $artist= $custom["artist"][0]; $imageurl = $custom["imageurl"][0]; $iconurl = $custom["iconurl"][0]; $downloadText = $custom["downloadText"][0]; $ExtraInfoText = $custom["ExtraInfoText"][0]; ?>
Upload MP3 :
ID ); //require_once('getid3/getid3.php'); $prefix = 'sample_'; $fields = array( array( // Text Input 'label' => 'Text Input', // 'desc' => 'A description for the field.', // description 'id' => $prefix.'text', // field id and name 'type' => 'text' // type of field ), array( // Textarea 'label' => 'Textarea', // 'desc' => 'A description for the field.', // description 'id' => $prefix.'textarea', // field id and name 'type' => 'textarea' // type of field ) ); ?>
Track Title :
Artist :
Icon Url:
Download Link :
Extra Info Text:

Add Another

add_action('save_post', 'business_manager_save_extras');
function business_manager_save_extras(){
global $post;
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ){
//if you remove this the sky will fall on your head.
return $post_id;
}else{
update_post_meta($post->ID, "iconurl",
$_POST["iconurl"]);
update_post_meta($post->ID, "tracktitle", $_POST["tracktitle"]);
update_post_meta($post->ID, "artist", $_POST["artist"]);
update_post_meta($post->ID, "upload_track",
$_POST["upload_track"]);
update_post_meta($post->ID, "upload_track_two",
$_POST["upload_track_two"]);
update_post_meta($post->ID, "imageurl", $_POST["imageurl"]);
update_post_meta($post->ID, "downloadText", $_POST["downloadText"]);
update_post_meta($post->ID, "ExtraInfoText", $_POST["ExtraInfoText"]);
}
}

add_filter("manage_edit-musicalbums_columns", "business_manager_edit_columns");
function business_manager_edit_columns($columns){
$columns = array(
"cb" => "<input type="checkbox" />",
"title" => "Albums Name",
"upload_track" => "Track",
"ExtraInfoText" => "Extra Info Text",
"cat" => "Category",
);
return $columns;
}

add_action("manage_musicalbums_posts_custom_column",
"business_manager_custom_columns");
function business_manager_custom_columns($column){
global $post;
$custom = get_post_custom();
switch ($column)
{

case "upload_track":
$upload_track= $custom["upload_track"][0].'
';
echo $upload_track;
break;
case "ExtraInfoText":
echo $custom["ExtraInfoText"][0];
break;
case "cat":
echo get_the_term_list($post->ID, 'business-type');
break;
}
}

}
?>

@mundothemes

This comment has been minimized.

Copy link

commented Apr 15, 2016

Display in single Post

PHP code

<?php $repeatable_fields = get_post_meta($post->ID, 'repeatable_fields', true);  if ( $repeatable_fields ) : ?>
    <div class="list">
        <?php foreach ( $repeatable_fields as $field ) { ?>
        <div class="row">
            <?php if($field['name'] != '') echo '<span class="field">'. esc_attr( $field['name'] ) . '</span>'; ?>
            <?php if($field['select'] != '') echo '<span class="field">'. esc_attr( $field['select'] ) . '</span>'; ?>
            <?php if($field['url'] != '') echo '<span class="field">'. esc_attr( $field['url'] ) . '</span>'; ?>
        </div>
        <?php } ?> 
    </div>
<?php endif; ?>

CSS Code

.list {
    float: left;
    width: 100%;
    padding: 15px;
}
.list .row {
    width: 100%;
    padding: 5px 0;
    float: left;
}
.list .row span.field {
    width: calc(100% / 3);
    float: left;
}

@FlibertyP

This comment has been minimized.

Copy link

commented Feb 15, 2017

hi @mundothemes, You could share your code, because the one you show is almost exactly what I want, ie a button to upload images, add a URL and just as the field is repeatable.

@biklik

This comment has been minimized.

Copy link

commented Apr 1, 2017

Hi Helen! very nice work!
One question...is there any way to implement that code in a WordPress options page with settings API? I can build the form but the problema is to sanitize and save data.

Thank you!! +1

@moisesmachillanda

This comment has been minimized.

Copy link

commented Apr 17, 2017

Is there a way to create a dynamic ID to each name input when create based like

@sajadk48

This comment has been minimized.

Copy link

commented Jul 9, 2017

it have problem :
Parse error: syntax error, unexpected '}' on line 119

@sagar290

This comment has been minimized.

Copy link

commented Sep 21, 2017

@MajesticSJ this problem occurs because of the <? instead of <?php on the first line.

@thinzarwin

This comment has been minimized.

Copy link

commented Aug 2, 2018

i want to display repeatable field to specific page template.
I add the following code then repetable-fields was not display.

global $post;
if(!empty($post)) {
$pageTemplate = get_post_meta($post->ID, '_wp_page_template', true);
if($pageTemplate == 'inner_template.php' ){
add_meta_box( 'repeatable-fields', 'repeatable-fields', 'hhs_repeatable_meta_box_display', 'page', 'normal', 'high');
}
}
Please help me.

@rilwis

This comment has been minimized.

Copy link

commented Sep 26, 2018

I'd suggest using Meta Box Group for repeatable group of custom fields. It supports unlimited level nesting and supports all field types.

@HuuDuc97

This comment has been minimized.

Copy link

commented Aug 5, 2019

How to export data? Thank !!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.