示範中心項目裡有一些頁面要求幾個下拉選擇框的内容是具有關聯的關系的,例如在編輯一個實驗項目時,要先在一個下拉框裡選擇該項目所在的示範中心,這時實驗室下拉框裡的内容要根據使用者選中的示範中心改變。為了實作這個目的,我們先後想了幾種方法。
1、在使用者選擇示範中心時,重新整理頁面,并把示範中心代碼加在url的後面傳給action。這樣的最大問題是,如果使用者已經填寫了一部分表單,在更改示範中心選擇的時候會丢失已填寫的資訊。除非在重新整理時把整個表單的所有域都加在url裡傳回,但這樣做要在jsp頁面裡增加非常多的邏輯,是以不能使用。
2、把與示範中心關聯的幾個下拉框作為iframe的方式,當選擇了一個示範中心時,根據所選的示範中心重新load這個iframe,這樣不會影響到其他可能已經填寫的域。這樣做的問題是,iframe對應的頁面裡要重複考慮權限問題,這是不能忍受的,同時和所有使用架構技術的應用一樣,有可能造成一些頁面不一緻的情形。
3、前面兩種方式雖然都被否決了,但它們共同的好處是在使用者改變對示範中心的選擇時,資料是動态加載的。第三種方式是把所有資料一次讀到用戶端,使用javascript的方法實作關聯。我在網上找到了一些js代碼,但大部分都不适合動态生成資料,這也是一開始沒有使用js方式的原因之一。不過最後還是找到了一個我認為不錯的js,對它進行少量修改後比較漂亮的完成了任務,下面就說說具體的方法。
生成的靜态頁面就是下面這樣,頁面顯示後會預設選擇“北京大學數學示範中心”和“軟體工程實驗室”:
不過這個js有個小問題,就是它的def數組中的每個元素隻能是一個字元串,當選擇框是可多選的清單框時,就不能實作多個選項的預選擇(populate)。為了解決這個問題,我對xselect.js進行了少量的修改,允許def中的每個元素是一個數組。以下是修改後的xselect.js檔案中的doChange()函數:
其中注釋掉了兩句,并增加了一段對數組元素的處理,目前這個js在示範中心系統裡工作良好。為了讓jsp頁面中的代碼進一步減少,我們今後還要把動态生成js的代碼寫為tag的方式。
Web頁中級聯下拉選擇框問題是一個非常普遍的問題,本貼裡介紹的是我認為十分圓滿的一個用戶端方式的解決方法,使用者在使用時不會感到任何不便,而且因為資料權限問題是在action裡已經解決的,在對應的jsp頁面裡所做的任何處理都不需要考慮資料權限了。但在一些資料量特别大的系統裡要考慮網絡連接配接速度是否适合将所有資料傳到用戶端的問題。