您在這裡

請教一個模組的問題

ivanliaw's 的頭像
ivanliaw 在 2011-12-19 (週一) 09:03 發表

請教,

在Drupal官網提問(如以下連結),但似乎沒有答案,或是有其他更好的方法,請協助解答,謝謝。
http://drupal.org/node/1133146#comment-5340182

在「return $form ;」之前加一個「print_r($form);」把陣列印出來看看是否正常,
如果是陣列沒有正常產生的話,
試試看在最前面加一個「$form = array();」。

我是神豬~神豬的神,神豬的豬.......

Hi, James,

感謝您的回覆,

1. return $form 前 加print_r($form);

印出來的內容Submit前與Submit後都一樣,如下:
Array ( [date_query] => Array ( [#title] => [#type] => fieldset [#description] => Enter query condition: [start_date] => Array ( [#title] => Start date: [#type] => textfield ) [end_date] => Array ( [#title] => End date: [#type] => textfield ) ) [submit] => Array ( [#type] => submit [#value] => Submit ) )

是不是應該要在Array中看到 [query_result]等字樣?

2. 在form function 前面加 $form = array();
結果同1.

以上. 不知是否有其他方法可以正常顯示 $form['query_result'] ('#markup')?

跟你確認一下,
因為看起來陣列沒有問題,
只是query_result沒有參數。

你現在的狀況是表單有出來,
但是query_resut的內容沒有出來嗎?

如果是這樣的話,
把「$_POST['start_date']」「$_POST['end_date']」「$query_result」,
都用print_r印出來看看是否正常,
確認if裡跑的狀況是否有問題。

我是神豬~神豬的神,神豬的豬.......

Hi, James,

如我在官網論壇裡貼的source code, 將 $_POST['start_date'], $_POST['end_date'], $query_result 用drupal_set_messages()都可以印出來,但是,希望可以將查詢結果印在畫面上,而不是印在message box裡面,tks.

但是就你上面print_r出來的結果來看,
表單的array並沒有包含「query_result」這個參數,
所以你最好先確定一下if跑的狀況。

剛才看了一下#markup的用法......
http://api.drupal.org/api/drupal/developer--topics--forms_api_reference....
http://api.drupal.org/api/drupal/developer--topics--forms_api_reference....

看起來你是沒有用錯,
目前是有想到幾個可能的處理方法,
(if有正常執行的狀況下)
.硬設type給他「'#type' => 'markup',」,你也可以試試「'#type' => 'item',」
.改成設定「$form['#theme'] = 'function';」,然後再theme的function中再把table含進去
.把table跟form分開處理,menu先指到另一個function,然後用drupal_get_form取得表單,並產生table,再一起用$output回傳

-------------------------------------

你form的參數有一個「$form_state」,
他是當你在呼叫「drupal_get_form('form id');」時,
如果後面多給了其他參數,像是「drupal_get_form('form id', 'arg1', 'arg2');」時,
他就會用$form_state來傳給你,
詳細的狀況可以參考:
http://api.drupal.org/api/drupal/includes--form.inc/function/drupal_get_...
或是直接用print_r跟var_dump印出來看看。

我是神豬~神豬的神,神豬的豬.......

從函式原型來看, 在函式內部對 $form 給值根本不會起作用 因為 $form 是以 call by value 方式被傳入的,
要對 $form_state 給值才會起作用, 因為 $form_state 是以 call by reference 方式傳值.

function date_query_form($form, &$form_state) { ... }

據此, 有兩個方式可以再試看看:

1. 將 function date_query_form($form, &$form_state) { ... } 改成
function date_query_form(&$form, &$form_state) { ... }

2. 用 $form_state['values'] 來儲值, 而不是用 $form

以上 2. 應該是比較正規的, 我看過的範例都是以 $form_state['values'] 來儲值, 而不是 $form.

$form 一般是給 drupal系統 在用的, 用來承載表單流程所需資訊. programmer 要承載或修改
其它資料, 應當透過 $form_state['values'] 才是.

Hi, bobju,

感謝您的回覆,因為接觸Drupal不到一個月,所以不是很清楚$form_state['values']的用法,看範例$form_state['values']都是在_submit(), 或_validate()裡面用到的,原來的$form似乎沒有辦法取得$form_state['values']? 或是有其他方法可以將$query_result印出?

不好意思, 我之前愈描愈黑了, 因為重點只是在釐清 $ 跟 &$ 的差別.

要對 $form_state 給值, 確實是在

function xxx_submit($form, &$form_state){...} 裏進行,

而非 function xxx($form){...}

問題是,你沒有自定的 _form_submit,也會經過預設的 form_submit 處理

USER INPUT -> SUBMIT ~ ~> (FORM SUBMIT REDIRECT) -> FROM DISPLAY (GET FORM)
HTML FORM REDIRECT 後,就不會再有任何 $_POST

所以,應該如此:

function date_query_form_submit($form, &$form_state) {
$form_state['rebuild'] = TRUE;
return $form;
}

完整加上你的 CODE:

<?php

/**
* Implements hook_menu().
*/
function date_query_menu() {
$items['date_query'] = array(
'title' => 'Report',
'page callback' => 'drupal_get_form',
'page arguments' => array('date_query_form'),
'access callback' => TRUE,
'type' => MENU_CALLBACK
);
return $items;
}

/**
* Define a form.
*/
function date_query_form($form, &$form_state) {

$form['date_query'] = array(
'#title' => t(''),
'#type' => 'fieldset',
'#description' => t('Enter query condition:')
);
$form['date_query']['start_date'] = array(
'#title' => t('Start date:'),
'#type' => 'textfield',

);
$form['date_query']['end_date'] = array(
'#title' => t('End date:'),
'#type' => 'textfield',

);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit')
);

/*
* Kay Modified Part
*/
if (isset($form_state['input']['start_date']) && isset($form_state['input']['start_date'])){

$start_date = $form_state['input']['start_date'];
$end_date = $form_state['input']['end_date'];

$form['date_query']['query_result2'] = array(
'#markup' => t('Kay TEST: !start_date - !end_date', array('!start_date' => $start_date, '!end_date' => $end_date)), //nothing print out
'#weight' => -9999
);

/*
* Kay Modified Part END
*/

$query_result = db_query_with_date($start_date, $end_date);

//drupal_set_message($query_result); //the result can be printed in message box

$form['query_result'] = array(
'#markup' => $query_result, //nothing print out
);

}
return $form ;
}

function db_query_with_date($start_date, $end_date){

$query = db_select('node', 'n')->extend('PagerDefault');
$query
->condition('type', 'page')
->condition('created', array(strtotime($start_date), strtotime('+1 day',strtotime($end_date))), 'BETWEEN')
->fields('n', array('nid', 'title', 'created'));
//->range(0,100);

$results = $query->execute();

$header = array(
'Node ID','Title', 'Created',
);
$rtnStr = '';

$rows = array();
//$DBdata = array();
foreach ($results as $node) {
$rows[] = array(
$node -> nid,
$node -> title,
readabledateformat($node -> created),
);
}
// Theme the html table
$html = theme('table',
array(
'header' => $header,
'rows'=>$rows,
)
);

//Append pager
$html .= theme('pager',
array(
'tags' => array()
)
);

return $html;

}

function readabledateformat($enterdate) {
//$newdate = date("D, j M Y", $enterdate);
$newdate = date("Y/m/d", $enterdate);
return $newdate;
}

/*
* Kay Modified Part
*/

function date_query_form_submit($form, &$form_state) {
$form_state['rebuild'] = TRUE;
return $form;
}
/*
* Kay Modified Part END
*/

?>

Hi, Key,

非常感謝您的回覆,您所修改的程式碼確實可以印出$query_result. 但是分頁的部分(PagerDefault)似乎還要另外去處理submit,不然每一個分頁都是回到第一個Form(空白)。

Good point. 我也希望Views可以達到我們的需求,但是Views似乎只能列出來(list),沒有看見可以提供輸入查詢鍵值(E.g. $start_date, $end_date),然後列出查詢結果($query_result)的功能,另外Views似乎只能列出系統內建的Table如Node, Users...,如果非系統的Table是否也可以列出?

Drupal內建的Search可以提供類似的搜尋,但是要實作 _search_form_alter()才能搜尋非系統的Table,列出查詢結果也要實作_search_page(),另外,Drupal的Search,也是將搜尋的鍵值帶在URL之後。

或許是我了解不夠深入,還請您點解,謝謝。

查詢功能在 views 的 filter 面板裏設定. 將你所新增的 filter field "exposed" 即是查詢功能.
另外, cck + views 已可完成很多有CRUD需求的功能, 我用 drupal 快2年了, 還未實作過任何一個底層的 table ^^!
(不過 drupal node 跟 cck 的 table 架構倒是花過一點時間研究過. 因為難免有些繞過 node 跟 cck, 直接存取 table 的需求)

最近也剛開始碰 drupal , 也使用了 view 近2星期.
我有個疑問, list 裡的 Link 是可以自己定義要連去哪裡的嗎?
由 view 帶出來的 link , 已自動加上要連結的位置.
比如我拉了 user 的 name, 它可以讓我點選直接導至使用者修改頁面, 但我如果想要點擊後導至我自訂的頁面, 這樣是可以辦到的嗎?
謝謝前輩指引.

Usernames
____________
NAME | Active |
AAA   | ON     |
BBB   | OFF     |
____________