Cum să adaugi un Date Picker în Câmpuri Personalizate Dinamice (Repeater Fields)

6 iul. 2017, 17:42:35
Vizualizări: 15.2K
Voturi: 0

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' );
3
Comentarii

De ce încerci să adaugi propriul tău selector de dată JQuery dacă ACF are deja acest câmp?

Cesar Henrique Damascena Cesar Henrique Damascena
6 iul. 2017 17:47:13

Nu vreau să folosesc ACF

Minu Minu
6 iul. 2017 18:05:36

Oh, scuze, am înțeles greșit, am crezut că îl folosești

Cesar Henrique Damascena Cesar Henrique Damascena
6 iul. 2017 18:23:42
Toate răspunsurile la întrebare 2
0

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.

7 iul. 2017 15:07:07
1
-1

@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' );
7 iul. 2017 16:12:22
Comentarii

Îmi pare rău, nu am primit notificare, abia acum am văzut că ai încercat să mă contactezi. Voi actualiza răspunsul meu cât mai curând posibil.

LWS-Mo LWS-Mo
13 oct. 2017 17:19:01