-
-
Save helen/1593065 to your computer and use it in GitHub Desktop.
<? | |
/** | |
* 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 ); | |
} | |
?> |
Yes, sir.
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
it would be possible to make the rows sortable?
forget it, i've done it :)
How to use radio buttons instead of select box ?
Where I need to put the code? in functions.php?
Thanx alot its very helpful to me - just edit some code. :)
@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?
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.
I like the results I see in the single.php file
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,
Try to use function get_post_meta( $post_id, $key) http://codex.wordpress.org/Function_Reference/get_post_meta
hey i am writing all of the above code but there is no any response means there is no any meta box is created
What should I use in my template in order to display a certain field value in my webpage?
Awesome! Thanks for sharing this. It is very similar to what I needed. One of my repeating inputs, is repeating.
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]; ?>Add Another
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;
}
}
}
?>
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;
}
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.
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
Is there a way to create a dynamic ID to each name input when create based like
it have problem :
Parse error: syntax error, unexpected '}' on line 119
@MajesticSJ this problem occurs because of the <?
instead of <?php
on the first line.
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.
I'd suggest using Meta Box Group for repeatable group of custom fields. It supports unlimited level nesting and supports all field types.
How to export data? Thank !!!
Thank For the code,
I face problem while removing column, if i remove from buttom it works fine, but when i remove random any field it remove its sibling fields too. and always select its very first value..
Dear Helen,
first of all, thank you so much. It seems that this is nearly what I need.
Sadly, I am not a really professional coder, just starting with wordpress metaboxes and custom fields. Actually, my proud success was to add custom fields to select or multiselect custom taxonomy terms and save them. Well, everybody´s starting low, right.
I have a big question. Would you be so kind to gibt me an example of one repeatable group of fields including 4 fields (like I created them)?
In the meantime, I will try this on my own, but many passages in your code look (actually) hard to understand for me :)
Let me know, if you like to help.
Best wishes and thanks again
Buddy
Hi Dear Helen, glad to know that, your code is working fine. but when I try to upload media as a repeatable field then I am facing a few problems to solve this. please check my following code and let me know the solutions. if I get a solution then it will save lots of time. Already I wasted my 2 nights.
add_action('admin_init', 'custom_repeater_add_meta_boxes', 1);
function custom_repeater_add_meta_boxes() {
add_meta_box( 'custom_repeater_field', 'Custom Repeater Fields', 'custom_repeater_meta_box_display', array('lawncare_service'), 'normal', 'default');
}function custom_repeater_meta_box_display()
{
global $post;$custom_repeater_field = get_post_meta($post->ID, 'custom_repeater_field', true); wp_nonce_field( 'custom_repeater_meta_box_nonce', 'custom_repeater_meta_box_nonce' ); ?> <script type="text/javascript"> jQuery(document).ready(function( $ ){ $( '#add-row-custom' ).on('click', function() { var row = $( '.custom-empty-row.screen-reader-text' ).clone(true); row.removeClass( 'custom-empty-row screen-reader-text' ); row.insertBefore( '#custom-repeatable-fieldset-one tbody>tr:last' ); return false; }); $( '.remove-row-custom' ).on('click', function() { $(this).parents('tr').remove(); return false; }); }); </script> <table id="custom-repeatable-fieldset-one" width="100%"> <thead> <tr> <th width="30%">Name</th> <th width="20%">Designation</th> <th width="20%">Image Upload</th> <th width="20%">URL</th> <th width="10%"></th> </tr> </thead> <tbody> <?php if ( $custom_repeater_field ) : foreach ( $custom_repeater_field as $field ) { ?> <tr> <td><input type="text" class="widefat" name="custom_name[]" value="<?php if($field['custom_name'] != '') echo esc_attr( $field['custom_name'] ); ?>" /></td> <td><input type="text" class="widefat" name="custom_designation[]" value="<?php if ($field['custom_designation'] != '') echo esc_attr( $field['custom_designation'] ); ?>" /></td> <td> <?php $html = '<p class="description">Upload your Image here.</p>'; $html .= '<input id="wp_custom_attachment" name="wp_custom_attachment" size="25" type="file" value="" />'; // $filearray = get_post_meta( get_the_ID(), 'wp_custom_attachment', true ); $this_file = $field['wp_custom_attachment']['url']; if ( $this_file == '' ) { $html .= '<div><p>Current file: ' . $this_file . '</p></div>'; } echo $html; ?> </td> <td><input type="text" class="widefat" name="custom_url[]" value="<?php if ($field['custom_url'] != '') echo esc_attr( $field['custom_url'] ); ?>" /></td> <td><a class="button remove-row-custom" href="#">Remove</a></td> </tr> <?php } else : // show a blank one ?> <tr> <td><input type="text" class="widefat" name="custom_name[]" /></td> <td><input type="text" class="widefat" name="custom_designation[]" value="" /></td> <td> <p class="description">Upload your Image here.</p> <input id="wp_custom_attachment_two" name="wp_custom_attachment" size="25" type="file" value="" /> </td> <td><input type="text" class="widefat" name="custom_url[]" value="" /></td> <td><a class="button remove-row-custom" href="#">Remove</a></td> </tr> <?php endif; ?> <!-- empty hidden one for jQuery --> <tr class="custom-empty-row screen-reader-text"> <td><input type="text" class="widefat" name="custom_name[]" /></td> <td><input type="text" class="widefat" name="custom_designation[]" value="" /></td> <td> <p class="description">Upload your Image here.</p> <input id="wp_custom_attachment_three" name="wp_custom_attachment" size="25" type="file" value="" /> </td> <td><input type="text" class="widefat" name="custom_url[]" value="" /></td> <td><a class="button remove-row-custom" href="#">Remove</a></td> </tr> </tbody> </table> <p><a id="add-row-custom" class="button" href="#">Add another</a></p> <?php
}
add_action('save_post', 'custom_repeater_meta_box_save');
function custom_repeater_meta_box_save($post_id) {
if ( ! isset( $_POST['custom_repeater_meta_box_nonce'] ) ||
! wp_verify_nonce( $_POST['custom_repeater_meta_box_nonce'], 'custom_repeater_meta_box_nonce' ) )
return;if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return; if (!current_user_can('edit_post', $post_id)) return; $old_custom = get_post_meta($post_id, 'custom_repeater_field', true); $new_custom = array(); $names_custom = $_POST['custom_name']; $custom_designation = $_POST['custom_designation']; $custom_file = $_FILES['wp_custom_attachment']; $custom_url = $_POST['custom_url']; $count_custom = count( $names_custom ); for ( $j = 0; $j < $count_custom; $j++ ) { if ( $names_custom[$j] != '' ) : $new_custom[$j]['custom_name'] = stripslashes( strip_tags( $names_custom[$j] ) ); if ( $custom_designation[$j] == '' ) $new_custom[$j]['custom_designation'] = ''; else $new_custom[$j]['custom_designation'] = stripslashes( $custom_designation[$j] ); if ( $custom_url[$j] == '' ) $new_custom[$j]['custom_url'] = ''; else $new_custom[$j]['custom_url'] = stripslashes( $custom_url[$j] ); if ( ! empty( $custom_file[$j]['name'] ) ) { $upload_custom[$j] = wp_upload_bits($custom_file[$j]['name'], null, file_get_contents($custom_file[$j]['tmp_name'])); if ( isset( $upload_custom[$j]['error'] ) && $upload_custom[$j]['error'] != 0 ) { wp_die( 'There was an error uploading your file. The error is: ' . $upload_custom[$j]['error'] ); } else { // add_post_meta( $post_id, 'wp_custom_attachment', $upload_custom[$j] ); // update_post_meta( $post_id, 'wp_custom_attachment', $upload_custom[$j] ); $new_custom[$j]['wp_custom_attachment'] = $upload_custom[$j] ; } } // and however you want to sanitize endif; } if ( !empty( $new_custom ) && $new_custom != $old_custom ) update_post_meta( $post_id, 'custom_repeater_field', $new_custom ); elseif ( empty($new_custom) && $old_custom ) delete_post_meta( $post_id, 'custom_repeater_field', $old_custom );
}
/**
- Add functionality for file upload.
*/
function update_edit_form_custom() {
echo ' enctype="multipart/form-data"';
}
add_action( 'post_edit_form_tag', 'update_edit_form_custom' );
?>
I don't know, what is the problem. please help me and save my time
thanks for this code ,it's working fine can anyone help me to implement this with checkbox ,when I tried it's not saving checkbox entries
stripslashes()
your$_POST
values.esc_attr()
for anything that echoes in an HTML attribute. Especially on line 72!