Skip to content

Instantly share code, notes, and snippets.

@ashokmhrj
Forked from helen/repeatable-fields-metabox.php
Last active March 25, 2024 03:39
Show Gist options
  • Save ashokmhrj/73229f77acad07c9130fab4bf2947b95 to your computer and use it in GitHub Desktop.
Save ashokmhrj/73229f77acad07c9130fab4bf2947b95 to your computer and use it in GitHub Desktop.
Repeating Custom Fields with Image Uploading and drag n drop in a Metabox
<?php
/**
* Repeatable Custom Fields in a Metabox with Image upload
* Drag and Drop option
* Modified by: ashokmhrj
* Extracted from: Helen Hou-Sandi
*/
define('PATH_TO_JS','define path here');
function ask_admin_repeater_script(){
wp_enqueue_media();
wp_enqueue_script( 'ask-admin-repeater-js', PATH_TO_JS . '/repeatable-fields.js', array('jquery'), '',true );
wp_localize_script( 'ask-admin-repeater-js', 'askAdmin', array(
'title' => __( "Choose an image", "ask" ),
'btn_txt' => __( "Use image", "ask" ),
) );
}
add_action( 'admin_enqueue_scripts', 'ask_admin_repeater_script' );
function ask_get_sample_options() {
$month = array ( '' => 'months' );
for( $i = 1; $i <= 12; $i++ ) {
$month[$i] = date('F', mktime(0,0,0,$i) );
}
$year = array ( '' => 'Year' );
foreach( range( 1990, date('Y') ) as $yr ) {
$year[$yr] = $yr;
}
return array( $month, $year );
}
add_action('add_meta_boxes_page', 'ask_history_add_meta_boxes', 10);
function ask_history_add_meta_boxes() {
add_meta_box(
'repeatable-fields', // id
'Repeatable Fields', //title
'ask_history_repeatable_meta_box_display', // cb
'page', // page
'normal', // context
'default' // priority
);
}
function ask_history_repeatable_meta_box_display() {
global $post;
$repeatable_fields = get_post_meta( $post->ID, 'repeatable_fields', true);
list( $month, $year ) = ask_get_sample_options();
wp_nonce_field( 'ask_history_repeatable_meta_box_nonce', 'ask_history_repeatable_meta_box_nonce' );
?>
<table id="repeatable-fieldset-one" width="100%">
<col width="30%">
<col width="30%">
<col width="30%">
<col width="10%">
<tbody id="ask-sortable">
<?php
if ( $repeatable_fields ) :
foreach ( $repeatable_fields as $key => $field ) {
$field['month'] = isset( $field['month'] )? $field['month'] : false;
$field['year'] = isset( $field['year'] )? $field['year'] : false;
$field['logo'] = isset( $field['logo'] )? $field['logo'] : false;
?>
<tr class="ui-state-default" style="border: 1px solid #e5e5e5; background: white; padding: 5px; height: 200px;">
<td class="ask-repeater-logo-wrapper">
<?php if($field['logo'] ) { ?>
<div>
<img src="<?php echo esc_url( $image = wp_get_attachment_thumb_url( $field['logo'] ) ); ?>" width="150px" height="150px" />
</div>
<?php } ?>
<input type="hidden" class="ask-logo" name="logo[]" value="<?php if( $field['logo'] != '') echo esc_attr( $field['logo'] ); ?>" />
<button type="button" class="ask-upload_image_button button" style="display:<?php echo ( $field['logo'] )? 'none' : 'block';?>"><?php _e( 'Add image', 'woocommerce' ); ?></button>
<button type="button" class="ask-remove_image_button button" style="display:<?php echo ( !$field['logo'] )? 'none' : 'block';?>;"><?php _e( 'Remove image', 'woocommerce' ); ?></button>
</td>
<td>
<textarea class="widefat" name="name[]" rows="6"><?php if($field['name'] != '') echo esc_attr( $field['name'] ); ?></textarea>
</td>
<td>
<div>
<strong>Month: </strong>
<select name="month[]" style="width:100%">
<?php foreach ( $month as $label => $value ) : ?>
<option value="<?php echo $value; ?>"<?php selected( $field['month'], $value ); ?>><?php echo $value; ?></option>
<?php endforeach; ?>
</select>
</div>
<div>
<strong>Year: </strong>
<select name="year[]" style="width:100%">
<?php foreach ( $year as $label => $value ) : ?>
<option value="<?php echo $value; ?>"<?php selected( $field['year'], $value ); ?>><?php echo $value; ?></option>
<?php endforeach; ?>
</select>
</div>
</td>
<td><a class="button remove-row" href="#"><span class="dashicons dashicons-trash"></span></a></td>
</tr>
<?php
}
else :
// show a blank one
?>
<tr class="ui-state-default" style="border: 1px solid #e5e5e5; background: white; padding: 5px; height: 200px;">
<td class="ask-repeater-logo-wrapper">
<input type="hidden" class="ask-logo" name="logo[]" />
<button type="button" class="ask-upload_image_button button"><?php _e( 'Add image', 'ask' ); ?></button>
<button type="button" class="ask-remove_image_button button" style="display:none;"><?php _e( 'Remove image', 'ask' ); ?></button>
</td>
<td>
<textarea class="widefat" name="name[]" rows="6"></textarea>
</td>
<td>
<div>
<strong>Month: </strong>
<select name="month[]" style="width:100%">
<?php foreach ( $month as $label => $value ) : ?>
<option value="<?php echo $value; ?>" ><?php echo $value; ?></option>
<?php endforeach; ?>
</select>
</div>
<div>
<strong>Year: </strong>
<select name="year[]" style="width:100%">
<?php foreach ( $year as $label => $value ) : ?>
<option value="<?php echo $value; ?>" ><?php echo $value; ?></option>
<?php endforeach; ?>
</select>
</div>
</td>
<td><a class="button remove-row" href="#"><span class="dashicons dashicons-trash"></span></a></td>
</tr>
<?php endif; ?>
<!-- empty hidden one for jQuery -->
<tr class="ui-state-default empty-row screen-reader-text" style="border: 1px solid #e5e5e5; background: white; padding: 5px; height: 200px;">
<td class="ask-repeater-logo-wrapper">
<input type="hidden" class="ask-logo" name="logo[]" />
<button type="button" class="ask-upload_image_button button"><?php _e( 'Add image', 'ask' ); ?></button>
<button type="button" class="ask-remove_image_button button" style="display:none;"><?php _e( 'Remove image', 'ask' ); ?></button>
</td>
<td>
<textarea class="widefat" name="name[]" rows="6"></textarea>
</td>
<td>
<div>
<strong>Month: </strong>
<select name="month[]" style="width:100%">
<?php foreach ( $month as $label => $value ) : ?>
<option value="<?php echo $value; ?>" ><?php echo $value; ?></option>
<?php endforeach; ?>
</select>
</div>
<div>
<strong>Year: </strong>
<select name="year[]" style="width:100%">
<?php foreach ( $year as $label => $value ) : ?>
<option value="<?php echo $value; ?>" ><?php echo $value; ?></option>
<?php endforeach; ?>
</select>
</div>
</td>
<td><a class="button remove-row" href="#"><span class="dashicons dashicons-trash"></span></a></td>
</tr>
</tbody>
</table>
<p><a id="add-row" class="button" href="#">Add another</a></p>
<?php
}
add_action('save_post', 'ask_history_repeatable_meta_box_save');
function ask_history_repeatable_meta_box_save($post_id) {
if ( ! isset( $_POST['ask_history_repeatable_meta_box_nonce'] ) || ! wp_verify_nonce( $_POST['ask_history_repeatable_meta_box_nonce'], 'ask_history_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();
list( $month, $year ) = ask_get_sample_options();
$names = $_POST['name'];
$month_arr = $_POST['month'];
$year_arr = $_POST['year'];
$logo = $_POST['logo'];
$count = count( $names );
for ( $i = 0; $i < $count; $i++ ) {
if ( $names[$i] != '' ) :
$new[$i]['name'] = stripslashes( strip_tags( $names[$i] ) );
if ( in_array( $month_arr[$i], $month ) )
$new[$i]['month'] = $month_arr[$i];
else
$new[$i]['month'] = '';
if ( in_array( $year_arr[$i], $year ) )
$new[$i]['year'] = $year_arr[$i];
else
$new[$i]['year'] = '';
if ( $logo[$i] == '' )
$new[$i]['logo'] = '';
else
$new[$i]['logo'] = abs( $logo[$i] );
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 );
}
var repeatable_field = {
init: function(){
this.addRow();
this.removeRow();
this.addImageUploader();
this.removeImage();
this.dragnDrop();
},
dragnDrop: function(){
jQuery("#ask-sortable").sortable();
jQuery("#ask-sortable").disableSelection();
},
addRow: function(){
jQuery(document).on('click', '#add-row', function (e) {
e.preventDefault();
var row = jQuery('.empty-row.screen-reader-text').clone(true);
row.removeClass('empty-row screen-reader-text');
row.insertBefore('#repeatable-fieldset-one tbody>tr:last');
// return false;
});
},
removeRow: function(){
jQuery(document).on('click', '.remove-row', function () {
jQuery(this).parents('tr').remove();
return false;
});
},
addImageUploader: function(){
jQuery(document).on('click', '.ask-upload_image_button', function (event) {
event.preventDefault();
var inputField = jQuery(this).prev('.nts-logo');
// Create the media frame.
var pevent = event,
button = jQuery(this),
file_frame = wp.media({
title: ntsAdmin.title,
library: {
type: 'image',
},
button: {
text: ntsAdmin.btn_txt
},
multiple: false
}).on('select', function () {
var attachment = file_frame.state().get('selection').first().toJSON();
var attachment_thumbnail = attachment.sizes.thumbnail || attachment.sizes.full;
button.closest('.ask-repeater-logo-wrapper').find('.ask-logo').val(attachment.id);
button.closest('.ask-repeater-logo-wrapper').find('.ask-logo').before('<div><img src="' + attachment_thumbnail.url + '" width="150px" height="150px" /></div>');
button.closest('.ask-repeater-logo-wrapper').find('.ask-remove_image_button').show();
button.hide();
}).open();
});
},
removeImage: function(){
jQuery(document).on('click', '.ask-remove_image_button', function (event) {
event.preventDefault();
jQuery(this).closest('.ask-repeater-logo-wrapper').find('.ask-logo').val('');
jQuery(this).closest('.ask-repeater-logo-wrapper').find('.ask-upload_image_button').show();
jQuery(this).hide();
jQuery(this).closest('.ask-repeater-logo-wrapper').find('div').remove();
});
}
};
jQuery(document).ready(function ($) {
repeatable_field.init();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment