我正在构建一个简单的自定义模块来搜索某个节点类型并将其显示在与表单相同的页面中。它就像搜索功能。问题是如何使用paging-teaser节点样式在表单下方显示结果?
代码是:
<?php
/**
* Implements hook_help().
*
* Displays help and module information.
*
* @param path
* Which path of the site we're using to display help
* @param arg
* Array that holds the current path as returned from arg() function
*/
function book_search_help($path, $arg) {
switch ($path) {
case "admin/help#book_search":
return '<p>' . t("Displays book search page") . '</p>';
break;
}
}
function book_search_menu() {
$items = array();
$items['book/search'] = array(
'title' => 'Pencarian book',
'description' => 'Halaman pencarian book',
'page callback' => 'drupal_get_form',
'page arguments' => array('book_search_form'),
'access arguments' => array('access content'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function book_search_form($form, &$form_state) {
$form['cari'] = array(
'#type' => 'fieldset',
//'#title' => t('Pencarian'),
//'#attributes' => array('class' => array('container-inline')),
'#tree' => TRUE,
);
$form['cari']['pilihan'] = array(
'#type' => 'select',
'#title' => t('Pilihan Pencarian'),
'#options' => array(
'1' => t('Option 1'),
'2' => t('Option 2'),
'3' => t('Option 3'),
'4' => t('Option 4'),
'5' => t('Option 5'),
'6' => t('Option 6'),
'7' => t('Option 7'),
'8' => t('Option 8'),
),
'#attributes' => array('class' => array('container-inline')),
'#default_value' => $category['umum'],
// '#description' => t('Set this to <em>Yes</em> if you would like this category to be selected by default.'),
);
$form['cari']['kata'] = array(
'#type' => 'textfield',
'#title' => t('Kata Kunci'),
'#size' => 50,
'#maxlength' => 256,
);
$form['cari']['submit'] = array('#type' => 'submit', '#value' => t('Cari'),'#submit' => array('book_search_submit'),);
if (isset ($form_state['hasil'])){
print render(node_view_multiple($form_state['hasil'], 'teaser')) . theme('pager');
}
return $form;
}
function book_search_submit($form, &$form_state) {
//db_query("INSERT INTO {table} (name, log, hidden) VALUES ('%s', %d, '%s')", $form_state['values']['name'], $form_state['values']['access']['log'], $form_state['values']['hidden']);
$query = new EntityFieldQuery;
$query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'mytype')
->pager(20)
->propertyCondition('status', 1); // in case you need it
// ->fieldCondition('field_customfield3', 'value', $user->uid)
// ->fieldCondition('field_customfield4', 'value', $anemailaddress);
$results = $query->execute();
if (isset($results['node'])) {
$news_items_nids = array_keys($results['node']);
$news_items = entity_load('node', $news_items_nids);
}
drupal_set_message(t('Your form has been submitted.'));
$nodes = node_load_multiple(array_keys($results['node']));
$form_state['hasil'] = $nodes;
// print render(node_view_multiple($nodes, 'teaser')) . theme('pager');
$form_state['rebuild'] = TRUE;
}
我修改了代码,以便根据选择选项动态构建查询。显示结果的技巧是使用$form['#suffix'] = $html;
将结果html附加到表单代码的后面。这导致结果分页不一致。 有什么方法可以改善它或使其正确吗?
修改后的代码:
function book_search_help($path, $arg) {
switch ($path) {
case "admin/help#book_search":
return '<p>' . t("Displays book search page") . '</p>';
break;
}
}
function book_search_menu() {
$items = array();
$items['book/search'] = array(
'title' => 'Pencarian book',
'description' => 'Halaman pencarian book',
'page callback' => 'drupal_get_form',
'page arguments' => array('book_search_form'),
'access arguments' => array('access content'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function book_search_form($form, &$form_state) {
$form['cari'] = array(
'#type' => 'fieldset',
'#tree' => TRUE,
);
$form['cari']['pilihan'] = array(
'#type' => 'select',
'#title' => t('Pilihan Pencarian'),
'#options' => array(
'1' => t('1'),
'2' => t('2'),
'3' => t('3'),
'4' => t('4'),
'5' => t('5'),
'6' => t('6'),
'7' => t('7'),
'8' => t('8'),
),
'#attributes' => array('class' => array('container-inline')),
'#default_value' => $category['umum'],
);
$form['cari']['kata'] = array(
'#type' => 'textfield',
'#title' => t('Kata Kunci'),
'#size' => 50,
'#maxlength' => 256,
);
$form['cari']['submit'] = array('#type' => 'submit', '#value' => t('Cari'),'#submit' => array('book_search_submit'),);
if (isset($_SESSION['hasil'])){
$html = drupal_render(node_view_multiple($_SESSION['hasil'], 'teaser')) . theme('pager');
$form['#suffix'] = $html;
}
return $form;
}
function book_search_submit($form, &$form_state) {
$query = new EntityFieldQuery;
$query->entityCondition('entity_type', 'node');
switch($form_state['values']['cari']['pilihan']){
case '1':
$query->entityCondition('bundle', array('montype','book'), 'IN')
->fieldCondition('body', 'value', $form_state['values']['cari']['kata'], 'CONTAINS');
break;
case '2':
$query->entityCondition('bundle', 'montype')
->fieldCondition('body', 'value', $form_state['values']['cari']['kata'], 'CONTAINS');
break;
case '3':
$query->entityCondition('bundle', 'montype')
->fieldCondition('field_dosis', 'value', $form_state['values']['cari']['kata'], 'CONTAINS');
break;
case '4':
$query->entityCondition('bundle', 'montype')
->fieldCondition('field_efek_samping', 'value', $form_state['values']['cari']['kata'], 'CONTAINS');
break;
case '5':
$query->entityCondition('bundle', 'montype')
->fieldCondition('field_peringatan', 'value', $form_state['values']['cari']['kata'], 'CONTAINS');
break;
case '6':
$query->entityCondition('bundle', 'montype')
->fieldCondition('field_interaksi', 'value', $form_state['values']['cari']['kata'], 'CONTAINS');
break;
case '7':
$query->entityCondition('bundle', 'montype')
->fieldCondition('field_kontraindikasi', 'value', $form_state['values']['cari']['kata'], 'CONTAINS');
break;
case '8':
$query->entityCondition('bundle', 'montype')
->propertyCondition('title', $form_state['values']['cari']['kata'], 'CONTAINS');
break;
default:
break;
}
$query->pager(20)
->propertyCondition('status', 1); // in case you need it
$results = $query->execute();
$_SESSION['hasil'] = node_load_multiple(array_keys($results['node']));
$form_state['rebuild'] = TRUE;
drupal_set_message(t('Your form has been submitted.'));
}
答案 0 :(得分:1)
只是快速重写了几个方面,没有测试它所以可能有一两个奇怪的错误。 除了几个标准之外我唯一真正添加的是使用$ form_state [&#39; storage&#39;],它主要用于多步骤表单,但我已经使用过它有几次实现你想要做的事情。 (https://www.drupal.org/node/1850410)
此外,使用render而不是drupal_render,只需在将其发送到drupal_render函数之前进行一些额外的检查。
/**
* Implements hook_menu().
*/
function book_search_menu() {
$items = array();
$items['book/search'] = array(
'title' => 'Pencarian book',
'description' => 'Halaman pencarian book',
'page callback' => 'drupal_get_form',
'page arguments' => array('book_search_form'),
'access arguments' => array('access content'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
/**
* Implements hook_form().
*/
function book_search_form($form, &$form_state) {
$results = _book_search_results();
$query = $results['query'];
$nids = $results['nids'];
$form['#method'] = 'get';
$form['#token'] = FALSE;
$form['#multistep'] = TRUE;
$form['#redirect'] = FALSE;
$form['#after_build'] = array('_book_search_form_after_build');
$form['cari'] = array(
'#type' => 'fieldset',
'#tree' => TRUE,
);
$form['cari']['pilihan'] = array(
'#type' => 'select',
'#title' => t('Pilihan Pencarian'),
'#options' => array(
'1' => t('1'),
'2' => t('2'),
'3' => t('3'),
'4' => t('4'),
'5' => t('5'),
'6' => t('6'),
'7' => t('7'),
'8' => t('8'),
),
'#attributes' => array('class' => array('container-inline')),
'#default_value' => $query['pilihan'],
);
$form['cari']['kata'] = array(
'#type' => 'textfield',
'#title' => t('Kata Kunci'),
'#size' => 50,
'#maxlength' => 256,
'#default_value' => $query['kata'],
);
$form['cari']['submit'] = array(
'#type' => 'submit',
'#value' => t('Cari'),
'#submit' => array('book_search_form_submit'),
);
if ($nids) {
$nodes = node_load_multiple($nids);
// $build = _book_search_results_node($nodes);
$build = _book_search_results_table($nodes);
if ($build) {
$form['results'] = array(
'#type' => 'markup',
'#markup' => render($build) . theme('pager'),
);
}
}
return $form;
}
/**
* Remove items from the form in a after_build event.
*
* @param array $form
* The drupal form.
*
* @return array
* The drupal form, post modifications.
*/
function _book_search_form_after_build($form) {
unset($form['form_token']);
unset($form['form_build_id']);
unset($form['form_id']);
return $form;
}
/**
* Get results by using filters in the query string.
*
* @return array
* An array of node id's.
*/
function _book_search_results() {
$values = drupal_get_query_parameters();
$field_values = array(
'pilihan' => FALSE,
'kata' => '',
);
// @todo: You may need to update these variables.
$cari = array_key_exists('cari', $values) && is_array($values['cari']) ? $values['cari'] : array();
// If the user has not submitted the form.
if (!$cari) {
$field_values = array(
'pilihan' => '7',
'kata' => 'searchterm',
);
}
$query = array(
'pilihan' => array_key_exists('pilihan', $cari) ? $cari['pilihan'] : $field_values['pilihan'],
'kata' => array_key_exists('kata', $cari) ? $cari['kata'] : $field_values['kata'],
);
$bundles = array('montype');
$field_conditions = array(
'1' => 'body',
'2' => 'body',
'3' => 'field_dosis',
'4' => 'field_efek_samping',
'5' => 'field_peringatan',
'6' => 'field_interaksi',
'7' => 'field_kontraindikasi',
);
$propery_conditions = array('title');
if ($query['pilihan'] == '1') {
$bundles[] = 'book';
}
$efquery = new EntityFieldQuery();
$efquery->entityCondition('entity_type', 'node')
->entityCondition('bundle', $bundles);;
if ($query['pilihan']) {
if (array_key_exists($query['kata'], $field_conditions)) {
$efquery->fieldCondition($field_conditions[$query['pilihan']], 'value', $query['kata'], 'CONTAINS');
}
elseif (array_key_exists($query['pilihan'], $propery_conditions)) {
$efquery->propertyCondition($propery_conditions[$query['pilihan']], $query['kata'], 'CONTAINS');
}
}
$results = $efquery->pager(20)
->execute();
return array(
'query' => $query,
'nids' => $results ? array_keys($results['node']) : array(),
);
}
/**
* Node teaser display for the results of the book search.
*
* @param array $nodes
* An array of nodes.
*
* @return array
* A renderable build array.
*/
function _book_search_results_node(array $nodes) {
return node_view_multiple($nodes, 'teaser');
}
/**
* Table display for the results of the book search.
*
* @param array $nodes
* An array of nodes.
*
* @return array
* A renderable build array.
*/
function _book_search_results_table(array $nodes) {
$build = array(
'#theme' => 'table',
'#header' => array(
t('Node Id'),
t('Title'),
t('Created'),
t('Random field'),
),
'#attributes' => array(
'class' => array('book-search-results-table'),
),
'#rows' => array(),
'#sticky' => FALSE,
'#empty' => t('There are no results matching that criteria.'),
);
foreach ($nodes as $n) {
$field_random_field = field_get_items('node', $n, 'field_random_field');
$random_field = $field_random_field ? $field_random_field[0]['value'] : '';
$build['#rows'][] = array(
$n->nid,
$n->title,
$n->created,
$random_field,
);
}
return $build;
}