Create Nested Repeater Meta Box in WordPress

Create Nested Repeater Meta Box in WordPress

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

<?php
// Add Meta Box to post
add_action('admin_init', 'nested_repeter_callback', 2);

function nested_repeter_callback() {
	add_meta_box( 'nested-repeter-data', 'Nested Repeter', 'nested_repeter_meta_box_callback', 'post', 'normal', 'default');
}

function nested_repeter_meta_box_callback($post) {
	$change_logs = get_post_meta($post->ID, 'nested_repeter_group', true);

	wp_nonce_field( 'nestedRepeaterLog', 'formType' );
	?>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.repeater/1.2.1/jquery.repeater.min.js"></script>
	<style>
		#nested_repeter table, #nested_repeter table input{ width: 100%; }
		td.inner_tr > tr { display: table; width: 100%; }
		td.inner_td tr { display: table; width: 100%; }
	</style>
	<div id="nested_repeter">
		<table>
			<tbody>
				<tr class="wc-repeater">
					<td data-repeater-list="change-log" class="inner_td">
						<?php if(!empty($change_logs)) { ?>
							<?php foreach($change_logs as $change_log) { 

								?>
								<table data-repeater-item>
									<tr>
										<td class="inner-outer-repeater">
											<table>
												<tr>
													<td><input type="text" name="version" value="<?php echo $change_log['version']; ?>" placeholder="Version" /></td>
													<td><input type="date" name="date" value="<?php echo $change_log['date']; ?>"/></td>
													<td><input data-repeater-delete class="button"  type="button" value="-" /></td>
												</tr>
											</table>
										</td>
										<!-- innner repeater -->
										<td class="inner-repeater">
											<table>
												<tr>
													<td data-repeater-list="notes" class="inner_tr">
														<?php if(!empty($change_log['inner-list'])) { ?>
															<?php foreach($change_log['inner-list'] as $note) { 
																?>
																<table data-repeater-item>
																	<tr>
																		<td><select class="form-select" aria-label="change-version" name="type">
																			<option selected>Open this select version</option>
																			<option value="New" <?php if($note['type'] == "New"){ echo "selected"; }; ?>>New</option>
																			<option value="Update" <?php if($note['type'] == "Update"){ echo "selected"; }; ?>>Update</option>
																			<option value="Fixed" <?php if($note['type'] == "Fixed"){ echo "selected"; }; ?>>Fixed</option>
																			<option value="Added" <?php if($note['type'] == "Added"){ echo "selected"; }; ?>>Added</option>
																			<option value="Removed" <?php if($note['type'] == "Removed"){ echo "selected"; }; ?>>Removed</option>
																		</select></td>

																		<td><input type="text" name="note" value="<?php echo $note['note']; ?>" placeholder="Note" /></td>
																		<td><input data-repeater-delete class="button"  type="button" value="-" /></td>
																	</tr>
																</table>
															<?php } ?>
														<?php } else if(!empty($change_log['notes'])){
															foreach($change_log['notes'] as $note) { 
																?>
																<table data-repeater-item>
																	<tr>
																		<td><select class="form-select" aria-label="change-version" name="type">
																			<option selected>Open this select version</option>
																			<option value="New" <?php if($note['type'] == "New"){ echo "selected"; }; ?>>New</option>
																			<option value="Update" <?php if($note['type'] == "Update"){ echo "selected"; }; ?>>Update</option>
																			<option value="Fixed" <?php if($note['type'] == "Fixed"){ echo "selected"; }; ?>>Fixed</option>
																			<option value="Added" <?php if($note['type'] == "Added"){ echo "selected"; }; ?>>Added</option>
																			<option value="Removed" <?php if($note['type'] == "Removed"){ echo "selected"; }; ?>>Removed</option>
																		</select></td>

																		<td><input type="text" name="note" value="<?php echo $note['note']; ?>" placeholder="Note" /></td>
																		<td><input data-repeater-delete class="button"  type="button" value="-" /></td>
																	</tr>
																</table>
															<?php }

														}else { ?>
															<table data-repeater-item>
																<tr>
																	<td>
																		<select class="form-select" aria-label="change-version" name="type">
																			<option >Open this select menu</option>
																			<option value="New">New</option>
																			<option value="Update">Update</option>
																			<option value="Fixed">Fixed</option>
																			<option value="Added">Added</option>
																			<option value="Removed">Removed</option>
																		</select>
																	</td>
																	<td><input type="text" name="note" value="" placeholder="Note" /></td>
																	<td><input data-repeater-delete class="button"  type="button" value="-" /></td>
																</tr>
															</table>
														<?php } ?>
													</td>
													<td><input class="button" data-repeater-create type="button" value="+"/></td>
												</tr>
											</table>
										</td>
									</tr>
								</table>
							<?php } ?>
						<?php } else { ?>
							<table data-repeater-item>
								<tr>
									<td class="inner-outer-repeater">
										<table>
											<tr>
												<td><input type="text" name="version" value="" placeholder="Version" /></td>
												<td><input type="date" name="date" value=""/></td>
												<td><input data-repeater-delete class="button"  type="button" value="-" /></td>
											</tr>
										</table>
									</td>
									<!-- innner repeater -->
									<td class="inner-repeater">
										<table>
											<tr>
												<td data-repeater-list="inner-list" class="inner_tr">
													<table data-repeater-item>
														<tr>
															<td>
																<select class="form-select" aria-label="change-version" name="type">
																	<option >Open this select menu</option>
																	<option value="New">New</option>
																	<option value="Update">Update</option>
																	<option value="Fixed">Fixed</option>
																	<option value="Added">Added</option>
																	<option value="Removed">Removed</option>
																</select>
															</td>
															<td><input type="text" name="note" value="" placeholder="Note" /></td>
															<td><input data-repeater-delete class="button"  type="button" value="-" /></td>
														</tr>
													</table>
												</td>
												<td><input class="button" data-repeater-create type="button" value="+"/></td>
											</tr>
										</table>
									</td>
								</tr>
							</table>
						<?php } ?>
					</td>
					<td><input data-repeater-create class="button"  type="button" value="+"/></td>
				</tr>
			</tbody>
		</table>
	</div>

	<script type="text/javascript">
		jQuery(document).ready(function () {
			jQuery('.wc-repeater').repeater(
			{
				repeaters: [{
					selector: '.inner-repeater'
				}]
			});
		});
	</script>
	<?php
}

// Save Meta Box values.
add_action('save_post', 'nested_repeter_meta_box_save');

function nested_repeter_meta_box_save($post_id) {

	if (!isset($_POST['formType']) && !wp_verify_nonce($_POST['formType'], 'nestedRepeaterLog'))
		return;

	if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
		return;

	if (!current_user_can('edit_post', $post_id))
		return;

	update_post_meta( $post_id, 'nested_repeter_group', $_POST['change-log'] );

}

Use below code to show metabox values from anywhere

<?php
// Use below code to show metabox values from anywhere
$id = get_the_ID();
$change_logs = get_post_meta($id, 'nested_repeter_group', true);

if(!empty($change_logs)) {
	?>
	<table class="plugin-detail-tabl <?php echo $class; ?>" width="100%" cellspacing="0" cellpadding="0">
		<tbody>
			<?php 
			$change_logs = array_reverse($change_logs);
			foreach ($change_logs as  $item) { 
				?>
				<div class="change_log">
					<h2><?php echo $item['version']; ?></h2>
					<p><?php echo date("F j, Y", strtotime($item["date"])); ?></p>
					<?php foreach ($item['notes'] as  $items) {
						$add_cls = '';
						$color_arr = array('New','Update','Fixed','Added','Removed');
						?>
						<div class="rn-desc">
							<p><span class="type_color <?php echo (in_array($items['type'],$color_arr)) ? 'color_'.$items['type'] : ''; ?>"><?php echo $items['type']; ?></span></p>
							<h5><?php echo $items['note']; ?></h5>
						</div>
					<?php } ?>
				</div>
			<?php } ?>
		</tbody>
	</table>
	<?php
}
Was this article helpful?
YesNo

1 comment

Leave a comment

Your email address will not be published. Required fields are marked *