辛苦的介绍完前两节后,我们来一个动态图看一下效果吧!

###③. summernote所在form表单的数据提交
这里,我们再回顾一下summernote所在的form表单,其中还包含了一个普通file的input标签,也就是说,该form还需要上传一张项目封面。
<form class="form-horizontal required-validate" action="#" enctype="multipart/form-data" method="post" οnsubmit="return iframeCallback(this, pageAjaxDone)">
先看一下form的属性:
enctype:“multipart/form-data”,表明为文件类型的form保存
iframeCallback方法,稍候详细介绍,主要是对有文件上传的form表单进行封装。
####1、iframeCallback
function iframeCallback(form, callback) {
YUNM.debug("带文件上传处理");
var $form = $(form), $iframe = $("#callbackframe");
var data = $form.data('bootstrapValidator');
if (data) {
if (!data.isValid()) {
return false;
}
}
// 富文本编辑器
$("div.summernote", $form).each(function() {
var $this = $(this);
if (!$this.summernote('isEmpty')) {
var editor = "<input type='hidden' name='" + $this.attr("name") + "' value='" + $this.summernote('code') + "' />";
$form.append(editor);
} else {
$.showErr("请填写项目详情");
return false;
}
});
if ($iframe.size() == 0) {
$iframe = $("<iframe id='callbackframe' name='callbackframe' src='about:blank' style='display:none'></iframe>").appendTo("body");
}
if (!form.ajax) {
$form.append('<input type="hidden" name="ajax" value="1" />');
}
form.target = "callbackframe";
_iframeResponse($iframe[0], callback || YUNM.ajaxDone);
}
function _iframeResponse(iframe, callback) {
var $iframe = $(iframe), $document = $(document);
$document.trigger("ajaxStart");
$iframe.bind("load", function(event) {
$iframe.unbind("load");
$document.trigger("ajaxStop");
if (iframe.src == "javascript:'%3Chtml%3E%3C/html%3E';" || // For
// Safari
iframe.src == "javascript:'<html></html>';") { // For FF, IE
return;
}
var doc = iframe.contentDocument || iframe.document;
// fixing Opera 9.26,10.00
if (doc.readyState && doc.readyState != 'complete')
return;
// fixing Opera 9.64
if (doc.body && doc.body.innerHTML == "false")
return;
var response;
if (doc.XMLDocument) {
// response is a xml document Internet Explorer property
response = doc.XMLDocument;
} else if (doc.body) {
try {
response = $iframe.contents().find("body").text();
response = jQuery.parseJSON(response);
} catch (e) { // response is html document or plain text
response = doc.body.innerHTML;
}
} else {
// response is a xml document
response = doc;
}
callback(response);
});
}
贴上全部代码以供参考,但是这里我们只讲以下部分:
// 富文本编辑器
$("div.summernote", $form).each(function() {
var $this = $(this);
if (!$this.summernote('isEmpty')) {
var editor = "<input type='hidden' name='" + $this.attr("name") + "' value='" + $this.summernote('code') + "' />";
$form.append(editor);
} else {
$.showErr("请填写项目详情");
return false;
}
});
通过form获取到summernote对象 t h i s 后 , 通 过 ‘ ‘ ‘ ! this 后,通过```! this后,通过‘‘‘!this.summernote(‘isEmpty’)```来判断用户是否对富文本编辑器有内容上的填写,保证不为空,为空时,就弹出提示信息。
$this.summernote('code')可获得summernote编辑器的html内容,将其封装到input对象中,name为前文中div提供的name,供后端使用。
这里其他地方就不做多解释了,详细可参照Bootstrap wysiwyg富文本数据如何保存到mysql。
保存到数据库中是什么样子呢?
<p><img src="http://localhost:8080/ymeng/upload/2016033117093076.jpeg" style=
####2、新版iframeCallback方法
var $form = $(form), $iframe = $("#callbackframe");
YUNM.debug("验证其他简单组件");
var data = $form.data('bootstrapValidator');
if (data) {
if (!data.isValid()) {
return false;
}
}
// 富文本编辑器
$("div.summernote", $form).each(function() {
var $this = $(this);
if ($this.summernote('isEmpty')) {
} else {
YUNM.debug($this.summernote('code'));
// 使用base64对内容进行编码
// 1.解决复制不闭合的html文档,保存后显示错乱的bug
// 2.解决文本中特殊字符导致的bug
var editor = "<input type='hidden' name='" + $this.attr("name") + "' value='" + $.base64.btoa($this.summernote('code')) + "' />";
$form.append(editor);
}
});
YUNM.debug("验证通过");
比对之前的代码,可以发现代码有两处发生了变化:
当summernote为空时,之前没有做在bootstrap的validator中,是因为还没有搞清楚summernote这种非input标签在validator中的使用,下面会做详细说明。
对summernote的内容加上了base64编码处理,这会有很多好处,稍候介绍。
3、base64的使用方法
js端我在Bootstrap wysiwyg富文本数据如何保存到mysql这篇文章中做了说明,此处不再说明。
可能会有同学需要javascript端的base64编码,而需要在springMVC后端使用base64的解码,那么此处介绍一个jar包(Java Base64.jar),使用方法很简单,下载好jar包后,就可以使用如下方法解码:
import it.sauronsoftware.base64.Base64;
deal.setDescription(StringEscapeUtils.escapeHtml(Base64.decode(description, "utf-8")));
1
2
3
首先,base64的import如上,来自于javabase64.jar包。
decode的编码前端js使用的utf-8,此处自然也用utf-8。
至于StringEscapeUtils类,也是一个非常实用的工具类,有兴趣的可详细关注一下(主要可以对html等等特殊标签进行转义)。
####4、summernote加入到bootstrap validator中
<div class="form-group">
<label for="" class="col-md-1 control-label">项目详情</label>
<div class="col-md-10">
<div class="summernote" name="description" data-bv-excluded="false" data-bv-notempty placeholder="请对项目进行详细的描述,使更多的人了解你的云梦"
action="${ctx}/file">${deal.description}</div>
</div>
</div>
注意data-bv-excluded=“false”(由于summernote使用了div作为form表单的呈现形式,非一般的input标签,所以此处要将该name="description"的field标识为非excluded,默认的validator是不对“[’:disabled’, ‘:hidden’, ‘:not(:visible)’]”三种标签做处理的,而summernote会默认作为disabled的一种,那么设置上data-bv-excluded=“false” 后,validator将会对summernote做非空的判断)、data-bv-notempty属性。
当然有了上述两个属性后,并不能保证validator的有效性,那么接下来,请继续看。
onChange : function(contents, $editable) {
if ($this.parents().length > 0) {
var $form = $this.parents().find("form.required-validate", $p);
if ($form.length > 0) {
var data = $form.data('bootstrapValidator');
YUNM.debug($this.summernote('isEmpty'));
if ($this.summernote('isEmpty')) {
data.updateStatus($this.attr("name"), 'INVALID');
} else {
data.updateStatus($this.attr("name"), 'VALID');
}
}
}
},
onInit : function() {
if ($this.parents().length > 0) {
var $form = $this.parents().find("form.required-validate", $p);
if ($form.length > 0) {
var data = $form.data('bootstrapValidator');
if (!$this.summernote('isEmpty')) {
data.updateStatus($this.attr("name"), 'VALID');
}
}
}
},
在summernote的callbacks中加入onChange 、onInit,当文本域发生变化、初始化时,对summernote在form中的验证字段进行状态的更新,validator中使用updateStatus方法。
/**
* Update all validating results of field
*
* @param {String|jQuery} field The field name or field element
* @param {String} status The status. Can be 'NOT_VALIDATED', 'VALIDATING', 'INVALID' or 'VALID'
* @param {String} [validatorName] The validator name. If null, the method updates validity result for all validators
* @returns {BootstrapValidator}
*/
updateStatus: function(field, status, validatorName) {