Редактирование метаданных записи с помощью чекбоксов на фронтенде

9 авг. 2012 г., 19:26:44
Просмотры: 1.68K
Голосов: 2

Я пытаюсь создать интерфейс, чтобы два пользовательских поля для произвольного типа записи можно было редактировать на фронтенде с помощью чекбоксов. Мне нужно отображать пустые чекбоксы, если в этих полях нет значений, и позволить пользователю отмечать один или оба чекбокса, чтобы соответствующие поля установились в true (или просто получили какое-то значение - не уверен, может ли postmeta содержать булево значение) (желательно через AJAX).

Первая мысль - использовать плагин Scribu Front End Editor, хотя он явно не решает эту задачу без доработок. Однако я хотел спросить, не делал ли кто-то подобное раньше или может предложить способы адаптации плагина FEE для этих целей (или посоветовать другие решения).

Уточнение: это будет использоваться на странице со списком нескольких записей, поэтому я пытаюсь найти способ, чтобы это работало для более чем одной записи. Вот как выглядит страница сейчас:

Скриншот таблицы с чекбоксами для редактирования метаданных

И вот разметка для этой таблицы:

    <table>
                <thead>
                    <tr>
                        <th>Дата/Время</th>
                        <th>ID задания</th>
                        <th>Имя клиента</th>
                        <th>Размер файла</th>
                        <th>Детали</th>
                        <th>Скачать</th>
                        <th>Запланировано</th>
                        <th>Завершено</th>
                    </tr>
                </thead>
                <tr class="job">
                        <td>8/8/12 1:12pm</td>
                        <td>28</td>
                        <td>Selina Kyle</td>
                        <td>filesize</td>
                        <td><a href="http://example.com/jobs/selina-kyle/" target="_blank">Детали</a></td>
                        <td><a href="http://example.com/wp-content/uploads/gravity_forms/1-884e859c1f31e83338dbdaefd3bb2853/2012/08/CC-Content-Checklist.docx">Скачать файл</a></td>
                        <td><input type="checkbox" name="28-scheduled"  /></td> 
                        <td><input type="checkbox" name="28-completed"  /></td> 
                        <td><input type="hidden" name="post_id" value="28" /></td>
                        <td><span class="response"></span></td>
                </tr>
                <tr class="job">
                        <td>8/8/12 1:06pm</td>
                        <td>26</td>
                        <td>Jim Gordon</td>
                        <td>filesize</td>
                        <td><a href="http://example.com/jobs/jim-gordon/" target="_blank">Детали</a></td>
                        <td><a href="http://example.com/wp-content/uploads/gravity_forms/1-884e859c1f31e83338dbdaefd3bb2853/2012/08/Copy-Corner-Proposal-7-17-121.pdf">Скачать файл</a></td>
                        <td><input type="checkbox" name="26-scheduled"  /></td> 
                        <td><input type="checkbox" name="26-completed"  /></td> 
                        <td><input type="hidden" name="post_id" value="26" /></td>
                        <td><span class="response"></span></td>
                </tr>
                <tr class="job">
                        <td>8/8/12 1:05pm</td>
                        <td>25</td>
                        <td>Lucius Fox</td>
                        <td>filesize</td>
                        <td><a href="http://example.com/jobs/lucius-fox-2/" target="_blank">Детали</a></td>
                        <td><a href="http://example.com/wp-content/uploads/gravity_forms/1-884e859c1f31e83338dbdaefd3bb2853/2012/08/Process-and-deadlines-Copy-Corner2.pdf">Скачать файл</a></td>
                        <td><input type="checkbox" name="25-scheduled"  /></td> 
                        <td><input type="checkbox" name="25-completed"  /></td> 
                        <td><input type="hidden" name="post_id" value="25" /></td>
                        <td><span class="response"></span></td>
                </tr>
                <tr class="job">
                        <td>8/8/12 12:51pm</td>
                        <td>22</td>
                        <td>Bruce Wayne</td>
                        <td>filesize</td>
                        <td><a href="http://example.com/jobs/bruce-wayne-2/" target="_blank">Детали</a></td>
                        <td><a href="http://example.com/wp-content/uploads/gravity_forms/1-884e859c1f31e83338dbdaefd3bb2853/2012/08/CC-Wireframes1.pdf">Скачать файл</a></td>
                        <td><input type="checkbox" name="22-scheduled"  /></td> 
                        <td><input type="checkbox" name="22-completed"  /></td> 
                        <td><input type="hidden" name="post_id" value="22" /></td>
                        <td><span class="response"></span></td>
                </tr>
   </table>
2
Комментарии

Можете привести пример разметки страницы? Это поможет нам точнее определить селекторы для JS...

EAMann EAMann
10 авг. 2012 г. 22:29:07

@EAMann хорошее замечание. Я также добавил скриншот.

Travis Northcutt Travis Northcutt
10 авг. 2012 г. 22:48:35
Все ответы на вопрос 1
3

Мое первое побуждение — реализовать собственный AJAX-обработчик. Вы уже знаете ID записи (поскольку он есть на фронтенде) и названия полей, просто отправьте их обратно в WordPress с помощью AJAX и программно установите значения.

Непроверенный пример (спасибо Kailey Lampert):

// Добавляем чекбоксы к содержимому записи
add_filter( 'the_content', 'cba_add_checkboxes'); 
function cba_add_checkboxes( $c ) {

    $first = get_post_meta( get_the_ID(), 'first_item_key', true );
    $second = get_post_meta( get_the_ID(), 'second_item_key', true );

    $c .= '<p class="cba"><input type="checkbox"  name="test_value_1" '. checked( $first, 'true', false ) .' /><br />
    <input type="checkbox" name="test_value_2" '. checked( $second, 'true', false ) .' />
    <input type="hidden" name="post_id" value="'. get_the_ID() .'" /><br /><span class="response"></span></p>';

    return $c;
}
// Подключаем скрипты в футере
add_action('wp_footer', 'cba_script');
function cba_script() {
    wp_enqueue_script('jquery');
    ?><script>
    jQuery(function($) {
        var ajaxurl = '<?php echo admin_url( 'admin-ajax.php' ); ?>';
        var spinner = '<?php echo admin_url( 'images/loading.gif' ); ?>';
        $('.cba input').click( function() {
            var p = $(this).parent('p');
            p.find('.response').html('<img src="'+spinner+'" />');
            $.post(ajaxurl, {
                'action': 'update_custom_fields',
                'post_id': p.find('input[name="post_id"]').val(),
                'first_item': p.find('input[name="test_value_1"]').is(':checked'),
                'second_item': p.find('input[name="test_value_2"]').is(':checked')
            }, function( response ) {

                p.find('.response').html(response);

            }, 'text');
        });
    });
    </script><?php
}
// Добавляем обработчики AJAX-запросов в WordPress
add_action( 'wp_ajax_update_custom_fields', 'cba_update_custom_fields' ); // для авторизованных пользователей
add_action( 'wp_ajax_nopriv_update_custom_fields', 'cba_update_custom_fields' ); // для гостей
function cba_update_custom_fields() {
    $post_id = $_POST[ 'post_id' ];
    $first_item = $_POST[ 'first_item' ];
    $second_item = $_POST[ 'second_item' ];

    update_post_meta( $post_id, 'first_item_key', $first_item );
    update_post_meta( $post_id, 'second_item_key', $second_item );

    die( 'updated' );
}

Обновление на основе разметки

Теперь, когда мы больше знаем о том, что вы делаете, мы можем уточнить JS-код, который вам нужен.

В основном я рекомендую задать пользовательский класс и data-атрибуты для ваших чекбоксов. Например, вместо:

<td><input type="checkbox" name="28-scheduled"  /></td> 
<td><input type="checkbox" name="28-completed"  /></td> 

Используйте:

<td><input type="checkbox" name="28-scheduled" class="ajax-checkbox" data-post="28" data-type="scheduled" /></td> 
<td><input type="checkbox" name="28-completed" class="ajax-checkbox" data-post="28" data-type="completed" /></td> 

Теперь вы можете добавить обработчик событий jQuery для всей таблицы, который будет отслеживать изменения в каждом input:

jQuery(function($) {
    $('table').on('change', 'input.ajax-checkbox', function() {
        var $this = $(this), 
            type = $this.data('type'), 
            postID = $this.data('post');

        // ... Теперь отправьте AJAX-запрос, как в предыдущих примерах
    });
});

Этот обработчик будет ждать события change для всех элементов <input> с классом ajax-checkbox. Затем он извлечет значения, которые вы добавили в атрибуты data- (надеюсь, сгенерированные в PHP), чтобы отправить их в AJAX-запросе. Вам нужно будет объединить этот код с приведенными выше примерами или вашей текущей реализацией для отправки запросов.

9 авг. 2012 г. 19:53:15
Комментарии

Развивая идею @EAMann, вот демо/тестовый плагин, который добавляет несколько чекбоксов и сохраняет их выбор через ajax: https://gist.github.com/3308061

Kailey Lampert Kailey Lampert
9 авг. 2012 г. 21:11:03

@KaileyLampert вау, круто! У меня уже почти всё работает - единственная загвоздка в том, что я получаю ответ '0' вместо 'Updated'. Есть предложения, как это отладить?

Travis Northcutt Travis Northcutt
10 авг. 2012 г. 18:40:07

Думаю, часть моей проблемы в том, что я пытаюсь заставить это работать для нескольких записей на одной странице (см. мой правки выше), но javascript проверяет только отмечен ли input каждого типа, не проверя к какой именно записи относятся отмеченные чекбоксы. Правда, я не уверен как исправить эту ситуацию.

Travis Northcutt Travis Northcutt
10 авг. 2012 г. 22:11:46