承接前文查詢/刪除功能,本文實現後台商品分類的新增與編輯,採用 EasyUI 模態視窗 + iframe 載入表單頁,結合前端驗證與 Struts2 後端處理。
在主頁面 aindex.jsp 的 <body> 底部放置一個隱藏的 <div>,作為所有彈窗的容器,並設定 modal:true 鎖定全螢幕:
<div id="win" data-options="collapsible:false,minimizable:false,maximizable:false,modal:true"></div>
{
iconCls: 'icon-add',
text: '新增分類',
handler: function() {
parent.$("#win").window({
title: "新增分類",
width: 350,
height: 150,
content: '<iframe src="send_category_save.action" frameborder="0" width="100%" height="100%"/>'
});
}
}
點擊後,iframe 載入 save.jsp 表單頁。
<form id="ff" method="post">
<div><label>分類名稱:</label><input type="text" name="type" /></div>
<div><label>所屬管理員:</label><input id="cc" name="account.id"/></div>
<div><label>熱門:</label>
是<input type="radio" name="hot" value="true" />
否<input type="radio" name="hot" value="false" />
</div>
<div><a id="btn" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-add'">新增</a></div>
</form>
<script>
$(function(){
// 1. 分類名稱必填驗證
$("input[name=type]").validatebox({ required: true, missingMessage: '請輸入分類名稱' });
// 2. 管理員下拉框遠端載入
$("#cc").combobox({
url: 'account_query.action',
valueField: 'id', textField: 'login',
panelHeight: 'auto', width: 120, editable: false
});
// 3. 預設關閉驗證,避免彈窗即顯示紅框
$("#ff").form("disableValidation");
// 4. 提交按鈕事件
$("#btn").click(function(){
$("#ff").form("enableValidation");
if ($("#ff").form("validate")) {
$("#ff").form('submit', {
url: 'category_save.action',
success: function(){
parent.$("#win").window("close");
// 刷新父頁面 DataGrid
parent.$("iframe[title='分類管理']").get(0).contentWindow.$("#dg").datagrid("reload");
}
});
}
});
});
</script>
@Controller("categoryAction")
@Scope("prototype")
public class CategoryAction extends BaseAction<Category> {
// ModelDriven 自動封裝表單參數到 model
public void save() {
categoryService.save(model); // 僅持久化,無需返回數據
}
}
{
iconCls: 'icon-edit',
text: '編輯分類',
handler: function() {
var rows = $("#dg").datagrid("getSelections");
if (rows.length == 0) { $.messager.show({title:'錯誤', msg:'請至少選擇一條記錄'}); return; }
if (rows.length > 1) { $.messager.show({title:'錯誤', msg:'每次只能編輯一條記錄'}); return; }
parent.$("#win").window({
title: "編輯分類",
width: 350,
height: 250,
content: '<iframe src="send_category_update.action" frameborder="0" width="100%" height="100%"/>'
});
}
}
關鍵差異:載入時自動回顯選中行數據。
<script>
$(function(){
var dg = parent.$("iframe[title='分類管理']").get(0).contentWindow.$("#dg");
// 管理員下拉框(同新增)
$("#cc").combobox({ url:'account_query.action', valueField:'id', textField:'login', width:120, editable:false });
// 1. 取得選中行並回顯表單
var rows = dg.datagrid("getSelections");
$("#ff").form('load', {
id: rows[0].id,
type: rows[0].type,
hot: rows[0].hot,
'account.id': rows[0].account.id // EasyUI 需用引號包裹巢狀屬性
});
// 2. 驗證與提交(同新增,url 改為 category_update.action)
$("#btn").click(function(){
$("#ff").form("enableValidation");
if ($("#ff").form("validate")) {
$("#ff").form('submit', {
url: 'category_update.action',
success: function(){
parent.$("#win").window("close");
dg.datagrid("reload");
}
});
}
});
});
</script>
<form id="ff" method="post">
<input type="hidden" name="id" /> <!-- 必須包含主鍵,Hibernate 才能更新而非新增 -->
<div><label>分類名稱:</label><input type="text" name="type" /></div>
<div><label>熱門:</label> 是<input type="radio" name="hot" value="true"/> 否<input type="radio" name="hot" value="false"/></div>
<div><label>所屬管理員:</label><input id="cc" name="account.id" /></div>
<div><a id="btn" class="easyui-linkbutton" data-options="iconCls:'icon-edit'">更新</a></div>
</form>
public void update() {
categoryService.update(model); // model 含 id,Hibernate 執行 update
}
@Controller("accountAction")
@Scope("prototype")
public class AccountAction extends BaseAction<Account> {
public String query() {
jsonList = accountService.query(); // 查詢所有管理員
return "jsonList";
}
}
<!-- struts.xml -->
<action name="account_*" class="accountAction" method="{1}">
<result name="jsonList" type="json">
<param name="root">jsonList</param>
<param name="excludeProperties">password</param> <!-- 排除敏感欄位 -->
</result>
</action>
#win 放在主頁,iframe 載入獨立表單頁,職責分離清晰。form('load') 自動回顯巢狀屬性(需引號),form('submit') 整合驗證與 AJAX 提交。