Cum să adaugi un Date Picker în Câmpuri Personalizate Dinamice (Repeater Fields)
Am creat Câmpuri Personalizate Dinamice (Repeater Fields) în tipurile mele custom de postări. Funcționează perfect. Vreau să adaug un nou câmp JQuery Date Picker. Am încercat să creez codul și am căutat pe internet fără succes.
Vă rog să mă ajutați.
Mai jos este codul meu.
function project_rewards_select_options() {
$options = array (
'Opțiunea 1' => 'Opțiunea 1',
'Opțiunea 2' => 'Opțiunea 2',
'Opțiunea 3' => 'Opțiunea 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;
});
// Inițializare Date Picker pentru toate câmpurile existente
$( '.date-picker' ).datepicker();
});
</script>
<table id="repeatable-fieldset-one" width="100%">
<thead>
<tr>
<th width="15%">Suma recompensă</th>
<th width="25%">Titlu recompensă</th>
<th width="10%">Livrare</th>
<th width="15%">Dată limită</th>
<th width="30%">Descriere recompensă</th>
<th width="5%"></th>
</tr>
</thead>
<tbody>
<?php
if ( $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><input type="text" class="widefat date-picker" name="reward_date[]" value="<?php if ( isset ( $field['reward_date'] ) ) 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="Șterge" width="35" height="35"></td>
</tr>
<?php } } ?>
<!-- Șablon ascuns pentru 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><input type="text" class="widefat date-picker" name="reward_date[]" /></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="Șterge" width="35" height="35"></td>
</tr>
</tbody>
</table>
<p><a id="add-row" class="button" href="#">Adaugă recompensă</a></p>
<?php
}
function save_project_reward( $post_id ) {
// Verifică dacă nonce-ul este setat
if ( ! isset( $_POST['project_reward_nonce'] ) {
return;
}
// Verifică dacă nonce-ul este valid
if ( ! wp_verify_nonce( $_POST['project_reward_nonce'], 'project_reward_nonce' ) ) {
return;
}
// Dacă e autosave, nu facem nimic
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
// Verifică permisiunile utilizatorului
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'] = '';
}
if ( $reward_titles[$i] != '' ) {
$reward_data[$i]['reward_title'] = stripslashes( strip_tags( $reward_titles[$i] ) );
}
if ( $reward_dates[$i] != '' ) {
$reward_data[$i]['reward_date'] = stripslashes( strip_tags( $reward_dates[$i] ) );
}
if ( $reward_descriptions[$i] != '' ) {
$reward_data[$i]['reward_description'] = stripslashes( $reward_descriptions[$i] );
}
}
update_post_meta( $post_id, '_project_rewards', $reward_data );
}
add_action( 'save_post', 'save_project_reward' );

WordPress are deja inclus jQuery datepicker. Deci poți încărca scriptul implicit din WP. Totuși, din câte știu, WP nu include stilurile necesare pentru datepicker!
Încearcă să încarci scriptul WP și, de exemplu, stilurile dintr-o sursă externă:
function my_datepicker_enqueue() {
wp_enqueue_script( 'jquery-ui-datepicker' ); // încarcă datepicker din 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' );
Creează un nou câmp de input HTML cu cel puțin o clasă și un nume. HTML pentru câmpul de input: (ai deja câteva câmpuri definite, așa că treci direct la script)
<input type="text" name="_custom_datepicker[]" id="_custom_datepicker[]" class="my-custom-datepicker-field" value="<?php echo $your_saved_value; ?>" />
Apoi adaugă un script pentru a inițializa datepicker pentru noul element. Script: (asigură-te că ai țintit câmpul corect, folosim clasa definită aici pentru a putea folosi mai multe instanțe.)
jQuery(document).ready(function($){
$('.my-custom-datepicker-field').datepicker({
dateFormat: 'dd-mm-yy', // poate dorești ceva de genul acesta
showButtonPanel: true
});
});
Actualizare:
Am avut inițial probleme în înțelegerea codului tău și ai și câteva erori în cod. La început am observat același comportament ciudat. Am configurat acum un plugin de test pe un site de dezvoltare, iar acum funcționează corect.
1: Ai configurat funcția de salvare astfel încât nu poți introduce doar o dată și să salvezi. Trebuie să introduci și o sumă, titlu sau descriere pentru a putea salva. Presupun că asta ai dorit?
2: În funcția de salvare ai următorul cod:
if ( $reward_descriptions[$i] != '' ) :
$reward_data[$i]['reward_date'] = stripslashes( $reward_dates[$i] );
endif;
Deci data va fi salvată doar dacă câmpul de descriere nu este gol?! Se pare că a fost o greșeală, deoarece celelalte câmpuri arată bine. Schimbă în:
if ( $reward_data[$i] != '' ) :
$reward_data[$i]['reward_date'] = stripslashes( $reward_dates[$i] );
endif;
3: În codul tău de callback ai aceste câmpuri ca 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>
și
<td><input type="text" class="my-custom-datepicker-field" name="_custom_datepicker[]" /></td>
Ambele numite _custom_datepicker[]
.
Dar în funcția de salvare încerci să salvezi câmpuri numite reward_date
în loc.
De asemenea, id
-ul ar trebui să fie unic. Dar adaugi același id
la toate câmpurile de dată.
Poți să elimini id
din aceste câmpuri, oricum nu este necesar.
4. Dacă adaugi câmpuri dinamic cum dorești, trebuie să modifici funcția JS pentru datepicker. Și în loc să încarci codul JS inline (și de mai multe ori cum ai făcut), recomand să încarci un singur fișier JS. Încearcă să înlocuiești codul JS cu ceva de genul:
jQuery(document).ready(function($){
// codul tău implicit
$( '#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;
});
// modificat pentru a funcționa pe câmpuri dinamice adăugate și eliminate din DOM
// dacă elementul cu clasa .my-custom-datepicker-field primește focus, adaugă datepicker
$(document).on('focus', '.my-custom-datepicker-field', function(){
$(this).datepicker({
dateFormat: 'dd-mm-yy', // poate dorești ceva de genul acesta
showButtonPanel: true
});
});
});
După ce am corectat aceste lucruri și am încărcat fișierul JS cu codul așa cum dorește WordPress, acum funcționează corect.

@LWS-Mo, Mulțumesc pentru ajutor. Am adăugat codurile conform instrucțiunilor, dar selectorul de date nu funcționează corect. Data selectată în primul câmp se reflectă în câmpurile ulterioare. Nu funcționează cum trebuie.
Te rog să-mi spui unde greșesc. Mai jos este codul.
function project_rewards_select_options() {
$options = array (
'Opțiunea 1' => 'Opțiunea 1',
'Opțiunea 2' => 'Opțiunea 2',
'Opțiunea 3' => 'Opțiunea 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%">Suma recompensei</th>
<th width="25%">Titlul recompensei</th>
<th width="10%">Livrare</th>
<th width="20%">Data</th>
<th width="25%">Descrierea recompensei</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', //poate doriți ceva de genul acesta
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="Șterge" width="35" height="35"></td>
</tr>
<?php } ?>
<!-- rând gol ascuns pentru 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', //poate doriți ceva de genul acesta
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="Șterge" width="35" height="35"></td>
</tr>
</tbody>
</table>
<p><a id="add-row" class="button" href="#">Adaugă recompensă</a></p>
<?php
}
function save_project_reward( $post_id ) {
// Verifică dacă nonce-ul nostru este setat
if ( ! isset( $_POST['project_reward_nonce'] ) ) {
return;
}
// Verifică dacă nonce-ul este valid
if ( ! wp_verify_nonce( $_POST['project_reward_nonce'], 'project_reward_nonce' ) ) {
return;
}
// Dacă acesta este un autosave, formularul nostru nu a fost trimis, așa că nu vrem să facem nimic
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
// Verifică permisiunile utilizatorului
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' );
