Редактирование метаданных записи с помощью чекбоксов на фронтенде
Я пытаюсь создать интерфейс, чтобы два пользовательских поля для произвольного типа записи можно было редактировать на фронтенде с помощью чекбоксов. Мне нужно отображать пустые чекбоксы, если в этих полях нет значений, и позволить пользователю отмечать один или оба чекбокса, чтобы соответствующие поля установились в 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>

Мое первое побуждение — реализовать собственный 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-запросе. Вам нужно будет объединить этот код с приведенными выше примерами или вашей текущей реализацией для отправки запросов.

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

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

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