一般动作
登录
Wiki: BROPEN ▼: Document Index
»
Space: FAQ ▼: Document Index
»
Page: 使用 $.formDialog 开发 AJAX 表单（含附件上传）
搜索
zh
页面动作
导出 ▼: 以PDF格式导出 以RTF格式导出 以HTML格式导出
更多动作 ▼: 打印预览 察看源码
欢迎进入Wiki » FAQ » 使用 $.formDialog 开发 AJAX 表单（含附件上传）?

# 使用 $.formDialog 开发 AJAX 表单（含附件上传）?

在2015-05-22 11:02上被李小翔修改
评论 (0) · 附件 (0) · 记录 · 信息

BroFramework 中集成了 JQuery UI，因此，我们通常采用其 dialog 组件来开发 AJAX 表单。

对于多数 AJAX 表单来说，基本流程如下：

1. 创建一个 dialog，并初始化大小、按钮等属性，多数情况下，仅包含“确定”、“关闭”两个按钮
2. 加载一个 AJAX 表单，加载完成后显示 dialog
3. 触发确定按钮后，执行 ajax 提交并回显

如下面的两个例子所示：

/**
* 示例1：AJAX 表单提交
*/
function createFolder(url) {
var id = "dlgCmsCreateFolder";
var dlg = $j("#"+id);
if ( dlg.length == 0 ) {
$j("<div id='"+id+"' class='body'></div>").appendTo("body");
dlg = $j("#"+id);
dlg.dialog({
autoOpen:false, modal:true, title:"创建文件夹", width:420, resizable:false,
buttons: {
"提交": function() {
var fm = $j("#fmCreateFolder");
showProcessingDlg();
$j.post(fm[0].action, fm.serialize(), function(msg){
hideProcessingDlg();
showAjaxMsg(msg, function(){
dlg.dialog("close");
try { parent.reloadNode($j("#folderId")[0].value); }catch(e){}
location.reload();
})
})
},
"关闭": function() { $j(this).dialog("close"); }
} // end of buttons
}) // end of dlg.dialog
}
dlg.load( url, function(msg){
if (/{"error"/.test(msg)) return;
dlg.dialog('open');
$j("#fmCreateFolder #name").focus()
});
}
/**
* 示例2：AJAX 附件上传
*/
function createFile(url) {
var id = "dlgCmsCreateFile";
var dlg = $j("#"+id);
if ( dlg.length == 0 ) {
$j("<div id='"+id+"' class='body'></div>").appendTo("body");
dlg = $j("#"+id);
dlg.dialog({
autoOpen:false, modal:true, title:"上传附件", width:450, resizable:false,
buttons: {
"上传": function() {
if ( $j("#fmCreateFile").find(":file").val() ) {
if ( $j.browser.fileApiSupported ) {
$j("#fmCreateFile").submit();
} else {
showProcessingDlg(function(){
$j("#fmCreateFile").submit();
return false;
});
$j(this).dialog("close");
}
}
},
"关闭": function() { $j(this).dialog("close"); }
} // end of buttons
}) // end of dlg.dialog
}
dlg.load( url, function(msg){
if (/{"error"/.test(msg)) return;
dlg.dialog('open');
// AJAX 上载，如果支持XMLHttpRequest Level 2，则显示上传进度
$j("#fmCreateFile").ajaxForm({
dataType: 'json',
beforeSend : function() {
if ( $j.browser.fileApiSupported ) {
dlg.closest("div.ui-dialog").find(".ui-dialog-titlebar, .ui-dialog-buttonpane, .ui-dialog-titlebar-close, .ui-resizable-handle").hide();
$j("#fmCreateFile").html('&nbsp;<br/><div class="progressbar"><div class="progress-label" style="float:right; margin-top:5px">Uploading...</div></div><br/>&nbsp;');
$j("#fmCreateFile .progressbar").progressbar({value: 0});
}
},
uploadProgress: function(event, position, total, percentComplete) {
$j("#fmCreateFile .progressbar").progressbar( "value", percentComplete );
$j("#fmCreateFile .progress-label").text( percentComplete + '%' );
},
complete: function(xhr) {
if ( $j.browser.fileApiSupported ) {
dlg.closest("div.ui-dialog").find(".ui-dialog-titlebar, .ui-dialog-buttonpane, .ui-dialog-titlebar-close, .ui-resizable-handle").show();
dlg.dialog("close");
}
}
})
});
}

上面的代码乍一看，麻烦得很，尤其是每次写AJAX表单时，总是要拷贝粘贴大量代码，因此，BroFWK提供了一个简化的API：$.formDialog，简化后的代码如下所示：

/**
* 示例1：AJAX 表单提交
*/
function createFolder(url) {
$j.formDialog({
modal:true, title:"创建文件夹", width:420, resizable:false,
id: "dlgCmsCreateFolder", url: url,
"submit.close": true, "submit.reload": true,
"submit.after": function() {
try {
parent.reloadNode($j("#folderId").val());
} catch(e) {}
}
})
}
/**
* 示例2：AJAX 附件上传
*/
function createFile(url) {
$j.formDialog({
modal:true, title:"上传附件", width:450, resizable:false,
id: "dlgCmsCreateFile", url: url, cache: false,
"submit.close": true, "submit.reload": true,
"submit.before": function() {
return $j("#fmCreateFile").find(":file").val();
}
})
}

和简化前的代码示例相比，代码量整整减少了2/3。

下面对 $.formDialog 做个简单的介绍：

- 封装了jquery ui的dialog组件，仅接收一个 options 参数，参数中的内容除了下面的注释所写的内容外，全部和 jqui 的 dialog 兼容
- 参数 options 说明：
  @param options.id HTML容器的ID，如果不存在，则会创建一个DIV
  @param options.html 表单的HTML文本内容，当容器不存在、并创建容器时将本参数的值放到 DIV 中
  @param options.url 表单的URL，通过AJAX加载
  @param options.cache 是否保存表单URL的Cache，默认为true
  @param options.progressbar 如果有附件域、且浏览器支持XMLHttpRequest Level 2，是否显示上传进度条，默认为真
  @param options.'buttons.default' 是否生成默认的确定（提交）、关闭（取消）按钮，默认为 true，即如果没有按钮Ok、Close按钮，则自动生成
  @param options.'buttons.OK' 默认确定按钮的名称，默认取i18n配置 jqui.dalog.button.OK，即“确定”，如果为 false 则不显示
  @param options.'buttons.CLOSE' 默认关闭按钮的名称，默认取i18n配置 jqui.dalog.button.CLOSE，即“关闭”，如果为 false 则不显示
  @param options.'submit.ajax' 是否采用ajax的方式提交，默认为true。
  如果提交后，需要根据上传的数据渲染或者重定向到其他页面（表单的 target 属性设为 _blank），则应设为false，此时ProcessingDlg显示3秒后自动关闭。
  @param options.'submit.close' 提交成功后是否自动关闭
  @param options.'submit.reload' 提交成功后是否自动刷新当前页面
  @param options.'submit.before' 点击“确定”前的事件，接收参数 form，如果返回 false 则中断提交
  @param options.'submit.after' 点击“确定”并且ajax提交成功后的事件，接收参数 message（服务器返回的对象）
  @params options.buttons jqui dialog 的按钮参数，用法不变，但其回调函数中可以调用 this.submit()、this.close()、this.form() 来直接提交、关闭、获取表单对象
- 需要注意的是，附件上传使用的是 jqeury 插件 ajaxForm，由于浏览器的支持程度不同，因此在控制器中需要采用下面的写法来接收附件、返回结果：
  def importExcel() {
  // 解析 Excel 文件
  Map result = bropen.toolkit.utils.office.MSExcelUtils.readAll(request)
  // 处理数据
  if ( !result.error ) {
  ....
  }
  // 渲染结果
  if ( isAjax() ) {
  render(result as JSON)
  } else {
  render(text:"<textarea>${result?.encodeAsJSON()}</textarea>", contentType:"text/html", encoding:"UTF-8")
  }
  }
  控制器中，还可以通过 request.getFileMap() 来获得所有上传的附件，或者使用默认的 attachmentService.save 将附件保存到 Domain 实体中。
  此外，提交过程默认为ajax的，如果上传附件后需要渲染一个预览界面，则应该设置 ‘submit.ajax’ 参数为 false，即禁用 ajax 方式提交表单。

标签： BroFramework ajax
在2014-06-11 17:32上被李小翔创建

- 评论 （0）
- 附件 （0）
- 记录
- 信息

# 快速链接

- 首页
- 新闻动态
- FAQ

Copyright © 2013 北京博瑞开源软件有限公司
京ICP备12048974号