Skip to content

Instantly share code, notes, and snippets.

@helen
Created January 11, 2012 04:42
Show Gist options
  • Save helen/1593065 to your computer and use it in GitHub Desktop.
Save helen/1593065 to your computer and use it in GitHub Desktop.
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 );
}
?>
@ibneAbdulHaque
Copy link

ibneAbdulHaque commented Dec 14, 2020

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

@anjanavk1
Copy link

anjanavk1 commented Dec 18, 2021

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment