Create Repeater Meta Box in WordPress

Create Repeater Meta Box in WordPress

Repeatable Custom Fields in a Meta box Creating a “repeater meta-box” without a Plugin in WordPress. Add below code in your functions.php file (this file is located in your theme folder)

What is a repeater meta box?

A popular interface within a WordPress meta box is the repeater. It enables your client to create new custom fields for a specific piece of content on the fly.

What’s the use of the repeater meta box?

Meta boxes are useful, adaptable, modular edit screen elements that can be used to collect data about the post being edited. Your custom meta box will be displayed alongside all other post-related information, establishing a clear relationship.

Use this code

add_action( 'admin_init', 'cxc_single_rapater_meta_boxes', 2 );
function cxc_single_rapater_meta_boxes() {
	add_meta_box( 'cxc-single-repeater-data', 'Single Repeater', 'cxc_single_repeatable_meta_box_callback', 'post', 'normal', 'default');

function cxc_single_repeatable_meta_box_callback( $post ) {
	$custom_repeater_item = get_post_meta( $post->ID, 'custom_repeater_item', true );
	wp_nonce_field( 'repeterBox', 'formType' );
	<script type="text/javascript">		
			jQuery(document).on('click', '.wc-remove-item', function() {
			jQuery(document).on('click', '.wc-add-item', function() {
				var row_no = jQuery('.wc-item-table tr.wc-sub-row').length;    
				var p_this = jQuery(this);
				row_no = parseFloat(row_no);
				var row_html = jQuery('.wc-item-table .wc-hide-tr').html().replace(/rand_no/g, row_no).replace(/hide_custom_repeater_item/g, 'custom_repeater_item');
				jQuery('.wc-item-table tbody').append('<tr class="wc-sub-row">' + row_html + '</div>');    
	<table class="wc-item-table" width="100%">
			if( $custom_repeater_item ){
				foreach( $custom_repeater_item as $item_key => $item_value ){
					<tr class="wc-sub-row">				
							<input name="custom_repeater_item[<?php echo $item_key; ?>][title]" type="text" value="<?php echo (isset($item_value['title'])) ? $item_value['title'] : ''; ?>" style="width:98%;" placeholder="Heading">		
							<input type="text" name="custom_repeater_item[<?php echo $item_key; ?>][desc]" value="<?php echo (isset($item_value['desc'])) ? $item_value['desc'] : ''; ?>" style="width:98%;" placeholder="Description"/>
							<button class="wc-remove-item button" type="button">Remove</button>
			<tr class="wc-hide-tr" style="display: none;">				
					<input name="hide_custom_repeater_item[rand_no][title]" type="text" value="<?php echo $page_title; ?>"  placeholder="Heading" style="width:98%;" >		
					<input type="text" name="hide_custom_repeater_item[rand_no][desc]" style="width:98%;" placeholder="Description"/>
					<button class="wc-remove-item button" type="button">Remove</button>
				<td colspan="4"><button class="wc-add-item button" type="button">Add another</button></td>

add_action( 'save_post', 'cxc_single_repeatable_meta_box_save' );
function cxc_single_repeatable_meta_box_save( $post_id ) {

	if ( !isset( $_POST['formType'] ) && !wp_verify_nonce( $_POST['formType'], 'repeterBox' ) ){

	if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ){

	if ( !current_user_can( 'edit_post', $post_id ) ){

	if ( isset($_POST['custom_repeater_item']) ){
		update_post_meta( $post_id, 'custom_repeater_item', $_POST['custom_repeater_item'] );
	} else {
		update_post_meta( $post_id, 'custom_repeater_item', '' );

Important parts of this code

  •  The function is called single_repeatable_meta_box_callback, and it’s passed $post as an argument.
  •  The code then creates a new meta box with the name “Single Repeater”.
  •  The code starts by using jQuery to click on the .wc-remove-item button.
  •  This will remove all of the items in a particular row from the repeater.
  •  Next, it uses jQuery to click on the .wc-add-item button.
  •  The code will remove all the items from the repeater list when a user clicks on the .wc-remove-item button.
  •  The code will add an item to the repeater list when a user clicks on the .wc-add-item button.
  •  The code starts by setting up a variable called row_no.
  •  This is used to keep track of the number of rows in the table.
  •  The code then sets up another variable, p_this, which will be used to reference the current item on the page.
  •  The next line calculates how many rows are in the table and assigns that value to row_no: parseFloat(row_no); Next, it creates an HTML string with all of the hidden rows removed from it.
  •  It replaces any instances of rand_no with row_number and removes any occurrences of hide-custom-repeater-item from its content: var row_html = jQuery(‘.wc-item-table .wc-hide-tr’).html().replace(/rand_no/g, row_number).replace(/hide_custom repeater item/g,’custom repeater item’);
  •  The code is used to generate the HTML for a table row.
  •  The first line of code is used to find out how many rows are in the table.
  •  The second line of code uses jQuery’s .html() method to replace all instances of “rand_no” with the number found in the first line, and replaces all instances of “hide_custom_repeater_item” with “custom_repeater_item”.
  •  The code is a loop that iterates through the $custom_repeater_item array.
  •  The code then creates an HTML table with a row for each key in the $custom_repeater_item array.
  •  Each row has two columns: one column is for the value of the key, and another column is for text to be displayed next to it.
  •  Next, jQuery(‘.wc-sub-row’) is appended to create rows within rows.
  •  The code above first creates a table with two columns and then appends three rows to it.
  •  The first row will have a class of “wc-sub-row” and the second row will have a class of “wc-sub-row”.
  • Then, the third row will have a class of “wc-sub-row”.
  • Inside these cells are some text which represents what should be displayed for that particular cell’s content.
  • The next section of code starts with an if statement that checks whether or not there is data in the $item_value array.
  •  If there is, then it sets up a repeater item for each value in the array, which are set as variables named $item_key and $item_value respectively.
  •  The repeater items have two input fields: one for title and another for description.
  •  After setting up all of these inputs, they also create a button called “Remove” which removes all of them at once by using wc-remove-item class on it.
  •  After this comes a loop that iterates through each item in the repeater list (the ones created earlier) and creates an HTML table row with three columns: heading, description, and button to remove them from view altogether.
      $item_value[‘title’] : ”; ?
  •  The code is a simple example of how to use the WordPress custom repeater function.
  •  The code starts by defining the loop that will be used to iterate through all the items in the custom repeater.
  •  Next, it defines an array called $item_value, which contains each item’s value and title.
  •  Then, it creates a new variable called $item_key with the key of each item in the loop.


What is the purpose of add_action?

The add_action function allows us to hook into WordPress and run our own custom code at specific times. In this case, we’re running our code when the admin page loads (admin_init).

What is the purpose of add_meta_box?

The add_meta_box function allows us to create a meta box on the post edit screen.

What is the purpose of single_repeatable_meta_box_callback?

The single_repeatable_meta_box callback function defines what will be displayed in our meta box.

What is the purpose of get_post_meta?

The get_post_meta function allows us to retrieve custom fields from a post.

What is the purpose of wp_nonce_field?

The wp_nonce field function creates a hidden form field that contains a unique token. This helps prevent malicious users from submitting forms on your site.

Was this article helpful?


  1. I haven’t tried this as it looks like there is a quite a few typos. I can see repeater being spelt as ‘repeter’, ‘rapeter’, ‘rapater’ among other things.

Leave a comment

Your email address will not be published.