Come aggiungere un Date Picker nei Campi Personalizzati Dinamici Aggiungi/Rimuovi (Repeater Fields)
Ho creato dei Campi Personalizzati Dinamici Aggiungi/Rimuovi (Repeater Fields) nei miei custom post type. Funzionano perfettamente. Ora voglio aggiungere un nuovo campo JQuery Date Picker. Ho provato a creare il codice e ho cercato sul web, ma senza successo.
Per favore aiutatemi.
Ecco il mio codice attuale.
function project_rewards_select_options() {
$options = array (
'Opzione 1' => 'Opzione 1',
'Opzione 2' => 'Opzione 2',
'Opzione 3' => 'Opzione 3',
);
return $options;
}
function project_reward_callback( $post ) {
wp_nonce_field( 'project_reward_nonce', 'project_reward_nonce' );
$reward_value = get_post_meta( get_the_ID(), '_project_rewards', true );
$options = project_rewards_select_options();
?>
<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="15%">Importo Ricompensa</th>
<th width="25%">Titolo Ricompensa</th>
<th width="10%">Spedizione</th>
<th width="45%">Descrizione Ricompensa</th>
<th width="5%"></th>
</tr>
</thead>
<tbody>
<?php
( $reward_value );
foreach ( $reward_value as $field ) {
?>
<tr>
<td><input type="text" class="widefat" name="reward[]" value="<?php if ( isset ( $field['reward'] ) ) echo esc_attr( $field['reward'] ); ?>" pattern="[1-9]\d*" /></td>
<td><input type="text" class="widefat" name="reward_title[]" value="<?php if ( isset ( $field['reward_title'] ) ) echo esc_attr( $field['reward_title'] ); ?>" /></td>
<td>
<select class="widefat" name="reward_shipping[]">
<?php foreach ( $options as $label => $value ) : ?>
<option value="<?php echo $value; ?>"<?php selected( $field['reward_shipping'], $value ); ?>><?php echo $label; ?></option>
<?php endforeach; ?>
</select>
</td>
<td><textarea class="widefat" name="reward_description[]"><?php if ( isset ( $field['reward_description'] ) ) echo esc_attr( $field['reward_description'] ); ?></textarea></td>
<td><input type="image" class="remove-row" src="<?php bloginfo('template_directory'); ?>/assets/images/remove-icon.png" alt="Rimuovi" width="35" height="35"></td>
</tr>
<?php } ?>
<!-- riga vuota nascosta per jQuery -->
<tr class="empty-row screen-reader-text">
<td><input type="text" class="widefat" name="reward[]" /></td>
<td><input type="text" class="widefat" name="reward_title[]" /></td>
<td>
<select class="widefat" name="reward_shipping[]">
<?php foreach ( $options as $label => $value ) : ?>
<option value="<?php echo $value; ?>"><?php echo $label; ?></option>
<?php endforeach; ?>
</select>
</td>
<td><textarea class="widefat" name="reward_description[]" ></textarea></td>
<td><input type="image" class="remove-row" src="<?php bloginfo('template_directory'); ?>/assets/images/remove-icon.png" alt="Rimuovi" width="35" height="35"></td>
</tr>
</tbody>
</table>
<p><a id="add-row" class="button" href="#">Aggiungi Ricompensa</a></p>
<?php
}
function save_project_reward( $post_id ) {
// Controlla se il nostro nonce è impostato
if ( ! isset( $_POST['project_reward_nonce'] ) ) {
return;
}
// Verifica che il nonce sia valido
if ( ! wp_verify_nonce( $_POST['project_reward_nonce'], 'project_reward_nonce' ) ) {
return;
}
// Se è un autosave, il form non è stato inviato, quindi non facciamo nulla
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
// Controlla i permessi dell'utente
if ( isset( $_POST['post_type'] ) && 'page' == $_POST['post_type'] ) {
if ( ! current_user_can( 'edit_page', $post_id ) ) {
return;
}
}
else {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
}
$reward_data = array();
$options = project_rewards_select_options();
$rewards = $_POST['reward'];
$reward_titles = $_POST['reward_title'];
$reward_shippings = $_POST['reward_shipping'];
$reward_descriptions = $_POST['reward_description'];
$count = count( $rewards );
for ( $i = 0; $i < $count; $i++ ) {
if ( $rewards[$i] != '' ) :
$reward_data[$i]['reward'] = stripslashes( strip_tags( $rewards[$i] ) );
if ( in_array( $reward_shippings[$i], $options ) )
$reward_data[$i]['reward_shipping'] = stripslashes( strip_tags( $reward_shippings[$i] ) );
else
$reward_data[$i]['reward_shipping'] = '';
endif;
if ( $reward_titles[$i] != '' ) :
$reward_data[$i]['reward_title'] = stripslashes( strip_tags( $reward_titles[$i] ) );
endif;
if ( $reward_descriptions[$i] != '' ) :
$reward_data[$i]['reward_description'] = stripslashes( $reward_descriptions[$i] );
endif;
}
update_post_meta( $post_id, '_project_rewards', $reward_data );
}
add_action( 'save_post', 'save_project_reward' );

WordPress include già il datepicker di jQuery. Quindi puoi accodare lo script predefinito di WP. Tuttavia, per quanto ne so, WP non include lo stile necessario per il datepicker!
Quindi prova ad accodare lo script di WP e, ad esempio, gli stili da una fonte esterna:
function my_datepicker_enqueue() {
wp_enqueue_script( 'jquery-ui-datepicker' ); // accoda il datepicker da WP
wp_enqueue_style( 'jquery-ui-style', '//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/base/jquery-ui.css', true);
}
add_action( 'admin_enqueue_scripts', 'my_datepicker_enqueue' );
Crea un nuovo campo di input HTML con almeno una classe e un nome. HTML del campo di input: (hai già alcuni campi di input definiti, quindi passa direttamente allo script)
<input type="text" name="_custom_datepicker[]" id="_custom_datepicker[]" class="my-custom-datepicker-field" value="<?php echo $your_saved_value; ?>" />
Quindi aggiungi uno script per inizializzare il datepicker per il nostro nuovo elemento. Script: (assicurati di puntare al giusto elemento di input, stiamo guardando alla classe definita qui, perché vogliamo usare più istanze.)
jQuery(document).ready(function($){
$('.my-custom-datepicker-field').datepicker({
dateFormat: 'dd-mm-yy', // forse vuoi qualcosa come questo
showButtonPanel: true
});
});
Aggiornamento:
All'inizio ho avuto alcuni problemi a leggere il tuo codice, e hai anche diversi errori nel tuo codice. All'inizio ho visto lo stesso strano comportamento. Ho ora impostato un testplugin su un sito di sviluppo, e ora funziona.
1: Hai impostato la tua funzione di salvataggio in modo che non puoi semplicemente inserire una data e salvare. Dovrai inserire anche un importo, un titolo o una descrizione per poter salvare. Penso che questo sia voluto da te?
2: Nella funzione di salvataggio hai il seguente codice:
if ( $reward_descriptions[$i] != '' ) :
$reward_data[$i]['reward_date'] = stripslashes( $reward_dates[$i] );
endif;
Quindi solo quando il campo descrizione non è vuoto la data verrà salvata?! Sembra che questo sia stato un errore di battitura perché gli altri campi sembrano corretti. Cambia in:
if ( $reward_data[$i] != '' ) :
$reward_data[$i]['reward_date'] = stripslashes( $reward_dates[$i] );
endif;
3: Nel tuo codice di callback hai questi campi come campi datepicker:
<td><input type="text" name="_custom_datepicker[]" id="_custom_datepicker[]" class="my-custom-datepicker-field" value="<?php echo esc_attr( $field['reward_date'] ); ?>" /></td>
e
<td><input type="text" class="my-custom-datepicker-field" name="_custom_datepicker[]" /></td>
Entrambi chiamati _custom_datepicker[]
.
Ma nella tua funzione di salvataggio provi a salvare campi chiamati reward_date
invece.
Inoltre l'id
dovrebbe essere unico. Ma aggiungi lo stesso id
a tutti i campi data.
Potresti semplicemente rimuovere l'id
da questi campi, non è necessario comunque.
4. Se aggiungi campi dinamicamente come vuoi, devi cambiare la funzione JS del datepicker. E invece di caricare il codice JS inline (e più volte come hai fatto), ti consiglio di accodare un file JS. Quindi prova a sostituire il tuo codice JS con qualcosa come questo:
jQuery(document).ready(function($){
// il tuo codice predefinito
$( '#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;
});
//cambiato per essere usato su campi dinamici che vengono aggiunti e rimossi dal DOM
//se l'elemento con la classe .my-custom-datepicker-field riceve il focus, aggiungi il datepicker
$(document).on('focus', '.my-custom-datepicker-field', function(){
$(this).datepicker({
dateFormat: 'dd-mm-yy', // forse vuoi qualcosa come questo
showButtonPanel: true
});
});
});
Dopo aver corretto queste cose e accodato il file JS con il codice come WordPress vuole che sia, ora funziona.

@LWS-Mo,
Grazie per l'aiuto. Ho aggiunto i codici come indicato ma il datepicker si comporta in modo strano. La data selezionata nel primo campo viene riflessa nei campi successivi. Non funziona correttamente.
Per favore dimmi dove sto sbagliando. Di seguito il codice.
function project_rewards_select_options() {
$options = array (
'Opzione 1' => 'Opzione 1',
'Opzione 2' => 'Opzione 2',
'Opzione 3' => 'Opzione 3',
);
return $options;
}
function crazicle_project_reward_callback( $post ) {
wp_nonce_field( 'project_reward_nonce', 'project_reward_nonce' );
$reward_value = get_post_meta( get_the_ID(), '_project_rewards', true );
$options = project_rewards_select_options();
?>
<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="15%">Importo Ricompensa</th>
<th width="25%">Titolo Ricompensa</th>
<th width="10%">Spedizione</th>
<th width="20%">Data</th>
<th width="25%">Descrizione Ricompensa</th>
<th width="5%"></th>
</tr>
</thead>
<tbody>
<?php
( $reward_value );
foreach ( $reward_value as $field ) {
?>
<tr>
<td><input type="text" class="widefat" name="reward[]" value="<?php if ( isset ( $field['reward'] ) ) echo esc_attr( $field['reward'] ); ?>" pattern="[1-9]\d*" /></td>
<td><input type="text" class="widefat" name="reward_title[]" value="<?php if ( isset ( $field['reward_title'] ) ) echo esc_attr( $field['reward_title'] ); ?>" /></td>
<td>
<select class="widefat" name="reward_shipping[]">
<?php foreach ( $options as $label => $value ) : ?>
<option value="<?php echo $value; ?>"<?php selected( $field['reward_shipping'], $value ); ?>><?php echo $label; ?></option>
<?php endforeach; ?>
</select>
</td>
<script type="text/javascript">
jQuery(document).ready(function($){
$('.my-custom-datepicker-field').datepicker({
dateFormat: 'dd-mm-yy', //forse vuoi qualcosa come questo
showButtonPanel: true
});
});
</script>
<td><input type="text" name="_custom_datepicker[]" id="_custom_datepicker[]" class="my-custom-datepicker-field" value="<?php echo esc_attr( $field['reward_date'] ); ?>" /></td>
<td><textarea class="widefat" name="reward_description[]"><?php if ( isset ( $field['reward_description'] ) ) echo esc_attr( $field['reward_description'] ); ?></textarea></td>
<td><input type="image" class="remove-row" src="<?php bloginfo('template_directory'); ?>/assets/images/remove-icon.png" alt="Rimuovi" width="35" height="35"></td>
</tr>
<?php } ?>
<!-- riga vuota nascosta per jQuery -->
<tr class="empty-row screen-reader-text">
<td><input type="text" class="widefat" name="reward[]" /></td>
<td><input type="text" class="widefat" name="reward_title[]" /></td>
<td>
<select class="widefat" name="reward_shipping[]">
<?php foreach ( $options as $label => $value ) : ?>
<option value="<?php echo $value; ?>"><?php echo $label; ?></option>
<?php endforeach; ?>
</select>
</td>
<script type="text/javascript">
jQuery(document).ready(function($){
$('.my-custom-datepicker-field').datepicker({
dateFormat: 'dd-mm-yy', //forse vuoi qualcosa come questo
showButtonPanel: true
});
});
</script>
<td><input type="text" class="my-custom-datepicker-field" name="_custom_datepicker[]" /></td>
<td><textarea class="widefat" name="reward_description[]" ></textarea></td>
<td><input type="image" class="remove-row" src="<?php bloginfo('template_directory'); ?>/assets/images/remove-icon.png" alt="Rimuovi" width="35" height="35"></td>
</tr>
</tbody>
</table>
<p><a id="add-row" class="button" href="#">Aggiungi Ricompensa</a></p>
<?php
}
function save_project_reward( $post_id ) {
// Verifica se il nonce è impostato
if ( ! isset( $_POST['project_reward_nonce'] ) {
return;
}
// Verifica che il nonce sia valido
if ( ! wp_verify_nonce( $_POST['project_reward_nonce'], 'project_reward_nonce' ) ) {
return;
}
// Se è un autosalvataggio, il form non è stato inviato, quindi non facciamo nulla
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
// Verifica i permessi dell'utente
if ( isset( $_POST['post_type'] ) && 'page' == $_POST['post_type'] ) {
if ( ! current_user_can( 'edit_page', $post_id ) ) {
return;
}
}
else {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
}
$reward_data = array();
$options = project_rewards_select_options();
$rewards = $_POST['reward'];
$reward_titles = $_POST['reward_title'];
$reward_shippings = $_POST['reward_shipping'];
$reward_dates = $_POST['reward_date'];
$reward_descriptions = $_POST['reward_description'];
$count = count( $rewards );
for ( $i = 0; $i < $count; $i++ ) {
if ( $rewards[$i] != '' ) :
$reward_data[$i]['reward'] = stripslashes( strip_tags( $rewards[$i] ) );
if ( in_array( $reward_shippings[$i], $options ) )
$reward_data[$i]['reward_shipping'] = stripslashes( strip_tags( $reward_shippings[$i] ) );
else
$reward_data[$i]['reward_shipping'] = '';
endif;
if ( $reward_titles[$i] != '' ) :
$reward_data[$i]['reward_title'] = stripslashes( strip_tags( $reward_titles[$i] ) );
endif;
if ( $reward_descriptions[$i] != '' ) :
$reward_data[$i]['reward_description'] = stripslashes( $reward_descriptions[$i] );
endif;
if ( $reward_descriptions[$i] != '' ) :
$reward_data[$i]['reward_date'] = stripslashes( $reward_dates[$i] );
endif;
}
update_post_meta( $post_id, '_project_rewards', $reward_data );
}
add_action( 'save_post', 'save_project_reward' );
