您在這裡

ajax和db的問題

renren's 的頭像
renren 在 2012-06-02 (週六) 18:22 發表

各位好

我要寫的模組中(drupal版本是7.X),有一部分是要寫「多重下拉式選單」
這部分的目標就是選一個縣市,然後可以對應出該縣市的鄉鎮市區
例如:
選台北市後,就會跑出大同區、中山區、中正區等等
相對的,若選了新北市後,就會跑出板橋區、新莊區、淡水區等等

另外,我已經在phpMyadmin裡面建立了表格,規則如下:
TWAMP -> drupal7 -> location
(id , location)
(1 , 基隆市)
(2 , 台北市)
(3 , 新北市)

TWAMP -> drupal7 -> city
(id , location_id , city)
(1 , 1 , 暖暖區)
(2 , 1 , 七堵區)
(3 , 2 , 大同區)
(4 , 2 , 中山區)
(5 , 2 , 中正區)
(6 , 3 , 板橋區)
(7 , 3 , 新莊區)
(8 , 3 , 淡水區)

在參考了dbtng_example.module 和 ajax_example.module 這兩個example後
我發現到,我有幾個問題無法解決,問題如下:

(1) 在縣市部分已經可以讀取,每選取一個選項後,select旁都會有loading的圖示在跑
不過,我在select下面的textfield卻無法即時反應所選擇的選項

(2) 在鄉鎮市區這部分,我覺得我是因為縣市部分沒有即時反應才無法對應出相對的鄉鎮市區
但是,在ajax部分和db的讀取方面,好像又無法用縣市那部分的寫法,有點不知道該怎麼寫起......

相關程式碼如下:
function ttupoi_sofun_form_select($form , &$form_state)
{
$form = array(
'#prefix' => 'div id="selectform"',
'#suffix' => '/div',
);

$locations = ttupoi_sofun_select_location_load();
$keyed_locations = array();

foreach ($locations as $location)
{
$options_location[$location->id] = t("@id: @location" , array('@id' => $location->id , '@location' => $location->location));
$keyed_locations[$location->id] = $location;
}

$default_location = !empty($form_state['values']['location_id']) ? $keyed_locations[$form_state['values']['location_id']] : $locations[0];
$form_state['locations'] = $keyed_locations;

$form['location_id'] = array(
'#type' => 'select',
'#options' => $options_location,
'#title' => t('Choose location'),
'#default_value' => $default_location->id,
'#ajax' => array(
'wrapper' => selectform',
'callback' => 'ttupoi_sofun_form_select_callback',
),
);

$form['location_location'] = array(
'#type' => 'textfield',
'#title' => t('Choose location'),
'#size' => 15,
'#default_value' => $default_location->location,
); //如問題1,無法即時顯示

$form['city_id'] = array(
'#type' => 'select',
'#title' => t('Choose city'),
'#prefix' => 'div id="selectform"',
'#suffix' => '/div',
'#options' => ttupoi_sofun_select_city_load($default_location->id),
'#default_value' => isset($form_state['values']['city_id']) ? $form_state['values']['city_id'] : '',
); //如問題2,不知該怎麼寫起......

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

return $form;

}

function ttupoi_sofun_select_location_load($location = array())
{
$select = db_select('location', 'id');
$select->fields('id');

foreach ($location as $field => $value)
{
$select->condition($field, $value);
}

return $select->execute()->fetchAll();
}

function ttupoi_sofun_select_city_load($city = array())
{
$select = db_select('city', 'id');
$select->fields('id');

foreach ($city as $field => $value)
{
$select->condition($field, $value);
}

return $select->execute()->fetchAll();
}

function ttupoi_sofun_form_select_callback($form, $form_state)
{
$location = $form_state['locations'][$form_state['values']['location_id']];

foreach (array('id' , 'location') as $item)
{
$form[$item]['#value'] = $location->$item;
}
return $form;

}

function ttupoi_sofun_form_select_submit($form , &$form_state)
{
print_r("this is the location_location: " . $form_state['values']['location_location'] . "");

exit;

}

希望前輩們可以不吝指教,謝謝

您好

以下是drupal所提供的examples module
http://drupal.org/project/examples

我的drupal是7.12版本,因此裝了7.x-1.x-dev這個版本,網址如下
tar.gz檔:
http://ftp.drupal.org/files/projects/examples-7.x-1.x-dev.tar.gz
zip檔:
http://ftp.drupal.org/files/projects/examples-7.x-1.x-dev.zip

所參考的examples module是dbtng_example.module 和 ajax_example.module
在dbtng_example.module主要參考的menu是$items['examples/dbtng/update']
而ajax_example.module主要參考的munu是$items['examples/ajax_example/dependent_dropdown']

麻煩各位前輩了,謝謝>"<

您好

我的模組(rar檔)如下:
http://140.129.20.145/ttupoi_sofun.rar

location_location部分是因為參考dbtng_example.module檔案中的
function dbtng_example_form_update($form, &$form_state)所寫的
$form['name'] 、 $form['surname'] 、 $form['age']中並無#ajax callback

city_id方面,我將location_location 的 form state解釋成與$default_location->id相同
傳入到 ttupoi_sofun_select_city_load中讀取對應的鄉鎮市區
不知道這樣的解釋有沒有錯誤@@"

另外,location_location並無法即時抓到location_id的值
因此,我覺得city_id也無法顯示該對應的鄉鎮市區才對
(其實,我連要怎麼load到對應的city都不知道有沒有寫對......)

麻煩指教,謝謝

1. location_id 沒有 #ajax callback / wrapper
2. location_location 有點無謂, 只會增加複雜性
3. city_id 也沒有 #ajax callback / wrapper
4. city_city 你沒有 #value

ttupoi_sofun_select_city_load 也完全不對........
$city 只有 pass ID 進去呢.....

您好

1.在我寫的程式碼中的138~141行 && 165~167行,應該是屬於#ajax callback / wrapper的部分
(我不太熟悉#ajax callback / wrapper的寫法,所以我不知道有沒有寫對,基本上都照抄example)
callback的function則寫在283~294行(也不知道內容和return有沒有寫對......)

2.location_location和city_city都是純粹測試有沒有即時顯示所選擇的選項
測試結果成功後,模組也順利寫完後,會拿掉相關測試用的code

3.在我寫的程式碼中的191~192行有#ajax callback / wrapper的部分
不過在example找不到兩個相關聯(對應)的#ajax callback / wrapper
所以,都是憑感覺去try try各種可能寫法
因為無法即時顯示縣市部分,就沒多加著墨此問題

4. 在我寫的程式碼中的201行有'#default_value' => $form['city_id']->city,
只是被我comment掉了= ="

因為無法即時抓到縣市的value的關係,因此我的猜測是
造成ttupoi_sofun_select_city_load無法從DB中
正確抓出該對應的鄉鎮市區(city)
(如果有抓到value,該怎麼從DB抓對應的city,對我也是個問題就是了QQ")

謝謝指教,麻煩前輩,謝謝

沒用的東西去掉吧 :)
你好像沒有進行過 debug 工程...
快速改修一下, 你自已優化整理...

#ajax callback 是處理傳回的資料
#ajax wrapper 是 AJAX 的目標 html element ID

還有..... 你的 DB table 是 "location", "city"
習慣一下加上你的模組名 "ttupoi_location", "ttupoi_city" 不會跟其他模組碰撞上
(eg. http://drupal.org/project/location 好像就使用了 "location")

多使用 dpm, dd, die()

您好

我沒想到DB table也會有碰撞的問題,謝謝您的提醒

debug我可能做得不夠完善= ="

請問一下,您所附加的檔案有修改過嗎@@?
沒看見有修改的部分

謝謝

您好

謝謝您的解答,讓我受益匪淺

想請教一下,在location_load 和 city_load中
1. $location = array() 和 $city = NULL的差別是什麼?
2. 兩者在return的時候,分別是fetchAll()和fetchAllKeyed() 差別又是什麼?

謝謝

1. 我只小修改到可運行, 其他都沒有仔細看過, $location = array() 我沒修改, 看一下也沒必要傳入什麼...這個你要重溫 PHP Function 的基礎
2.
fetchAllKeyed() 可以看看這段
http://api.drupal.org/api/drupal/includes%21database%21database.inc/func...

簡單點說:

function ttupoi_sofun_select_city_load($city = NULL)
{

$select = db_select('city', 'c');
$select->fields('c', array('id', 'city')); // id 會是 key, city 是值
$select->condition('c.location_id', $city, '=');

return $select->execute()->fetchAllKeyed();
}

你也可以 fetchAll 後再 foreach ....

http://hk2.php.net/manual/en/pdostatement.fetchall.php

找找 PHP PDO 的中文資料看看, 幾乎零差別

還有是..... 你的檔案都用 BIG5 儲存, 建議在 Drupal 中用 UTF-8 (no BOM) (其實現在大多程式也用 UTF-8)

$job = $form_state['values']['job'];
print_r("User的job: ");
print_r($job);
print_r("");
print_r("");

我注意到你這樣 debug, 如果你沒有安裝 xdebug, 遇上 array 應該看的很辛苦吧..

你可以用
print '

';
    print_r($job);
    print '

';

或看看這個會不會有幫助
http://www.notabluescreen.com/devel-tips
http://www.notabluescreen.com/debug_function

真是太謝謝您了,對我的幫助真的太大了

尤其是
print '

';
print_r($array);
print '

';
這個方法,眼睛終於可以不用看得這麼累了

真的太謝謝了,謝謝

不好意思 想再請教一下

在page 2的時候,可以得到page 1的「縣市」和「鄉鎮市區」的值
但是我想在page 3 or page 4繼續使用page 1抓到的這兩個值
請問一下,要怎麼做才能順利得到page 1的值?

懇請前輩播空指教,謝謝