Как добавить Date Picker в динамические добавляемые/удаляемые поля (Repeater Fields)

6 июл. 2017 г., 17:42:35
Просмотры: 15.2K
Голосов: 0

Я создал Динамические добавляемые/удаляемые пользовательские поля (Repeater Fields) в своих пользовательских типах записей. Они работают отлично. Теперь я хочу добавить новое поле JQuery Date Picker. Я пытался написать код и искал в интернете, но безуспешно.

Пожалуйста, помогите.

Вот мой текущий код:

function project_rewards_select_options() {
    $options = array (
        'Option 1' => 'Опция 1',
        'Option 2' => 'Опция 2',
        'Option 3' => 'Опция 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%">Сумма вознаграждения</th>
            <th width="25%">Название вознаграждения</th>
            <th width="10%">Доставка</th>       
            <th width="45%">Описание вознаграждения</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="Удалить"  width="35" height="35"></td>
    </tr>

<?php } ?>

    <!-- пустая скрытая строка для 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="Удалить"  width="35" height="35"></td>
    </tr>

    </tbody>

    </table>

    <p><a id="add-row" class="button" href="#">Добавить вознаграждение</a></p>

<?php   

}

function save_project_reward( $post_id ) {

    // Проверяем наличие nonce
    if ( ! isset( $_POST['project_reward_nonce'] ) ) {
        return;
    }

    // Проверяем валидность nonce
    if ( ! wp_verify_nonce( $_POST['project_reward_nonce'], 'project_reward_nonce' ) ) {
        return;
    }

    // Если это автосохранение, ничего не делаем
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
        return;
    }

    // Проверяем права пользователя
    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' ); 
3
Комментарии

Зачем вы пытаетесь добавить свой собственный JQuery Date Picker, если ACF уже имеет это поле?

Cesar Henrique Damascena Cesar Henrique Damascena
6 июл. 2017 г. 17:47:13

Я не хочу использовать ACF

Minu Minu
6 июл. 2017 г. 18:05:36

Ой, извините, я ошибся, я подумал, что вы его используете

Cesar Henrique Damascena Cesar Henrique Damascena
6 июл. 2017 г. 18:23:42
Все ответы на вопрос 2
0

WordPress уже включает в себя jQuery datepicker, поэтому вы можете подключить стандартный скрипт WP. Однако, насколько мне известно, WP не включает необходимые стили для datepicker!
Попробуйте подключить скрипт WP и, например, стили из внешнего источника:

function my_datepicker_enqueue() {
            wp_enqueue_script( 'jquery-ui-datepicker' ); // подключаем datepicker из 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' );

Создайте новое HTML-поле ввода с как минимум классом и именем. HTML поля ввода: (у вас уже есть некоторые поля ввода, поэтому переходим к скрипту)

<input type="text" name="_custom_datepicker[]" id="_custom_datepicker[]" class="my-custom-datepicker-field" value="<?php echo $your_saved_value; ?>" />

Затем добавьте скрипт для инициализации datepicker для нашего нового элемента. Скрипт: (убедитесь, что вы указываете на правильный элемент ввода, здесь мы используем определенный класс, потому что хотим использовать несколько экземпляров.)

jQuery(document).ready(function($){
    $('.my-custom-datepicker-field').datepicker({
        dateFormat: 'dd-mm-yy', // возможно, вам нужно что-то вроде этого
        showButtonPanel: true
    });
});

Обновление:
Сначала у меня были проблемы с чтением вашего кода, и в вашем коде также есть несколько ошибок. Сначала я наблюдал такое же странное поведение. Теперь я настроил тестовый плагин на тестовом сайте, и там всё работает.

1: Вы настроили функцию сохранения так, что нельзя просто ввести дату и сохранить. Вам также нужно добавить сумму, заголовок или описание, чтобы можно было сохранить. Я думаю, это было вашим намерением?

2: В функции сохранения у вас есть следующий код:

if ( $reward_descriptions[$i] != '' ) :
    $reward_data[$i]['reward_date'] = stripslashes( $reward_dates[$i] );
endif;

То есть дата сохраняется только если поле описания не пустое?! Похоже, это была опечатка, потому что другие поля выглядят нормально. Измените на:

if ( $reward_data[$i] != '' ) :
    $reward_data[$i]['reward_date'] = stripslashes( $reward_dates[$i] );
endif;

3: В вашем коде обратного вызова у вас есть эти поля как 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>

и

<td><input type="text" class="my-custom-datepicker-field" name="_custom_datepicker[]" /></td>

Оба названы _custom_datepicker[]. Но в вашей функции сохранения вы пытаетесь сохранить поля под названием reward_date.

Кроме того, id должен быть уникальным. Но вы добавляете один и тот же id ко всем полям с датой. Вы можете просто удалить id из этих полей, он всё равно не нужен.

4. Если вы добавляете поля динамически, как вы хотите, вам нужно изменить JS-функцию datepicker. И вместо загрузки JS-кода встроенно (и несколько раз, как вы сделали), я рекомендую подключить один JS-файл. Попробуйте заменить ваш JS-код чем-то вроде этого:

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;
    });

    // изменено для использования с динамическим полем, которое добавляется и удаляется из DOM
    // если элемент с классом .my-custom-datepicker-field получает фокус, добавляем datepicker
    $(document).on('focus', '.my-custom-datepicker-field', function(){
        $(this).datepicker({
            dateFormat: 'dd-mm-yy', // возможно, вам нужно что-то вроде этого
            showButtonPanel: true
        });
    });

});

После того, как я исправил эти вещи и подключил JS-файл с кодом, как этого хочет WordPress, теперь всё работает.

7 июл. 2017 г. 15:07:07
1
-1

@LWS-Mo, Спасибо за помощь. Я добавил код как указано, но datepicker работает странно. Дата, выбранная в первом поле, отражается в последующих полях. Он работает неправильно.

Пожалуйста, подскажите, где я допустил ошибку. Ниже приведен код.

function project_rewards_select_options() {
    $options = array (
        'Option 1' => 'Option 1',
        'Option 2' => 'Option 2',
        'Option 3' => 'Option 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%">Сумма вознаграждения</th>
            <th width="25%">Название вознаграждения</th>
            <th width="10%">Доставка</th>
            <th width="20%">Дата</th>                  
            <th width="25%">Описание вознаграждения</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', //возможно вам нужно что-то вроде этого
        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="Удалить"  width="35" height="35"></td>
    </tr>

<?php } ?>

    <!-- пустая скрытая строка для 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', //возможно вам нужно что-то вроде этого
        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="Удалить"  width="35" height="35"></td>
    </tr>

    </tbody>

    </table>

    <p><a id="add-row" class="button" href="#">Добавить вознаграждение</a></p>

<?php   

}

function save_project_reward( $post_id ) {

    // Проверяем установлен ли nonce
    if ( ! isset( $_POST['project_reward_nonce'] ) ) {
        return;
    }

    // Проверяем валидность nonce
    if ( ! wp_verify_nonce( $_POST['project_reward_nonce'], 'project_reward_nonce' ) ) {
        return;
    }

    // Если это автосохранение, форма не была отправлена, поэтому ничего не делаем
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
        return;
    }

    // Проверяем права пользователя
    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 июл. 2017 г. 16:12:22
Комментарии

Извините, я не получил уведомления и только сейчас увидел, что вы пытались связаться со мной. Я обновлю свой ответ как можно скорее.

LWS-Mo LWS-Mo
13 окт. 2017 г. 17:19:01