Ajax не выводится в модальный Ctools при использовании пейджера
Итак, в моем продолжающемся поиске для отображения формы с результатами поиска Solr в модальном окне Ctools и использования пейджера мне удалось добиться того, чтобы все отображалось нормально после первоначального поиска, но когда я использую пейджер, я получаю белый экран с данными в формате json вместо всего, что снова отображается в модальном режиме. Вот соответствующий код:
function imgsearch_page($ajax, $id, $a, $b) {
if ($ajax) {
//Load the modal library and add the modal javascript.
ctools_include('ajax');
ctools_include('modal');
$form_state = array(
'ajax' => TRUE,
'title' => t('Image Search Form'),
'next_field_id' => $id,
);
// Use ctools to generate ajax instructions for the browser to create
// a form in a modal popup.
$search_form = ctools_modal_form_wrapper('imgsearch_form', $form_state);
if (($form_state['executed'] && $form_state['ajax']) || isset($_GET['page'])) {
// If the form has been submitted, there may be additional instructions
// such as dismissing the modal popup.
if (!empty($form_state['ajax_commands'])) {
$output = $form_state['ajax_commands'];
}
if ($form_state['values']['search_terms'] != '' || isset($_GET['search_terms'])) {
$page_num = isset($_GET['page']) ? $_GET['page'] : 0;
if ($_GET['search_terms']) {
$form_state['values']['search_terms'] = $_GET['search_terms'];
}
$results = nb_image_search_search($form_state['values'], $page_num);
if (is_array($results['images']) && count($results['images'] > 0)) {
$next_field_id = $form_state['next_field_id'];
// Create object to store file and target field info. To be stored in ctools cache.
$file_info = new stdClass();
// Generate the field name. field_images is a multivalue field collection, so we just need the next available option
// in the $field_images['und'] array. The second number (for field_image) will always be 0 since it
// is a single value field.
$file_info->fieldname['url'] = '#edit-field-images-und-' . $next_field_id . '-field-image-und-0-imgsearch-file-url';
$file_info->fieldname['person'] = '#edit-field-images-und-' . $next_field_id . '-field-person-und-0-value';
$file_info->fieldname['organization'] = '#edit-field-images-und-' . $next_field_id . '-field-organization-und-0-value';
$file_info->fieldname['year'] = '#edit-field-images-und-' . $next_field_id . '-field-year-und-0-value';
$file_info->fids = array();
// Theme the results as a table.
$header = array(t('Image'), t('File Name'), t('Add to field'));
$rows = array();
foreach ($results['images'] as $image) {
// Create image style derivative for each image.
$imagestyle = array(
'style_name' => 'thumbnail',
'path' => $image['filepath'] . $image['filename'],
'width' => '',
'height' => '',
'alt' => '',
'title' => $image['filename'],
);
$styled_image = theme('image_style', $imagestyle);
$fid = $image['fid'];
$rows[] = array(
'image' => $styled_image,
'name' => $image['filename'],
'add' => ctools_ajax_text_button("select", "imgsearch/nojs/imgadd/" . $fid . '/' . $next_field_id, t('Select')),
);
$file_info->fids[$fid] = $image['filename'];
// Cache values for Person, Organization, and Year if they exist.
foreach (array('person', 'organization', 'year') as $field) {
if (isset($image[$field])) {
$file_info->meta[$fid][$field] = $image[$field];
}
}
}
//Cache image name in ctools object cache so it can be used later in nb_image_search_image_add()
ctools_include('object-cache');
ctools_object_cache_set('imgsearch', 'imgsearch_' . $next_field_id, $file_info);
// Create a render array ($build) which will be themed as a table with a
// pager.
$build['search_form'] = isset($search_form[0]) ? drupal_build_form('imgsearch_form', $form_state) : $search_form;
$build['imgsearch_table'] = array(
'#theme' => 'table',
'#header' => $header,
'#rows' => $rows,
'#empty' => t('There were no matching results found'),
);
// Attach the pager theme.
$pager = pager_default_initialize($results['total_found'], $results['rows']);
$build['imgsearch_pager'] = array(
'#theme' => 'pager',
'#parameters' => array(
'search_terms' => $form_state['values']['search_terms'],
//TODO: add params for Person, Organization, and Year.
),
);
$form_state['values']['title'] = t('Search Results');
$output = ctools_modal_form_render($form_state['values'], $build);
print ajax_render($output);
drupal_exit();
}
else {
$build['no_results'] = array(
'markup' => '<div class="no-results>No images found</div>',
);
}
}
}
elseif (!isset($output)) {
$output = ctools_modal_form_wrapper('imgsearch_form', $form_state);
// Return the ajax instructions to the browser via ajax_render().
print ajax_render($output);
drupal_exit();
}
}
else {
return drupal_get_form('imgsearch_form', $id);
}
}
Единственное реальное различие заключается в том, что, поскольку значения полей формы каким-то образом удаляются, когда форма отправленный через ajax, я использую элемент #parameters в массиве пейджеров, который помещает его в $_GET[], что позволяет мне получить к нему доступ в функции поиска (nb_image_search_search()). Аргумент страницы также присутствует, помещенный туда пейджером. Поскольку ctools_modal_form_wrapper() возвращает форму в режиме визуализации, мне нужно перестроить ее снова, чтобы передать ее в ctools_modal_form_render().
Кроме этого, я не вижу никаких различий. Я прошел через код до самого звонка, чтобы drupal_json_encode() в ajax_render(), но не может продвинуться дальше этого.
Что может привести к тому, что json будет просто отображаться на белом экране вместо отображения в модальном режиме, но только когда я использую ссылку на пейджер?
Спасибо.
2 answers
Ответом оказался отсутствующий класс в моих ссылках на пейджер. Всякий раз, когда вы используете модальный CTools, вам необходимо добавить класс ctools-use-modal в ссылку. Моей первой мыслью было добавить класс в качестве атрибута ссылки в функции тематизации ссылок, поскольку функция theme_pager_link() принимает атрибуты (через $values['атрибуты']). Однако функции, которые на самом деле вызывают theme_pager_link() (например, theme_pager_previous(), theme_pager_next(), и theme_pager_last()) не утруждает себя передачей атрибутов, поэтому нет способа передать их в функцию ссылки. Вздох.
Итак, чтобы обойти это, я просто создал быстрое поведение jQuery, которое добавляет класс ctools-use-modal в ссылки на пейджеры:
(function ($) {
Drupal.behaviors.addCtoolsModalClass = {
attach: function (context) {
$('#modalContent .pagination ul li a').addClass('ctools-use-modal');
}
}
})(jQuery);
И вуаля!, все работает так, как должно.
Используйте массивы массивов после pager_default_инициализировать.
Небольшой пример из моего кода, надеюсь, он вам поможет.
$per_page = 10;
$current_page = pager_default_initialize(count($result['node_ids']), $per_page);
$chunks = array_chunk(node_load_multiple($result['node_ids']),$per_page, TRUE);