1、作用:
在.net开发过程中,经常需要文章信息发布功能,常用的开源的文本编辑器ckeditor和kindeditor等。kindeditor是一款比较好用的编辑插件,功能齐全。
2、代码
<%@ Page Language="C#" AutoEventWireup="true" validateRequest="false" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
this.Literal1.Text = Request.Form["content1"];
}
</script>
<!doctype html>
<html>
<head runat="server">
<meta charset="utf-8" />
<title>KindEditor ASP.NET</title>
<link rel="stylesheet" href="webEditor/themes/default/default.css" />
<link rel="stylesheet" href="webEditor/plugins/code/prettify.css" />
<script charset="utf-8" src="webEditor/kindeditor.js"></script>
<script charset="utf-8" src="webEditor/lang/zh_CN.js"></script>
<script charset="utf-8" src="webEditor/plugins/code/prettify.js"></script>
<script>
KindEditor.ready(function(K) {
var editor1 = K.create('#content1', {
cssPath : 'webEditor/plugins/code/prettify.css',
uploadJson : 'webEditor/upload_json.ashx',
fileManagerJson : 'webEditor/file_manager_json.ashx',
allowFileManager : true,
afterCreate : function() {
var self = this;
K.ctrl(document, 13, function() {
self.sync();
K('form[name=example]')[0].submit();
});
K.ctrl(self.edit.doc, 13, function() {
self.sync();
K('form[name=example]')[0].submit();
});
}
});
prettyPrint();
});
</script>
</head>
<body>
<asp:Label ID="Label1" runat="server" Text="">
</asp:Label>
<asp:Literal ID="Literal1" runat="server"></asp:Literal>
<form id="example" runat="server">
<textarea id="content1" cols="100" rows="8" style="width:700px;height:200px;visibility:hidden;" runat="server"></textarea>
<br />
<asp:Button ID="Button1" runat="server" Text="提交内容" /> (提交快捷键: Ctrl + Enter)
</form>
</body>
</html>
kindeditor一个比较给力的WYSISG编辑器,比较给力,爆米花工作室提供的网站中,kindeditor基本上是标配。然而,kindeditor缺失一个比较重要的功能:上传附件,虽然有上传图片的功能与上传附件类似,但上传附件功能的缺失造成了一定的影响,于是,只有将自己弄了。
比较幸运的是,kindeditor基于插件的设计,扩展方便,整一个插件很简单,于是,本文参照上传图片插件,并参考了网上的一些资料,完成了一个简单的上传附件的插件。
功能限定
上传附件插件允许*.zip和*.rar的文件,上传到编辑器目录的attached目录下,附件上传完成后,编辑器的文本中,添加一个“下载附件”链接,指向上传的附件,服务器端为.net环境。
插件开发
(1) 基本配置
kindeditor的脚本文件kindeditor.js的KE.lang中,添加accessory : '插入附件'
invalidAccessory: "请上传有效的文件,只允许rar,zip格式。"KE.lang通过JSON格式,定义了“语言资源”。
(2) 上传附件的对话框HTML文件
<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Accessory</title>
<style type="text/css">
body { font-size: 12px; margin: 0px; background: #F0F0EE; overflow: hidden; }
</style>
<script type="text/javascript">
var KE = parent.KindEditor;
location.href.match(/\?id=([\w-]+)/i);
var id = RegExp.$1;
KE.event.ready(function () { KE.util.hideLoadingPage(id); }, window, document);
</script>
</head>
<body>
<iframe name="uploadIframe" id="uploadIframe" style="display:none;"></iframe>
<form name="uploadForm" method="post" enctype="multipart/form-data" action="../accessory_upload_json.ashx" target="uploadIframe">
<input type="hidden" id="editorId" name="id" value="" />
<table border="0" cellpadding="0" cellspacing="0" align="center">
<tr><td><input type="file" id="accessoryFile" name="accessoryFile" style="width:220px;" /></td></tr>
</table>
</form>
</body>
</html>以上代码,作为accessory.html文件,置于编辑器目录的plugin目录下。
(3) 上传附件的服务器端文件<%@ WebHandler Language="C#" class="Accessory" %>
using System;
using System.Collections;
using System.Web;
using System.IO;
using System.Globalization;
using LitJson;
public class Accessory : IHttpHandler
{
private String savePath = "./attached/";
//文件保存目录URL
private String saveUrl = "../Scripts/Editor/attached/";
//定义允许上传的文件扩展名
private String fileTypes = "zip,rar";
//最大文件大小(bytes)
private int maxSize = 100000000;
private HttpContext context;
public void ProcessRequest(HttpContext context)
{
this.context = context;
HttpPostedFile accessoryFile = context.Request.Files["accessoryFile"];
if (accessoryFile == null)
{
showError("请选择文件。");
}
String dirPath = context.Server.MapPath(savePath);
if (!Directory.Exists(dirPath))
{
showError("上传目录不存在。");
}
String fileName = accessoryFile.FileName;
String fileExt = Path.GetExtension(fileName).ToLower();
ArrayList fileTypeList = ArrayList.Adapter(fileTypes.Split(','));
if (accessoryFile.InputStream == null || accessoryFile.InputStream.Length > maxSize)
{
showError("上传文件大小超过限制。");
}
if (String.IsNullOrEmpty(fileExt) || Array.IndexOf(fileTypes.Split(','), fileExt.Substring(1).ToLower()) == -1)
{
showError("上传文件扩展名是不允许的扩展名。");
}
String newFileName = DateTime.Now.ToString("yyyyMMddHHmmss_ffff", DateTimeFormatInfo.InvariantInfo) + fileExt;
String filePath = dirPath + newFileName;
accessoryFile.SaveAs(filePath);
String fileUrl = saveUrl + newFileName;
Hashtable hash = new Hashtable();
hash["error"] = 0;
hash["url"] = fileUrl;
context.Response.AddHeader("Content-Type", "text/html; charset=UTF-8");
context.Response.Write(JsonMapper.ToJson(hash));
context.Response.End();
}
private void showError(string message)
{
Hashtable hash = new Hashtable();
hash["error"] = 1;
hash["message"] = message;
context.Response.AddHeader("Content-Type", "text/html; charset=UTF-8");
context.Response.Write(JsonMapper.ToJson(hash));
context.Response.End();
}
public bool IsReusable
{
get
{
return true;
}
}
}以上.net代码,作为accessory_upload_json.ashx文件,置于编辑器目录之中。
(3) 插件核心KE.plugin['accessory'] = {
click : function (id) {
KE.util.selection(id);
this.dialog = new KE.dialog({
id : id,
cmd : 'accessory',
file : 'accessory.html',
width : 310,
height : 55,
loadingMode : true,
title : KE.lang['accessory'],
yesButton : KE.lang['yes'],
noButton: KE.lang['no']
});
this.dialog.show();
},
check: function (id) {
var dialogDoc = KE.util.getIframeDoc(this.dialog.iframe);
var url = KE.$('accessoryFile', dialogDoc).value;
if (url.match(/\.(rar|zip)$/i) == null) {
alert(KE.lang['invalidAccessory']);
window.focus();
KE.g[id].yesButton.focus();
return false;
}
return true;
},
exec : function (id) {
var self = this;
var dialogDoc = KE.util.getIframeDoc(this.dialog.iframe);
if (!this.check(id)) return false;
KE.$('editorId', dialogDoc).value = id;
var uploadIframe = KE.$('uploadIframe', dialogDoc);
KE.util.showLoadingPage(id);
var onloadFunc = function() {
KE.event.remove(uploadIframe, 'load', onloadFunc);
KE.util.hideLoadingPage(id);
var uploadDoc = KE.util.getIframeDoc(uploadIframe);
var data = '';
try {
data = KE.util.parseJson(uploadDoc.body.innerHTML);
} catch(e) { alert(KE.lang.invalidJson); }
if (typeof data === 'object' && 'error' in data) {
if (data.error === 0) {
self.insert(id, data.url);
} else {
alert(data.message);
return false;
}
}
};
KE.event.add(uploadIframe, 'load', onloadFunc);
dialogDoc.uploadForm.submit();
return;
},
insert : function (id, url) {
KE.util.insertHtml(id, '<a href="' + url + '" >下载附件</a>');
this.dialog.hide();
KE.util.focus(id);
}
};以上代码,作为插件的核心,置于脚本文件kindeditor.js中,可以看到,kindeditor的代码设计风格非常好。
(4) 插件的图标
插件于Kindeditor中,图标是通过Css Sprite实现的16*16,网上找了个简单的,压缩成16*16,通过PhotoShop将之附在编辑器目录的skins/default的default.gif的最后,再将下面的CSS Sprite代码,置于编辑器目录的skins目录的default.css中。.ke-icon-accessory
{
background-position: 0px -960px;
width: 16px;
height: 16px;
}(5) 插件启用
kindeditor.js的KE.setting中,将’accessory’添加到items中,启用插件
插件的基本效果
(1) kindeditor的基本界面
开发完成的测试中,出现了一个比较有趣的问题,就是提交了附件,一直处于等待状态,没有任何提示,后来跟踪调试了下,原来是文件过大,抛出了“超过了最大请求长度”的异常。
于是,修改了Web.config下配置:
<system.web>
<httpRuntime maxRequestLength="***" executionTimeout="***" />
</system.web>maxRequestLength指定了最大请求长度(KB),executionTimeout指定了超时时间(s)
小结:
以上代码仅实现了上传rar与zip格式,要上传其他格式,修改如下
1、修改accessory_upload_json.ashx文件
//定义允许上传的文件扩展名
private String fileTypes
2、修改kindeditor.js
KE.plugin['accessory']下边的
check: function (id) 函数里面的正
- kindeditor-4.1.4.zip (854.5 KB)