魔鬼總是藏在細節裡!

複選方塊又稱為核取方塊也就是checkbox,當你需要多個複選方塊在同一個form裡面的時候,和ASP的習慣不同,要用類似以下的方法:

<form id='search' class='search' method='post' action='/vender/grid'>
    <label for='term'>公司查找</label>
    <input id='term' name='term' value='<?php echo $term ?>' />
    <input id='is_vender' name='filter[]' type='checkbox' value='is_vender' />
    <label for='vender_only'>廠商</label>
    <input id='is_customer' name='filter[]' type='checkbox' value='is_customer' />
    <label for='customer_only'>客戶</label>
    <button type='submit'> 搜尋 </button>
</form>

也就是說要將複選方塊的name設定成像filter[]這樣後面加方刮號,然後用$_POST['filter']的方法把值取出來,取出來的值會是個陣列形態,但如果沒有選取就會是沒有設定的值。

假設我們有個資料表叫vender,裡面包含了幾個主要的欄位vender_id,full_name,is_vender,is_customer,因為對一家公司而言,一個廠商可能同時是客戶也是你的供應商,所以開結構的時候如果將它分開成兩個資料表不但麻煩,而且也不符合實際上的需求。

而使用者在打資料的時候,可能只是拿到個名片,要將它歸類到客戶或供應商也都不太對,當然你可以規定客戶一定要選一個,甚至用javascript來限制,但使用者的直覺卻是我還沒有歸類為何要選一個?所以最好是能夠接受兩個都是NO的情況。

再回到前面的查詢,有了form傳回來的查詢資料,接著就是要組SQL查詢字串了。

$filter = $_POST('filter');
if ( ! isset($filter) ) $filter=array();
foreach($filter as $field) {
    $criteria[$field] = 'Y';
}
$criteria['term'] = $_POST('term');

我們先用這樣的方法把條件都變成變數,並且放在$criteria這個keyvalue陣列裡面,上面的回圈是針對checkbox同名傳回來是個陣列的情況做處理,當然要記得處理都沒有值的情況,所以先用isset()判斷一下。因此$criteria這個變數裡面就可能是只有一個term或是多了is_vender='Y'或is_customer='Y'。

$where = '';
foreach($criteria as $field=>$value) {
    $part = '';
    if ($field == 'term') {
        if (strlen($value)>0) {
        $part = "(vender_id LIKE '$value%' OR full_name LIKE '%$value%')";
        }
    } else {
        $part = "($field='$value')";
    }
    if (strlen($part)>0)
        $where.= (strlen($where)==0 ? ' WHERE ' : ' AND ').$part;
}

$sql = "SELECT * FROM tp_vender $where";

組字串的原理是這樣,逐個繞$criteria這個變數,當有輸入文字的時候,就用like查詢vender_id和full_name這兩個欄位,其他的就是 欄位名=值 這種簡單組合。接著再判斷是否是第一個條件,如果是就加上WHERE這個SQL關鍵字,否則就是AND當然你也可以根據你的需求來調整,這樣做的好處是,如果沒有條件,那麼$where會是個空字串,組進主要的條件式很簡單,不用另外再判斷。

當你勾了is_vender就會多了is_vender='Y'的條件,勾了is_customer就會多了is_customer='Y'的條件,但是當你都沒有勾的時候呢?卻全部資料都跑出來了。這時候你會想,那麼我們就一開始先給他們初值就好了呀,於是加上下面的句子在前面取值之前:

$criteria['is_vender']='N';
$criteria['is_customer']='N';

這樣的結果是,查詢出來的東西就是跟使用者在查詢框上面勾選的資料相同,故事好像到這裡就結束了。如果你將這樣的程式交給客戶,客戶肯定會有抱怨:勾選廠商應該是所有的廠商全部都出來,不管他是不是客戶都應該要出來呀!

當然你可以跟客戶解釋這個查詢的結果,但是這就是不直覺,也就是說當客戶想看所有廠商資料,他要進行兩次的查詢,一次是廠商=Y客戶=N,一次是廠商=Y客戶=Y。如果客戶好說話也就罷了,但如果是放在雲端你從來見不到面的客戶,要教育他甚至要說服他這樣的結果恐怕有問題。

其實這個問題也很好解,當你還沒有做初值設定的時候,查詢結果就是客戶要的,只是當都沒有選的時候,應該是顯示不是客戶同時也不是供應商的資料,也就是當你的$filter拿不到值的時候才能夠加上初值。

if ( isset($filter) ) {
    foreach($filter as $field) { 
        $criteria[$field] = 'Y'; 
    }
} else { 
    $criteria['is_vender']='N';
    $criteria['is_customer']='N';
}

所謂魔鬼總是藏在細節裡,我們程式設計師總是用我們自己的想法在思考問題,像這樣的問題肯定很多設計師不會想到最後一步,而且往往功力越高深的程式設計師越不容易想到,而就算是有系統分析師在幫忙規劃,也很難講到這個細節,這只有靠平時自我訓練,凡事以客戶的角度想事情才能夠辦得到。

創作者介紹

人生四十宅開始 二號宅

漠哥 發表在 痞客邦 PIXNET 留言(0) 人氣()