剛剛才在同事的協助下實做出和後端資料庫連動式的下拉式選單(在Liferay中使用Javascript),為了避免忘記以後怎麼寫,所以先記載一份於此。
例如我們有兩個下拉式選單需要連動,例如:
XXX.jsp檔
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
先引用。
<%List <course_Assort> course = course_AssortLocalServiceUtil.dynamicQuerySortByType("KeyWord"); %>
這一行是從資料庫內把course_Assort這個資料表內的資料經過自定義的dynamicQuerySortByType的篩選後產生course物件。
<aui:select id="assortType" name="assortType" label="請選擇類型" onChange="updateData(this)">
<%for(course_Assort assort:course){ %>
<aui:option value="<%=assort.getCourseAssortId()%>"><%=assort.getAssortName()%></aui:option>
</aui:select>
<%} %>
以上為第一個下拉式選單,使用了for迴圈讀取出資料庫內course_Assort這個List內的資料,再將其一筆一筆抓出,value為PK,下拉選單顯示的是類別名稱。
onClick方法呼叫的是我們等會要撰寫的javascript方法。
<aui:select name="assortName" label="請選擇子類型" value="">
</aui:select>
以上這個是第二個下拉式選單,需要跟第一個選單連動顯示子類別。
有了這兩個選單之後,我們就必須撰寫javascript方法,方法如下:
function updateData(v)這個V的參數代表著選單自己
{
var value=v.options[v.selectedIndex].value; //這一行是表示下拉式選單所選到的那個index
if (value!="") //真的選了選項才丟server side,平常選單是空的。
{
$.post("<portlet:resourceURL/>","courseAssortId="+value,function(data)//這裡就是丟資料到後端的方法去處理,把資料表的PK傳到後端去。
{
var subAssort=document.getElementsByName("<portlet:namespace/>assortName")[0];
上面這一行是獲取第二個下拉式選單,用name去抓。
var length = subAssort.options.length;
while(subAssort.options.length > 0){
subAssort.remove(0); //這裡是讓分類重新選擇後會清空
}
var assortData=data.split("\n");//用 \n 來做分資料分割,在此已經從後端抓出了整批資料,開始用換行碼來做分割。
for (i=0;i<assortData.length-1;i++)
{
value=assortData[i].split("-")[0];//用 - 來做分資料分割取出value
text=assortData[i].split("-")[1]; //用 - 來做分資料分割取出text
option=new Option(text,value); //用這樣的方法 IE 才會work
subAssort.options[i]=option; //
}
});
}
}
</script>
寫完javascript的動作後,最後就是後端的問題了。
在控制portlet的portlet.Java檔內加入以下程式碼:
public void serveResource(ResourceRequest resourceRequest,
ResourceResponse resourceResponse) throws PortletException,
IOException {
HttpServletRequest httpResRequest = PortalUtil
.getHttpServletRequest(resourceRequest);
httpResRequest = PortalUtil
.getOriginalServletRequest(httpResRequest);
以上這些就是和前台交換資料的方法
final String param = httpResRequest.getParameter("courseAssortId");
final PrintWriter writer = resourceResponse.getWriter();
上面第一行定義了一個String物件,是從前端方法傳過來的PK,下一行new了一個writer物件。
long courseAssortId = Long.parseLong(param); 轉型成long的型態。
List<course_Assort> assortList; 定義一個要使用的資料表list
try {
assortList=course_AssortLocalServiceUtil.getcourseAssortsByParentId(courseAssortId);
上面這一行比較重要,這個方法是在service.xml內所添加的finder標籤,只要加上了之後,重新建置便會產生利用這個欄位來找東西的方法。
方法的寫法跟dynamicQuery寫在相同的LocalServiceImpl內,然後寫入以下方法:
public List<course_Assort> getcourseAssortsByParentId(long parentId) throws SystemException{
return course_AssortPersistence.findByparentId(parentId);\
這樣我們就可以使用這個方便的方法了。
for (course_Assort job : assortList) {
if (true) {
writer.append(job.getCourseAssortId() + "-" + job.getAssortName()
+ "\n");
}
}
return;
} catch (SystemException e) {
e.printStackTrace();
}
}
以上這些是使用迴圈把list中的資料抓出,然後返回到前端網頁的下拉式選單內。
只要使用上沒出錯,可連動的下拉式雙選單就完成了。

很好的文章!!