首先感谢前辈们的无私奉献。贴出参考地址
http://zhidao.baidu.com/link?url=Q0ZM405OFNy_xAHSut9TepRJxgXCxFayQttrQz1N82dlA1_JnAb4Ojdl-b9T0AyzPNcgdHWI5h-66RUcVWLW6Mb295rWGUXJFyLw1GBrvwK
贴出效果图
按照前辈的指示。我复制代码存为了一个js文件。引入。关于之前的js代码请移步我贴出的链接。
最开始,我一字不改地复制了代码,除了修改了文件上传的url。测试,发现总是报错,并且不进入sucess也不进入failure。断点检查发现是因为服务器返回的数据格式不对,在解析成json的时候,extjs内部出错了。这里贴出一下后台关键代码仅供参考,后台我用的是asp.net:
protected void Page_Load(object sender, EventArgs e) { if (Request.QueryString["type"] != null && Request.QueryString["type"] == "newsImage") { Response.Write(InsertNewsImage()); Response.End(); } } private string InsertNewsImage() { string uploadPath = "D:\test"; string downloadPath = "http://localhost/UploadFiles"; try { string path = uploadPath + "/NewsImage/"; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } HttpPostedFile file = Request.Files[0]; if (file == null || file.ContentLength == 0 || string.IsNullOrEmpty(file.FileName)) { return "{success:false,error:‘上传文件为空‘}"; } string extName = "." + file.FileName.Substring(file.FileName.LastIndexOf(‘.‘) + 1); string saveName = Guid.NewGuid().ToString() + extName; file.SaveAs(path + "\\" + saveName); return "{success:true,filepath:‘" + downloadPath + "/NewsImage/" + saveName + "‘}"; } catch (Exception e) { return "{success:false,error:‘" + e.Message + "‘}"; } }
注意,后台一定要返回json格式的数组,并且带一个bool类型的success返回值。其他的就可以根据自己的需要返回。
目前为止,可以上传了,也可以显示图片了。但是美中不足的是,图片如果上传太大,显示的太大太大了就,不好控制。于是我加了一个宽高限定上去。
然后这里还有个问题,大家也都会发现。就是返回后的图片总是在文本的最前面,也就是说,无法插入到之前光标在的地方,为什么呢?
于是我仔细去看前辈的方法,也仔细去找extjs 的api看看有没有记录鼠标光标的方法。最后,我看到前辈们用的这个方法
if (Ext.isIE) {
editor.insertAtCursor(element.outerHTML);
}
我去翻阅了一下insertAtCursor的方法,这个方法是这样子的:
function(b){ if(!this.activated) { return } if(Ext.isIE) { this.win.focus(); var a=this.doc.selection.createRange(); if(a) { a.collapse(true); a.pasteHTML(b); this.syncValue(); this.deferFocus() } } else { this.win.focus(); this.execCmd("InsertHTML",b); this.deferFocus() } }
这里大家其实可以发现原因了。在插入图像之前,代码先获得文本框的焦点,在焦点处创建一个Range,这里可以理解成创建一个空元素吧,然后把后台返回的图像的html插入到这个元素里面。注意一下,这里获取焦点这个方法focus()是在上传图片之后执行的,获取焦点之后创建Range。问题就在这里了。在上传图片的时候,文本框是失去焦点的,也就是说,那个时候并不知道光标在哪个地方,因为没有焦点。所以最后总是把图片插在文字的最前面。我们只需要把获取焦点并创建Range的逻辑放在弹出上传对话框之前就好了。然后再把返回的图像路径放到Range里面。下面贴出插件全部代码!
var HTMLEditor = Ext.extend(Ext.form.HtmlEditor, { addImage: function() { var editor = this; editor.win.focus(); var range = editor.doc.selection.createRange(); var imgform = new Ext.FormPanel({ region: ‘center‘, labelWidth: 55, frame: true, bodyStyle: ‘padding:5px 5px 0‘, autoScroll: true, border: false, fileUpload: true, items: [{ xtype: ‘textfield‘, fieldLabel: ‘选择图片‘, id: ‘UserFile‘, name: ‘UserFile‘, inputType: ‘file‘, allowBlank: false, blankText: ‘文件不能为空‘, anchor: ‘90%‘ }, { xtype: ‘textfield‘, fieldLabel: ‘高(像素)‘, id: ‘height‘, name: ‘height‘, allowBlank: false, regex: /^\d+$/, regexText: ‘请输入数字‘, blankText: ‘请填写图片显示的高度‘, anchor: ‘90%‘ }, { xtype: ‘textfield‘, fieldLabel: ‘宽(像素)‘, id: ‘width‘, name: ‘width‘, allowBlank: false, regex: /^\d+$/, regexText: ‘请输入数字‘, blankText: ‘请填写图片显示的宽度‘, anchor: ‘90%‘ }], buttons: [{ text: ‘上传‘, handler: function() { if (!imgform.form.isValid()) { return; } var formValues = imgform.form.getValues(); var width = formValues["width"]; var height = formValues["height"]; if (!width || !height || width == "0" || height == "0") { MessageBox(‘错误‘, "请填写正确的宽度和高度"); return; } imgform.form.submit({ waitMsg: ‘正在上传......‘, url: ‘SaveAffix.aspx?type=newsImage‘, success: function(form, action) { var element = document.createElement("img"); element.style.width = width + "px"; element.style.height = width + "px"; element.src = action.result.filepath; if (Ext.isIE) { if (range) { range.collapse(true); range.pasteHTML(element.outerHTML); editor.syncValue(); editor.deferFocus() } } else { var selection = editor.win.getSelection(); if (!selection.isCollapsed) { selection.deleteFromDocument(); } selection.getRangeAt(0).insertNode(element); } form.reset(); win.close(); }, failure: function(form, action) { form.reset(); if (action.failureType == Ext.form.Action.SERVER_INVALID) MessageBox(‘上传失败‘, action.result.error); } }); } }, { text: ‘关闭‘, handler: function() { win.close(this); } }] }) var win = new Ext.Window({ title: "上传图片", width: 300, height: 200, modal: true, border: false, iconCls: "img.gif", layout: "fit", items: imgform }); win.show(); }, createToolbar: function(editor) { HTMLEditor.superclass.createToolbar.call(this, editor); this.tb.insertButton(16, { cls: "x-btn-icon", icon: "img.gif", handler: this.addImage, scope: this }); } });
使用方法:var Content = new HTMLEditor({ fieldLabel: ‘内容‘, width: 600, height: 250, value: contentValue });
最后值得一提的是,这只是一个例子,我没有判断上传文件的类型。大家可以在前端判断也可以在后端判断返回错误提示。祝愉快。