2012年8月8日 星期三

jQuery - 如何加入自動完成 ? How to achieve auto complete function?

第一步你要先 download jQuery,並且在jsp 中宣告 :

<script type="text/javascript" src="js/jquery-1.3.2.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.7.custom.min.js"></script>

版本號就看你下載的jQuery 來宣告。
接下來在你的 js 中,針對某一個 input 欄位,此例為料號,加入 auto complete 的功能 。

$("#material_text").autocomplete({
        source : function(request, response) {
           
            $.ajax({
                url : $("#path").val() + 'ajax.action?method=list&act=find_material_text',
                type : "POST",
                dataType : "json",
                cache : false,
                delay : 1500,
                data : {
                    term : request.term
                },
                success : function(data) {
                //    $("#material_desc").unblock();
                    response(
                        $.map(data , function(item) {
                            return {
                                label : item.label,
                                value : item.value,
                                desc : item.desc
                            };
                        })
                    );
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    alert(textStatus);
                
                }
            });
        },
        select : function(event, ui) {
            $("#product_desc").attr('value', ui.item.desc);            
        }     
    });

以下針對上面的程式做簡單說明。


自動完成,主要是搭配 ajax 的技術,來動態向後端要值。此例是將回傳結果,回傳成類似下拉式的選單,讓使用者可以從這些選單做選擇,而不用記得全部的輸入值資料。可以在 SQL 中做 LIKE ,或是其它搜索方式,讓使用者不一定要從「頭」開始輸入。


delay 是輸入後趨動查詢的間隔時間,如果使用者想要馬上打馬上看,那間隔可以短一點,不過對後台的呼叫次數當然也會變多,若機器不是很強的時候可以調慢一點。


 data : {
          term : request.term
         },


這是要送到後台去的,term 可以在後面當成一個 parameter 來抓取。就是使用者目前輸入的值。


select : function(event, ui) {
            $("#product_desc").attr('value', ui.item.desc);            
        } 


這裡是指,當使用者「點選了自動完成給你的結果集」之後所觸發的事件。
若沒有要特別做什麼,這裡可以不用去實作。
這裡是將 ui.item.desc 的值設入 某個 html input element 中 。
ui.item 是固定的,就是後台回傳的一個一個物件。
desc 是你自己可以在後台加入的屬性。
desc 我是放料號的說明。等下會解釋。

這樣前端的部份大概就好了。再來後端要提供觸發回傳的結果集有哪些。
至於這一段方法怎麼去觸發,就是看你web framework 使用的是哪一種,簡單來說就是要觸發到這一段,並且要用 ajax + json 的方式吐回去。


value = p("term");
sb.append("[");
List<Object[]> list = sap.createSQLQuery("select top 500 MATERIAL,MATERIAL_DESC from  MATERIAL where 1=1  and (material like  :val  or MATERIAL_DESC like :val )")
.setParameter("val", "%" + value + "%").list();
int i = 0;
for (Object[] ob : list) {
    sb.append(String.format("{\"label\":\"%s\",\"value\":\"%s\",\"desc\":\"%s\"}", getString(ob[0]) + " " + getString(ob[1]).replaceAll("\"", ""), getString(ob[0]), getString(ob[1])));
    if (i != list.size() - 1)
        sb.append(",");
    i++;
}
sb.append("]");

首先我只撈前500筆,若太多的話前端顯示會當掉。
可以用關鍵字查詢。
 json 裡則有三個屬性 label , value 與 desc ,desc是我自己加的,要和前端的程式同名才能使用。

  1. label 放料號的 id + 說明。這個是顯示用的。
  2. value 則放料號的 id。這個值在點了之後,會真的塞到原來的 input field中。
  3. desc 則只放料號的說明。我拿這個值來塞到畫面別處,讓使用者可以看到很長的料號說明。 將此三值分開,在前端可以方便使用。

組json 字串是當初花比較多時間的部份。


getString = String.valueOf 而已。  p 是取parameter 我自己簡化過的方式。

沒有留言:

張貼留言