wangEditor(轻量级web富文本编辑器)学习[全面]

了解:

我为什么要做富文本编辑器【wangEditor5个月总结】

轻量级富文本编辑器wangEditor源码结构介绍

wangEditor——介绍、使用手册

学习:

wangEditor包的下载 —— 轻量级web富文本框【试用:http://wangEditor.github.io/

wangEditor上传本地视频

参考:

wangEditor的使用【主要讲脚本代码】

wangEditor - 轻量级web富文本编辑器(可带图片上传)【有对应的pojo、controller、jsp(含js)、导入依赖代码(若带图片上传,可以看看)】

使用wangEditor实现富文本编辑(后端为Java)【全面:有对应的pojo、controller、jsp(含js)、service、serviceImp代码(若带图片上传,可以看看)】

$.ajax() AJAX请求页面接收后台json数据显示[object Object]解决方法【JSON.stringify()】

Bootstrap-table如何显示后台传过来的JSON数据?【$.getJSON()】

-------------------------没有带图片上传,只是简单的通知公告--------------- 

(我只传三个控件值,notice、title、content)ajax传的值为“[object Object]”,导致传值不了给Javabean对象 :

 

 改: (对我的,没有用,或许在后台要做某些操作才能取ajax传过来的json值,我没继续处理了)

可是照样传值不了给NoticeDetailVo对象

改:(对我的,也没有用)

改:(成功的!!!)

编辑前:

编辑发布后: 

多加了个id为content的隐藏控件,为了将editor.txt.html()获取的内容赋值于这个隐藏控件,然后通过ajax取form1表单数据并传至后台:(代码随着页面的完成,而更改了些许,成为正确的能正常使用的页面代码,还补充success属性!!!

-------------------------jsp页面代码-----------------------------------
<head>
    <!-- 文本编辑器(src值错误,导致编辑器无用)    css文件控制这"toolbar"的工具效果   js文件控制这编辑框和toolbar的显示与编辑框的文本获取 -->
    <link rel="stylesheet" href="../editor/wangEditor.min.css">
    <script type="text/javascript" src="../editor/wangEditor.min.js"></script>
    <style>
		.text {
			border: 1px solid #ccc;
			height: 300px;
			/*width: 800px;*/
		}
		.toolbar {
			border: 1px solid #ccc;
			/*width: 800px;*/
		}
	    body {
	        padding-top: 10px;
	        /*background-color: aqua; */
	    }		
    </style>
</head>
<body>
	<div class="container">
		<form  role="form" method="post" id="form1" name="form1">
			<a class="btn btn-default" href="${pageContext.request.contextPath }/noticeDetail/index" method="post" >返回</a>
			<input type="hidden" id="noticeId" name="noticeId" value="${ndVo.noticeId }">
			<input type="hidden" id="content" name="content" >
			<div class="form-group">
				<label for="title"><h4 style="text-align:left;padding:10px;"><b>标题</b></h4></label>
				<input type="text" class="form-control" id="title" placeholder="请输入标题" name="title" value="${ndVo.title }"/>
				<span class="col-lg-8" id="editor"></span>
			</div>
		</form>
        <div class="form-group" >
                <button class="btn btn-primary" id="save">发布</button>
         </div>
	</div>
    <script>
    $(function(){
        var E = window.wangEditor;
        var editor = new E('#editor');

        
        //代码随着页面的完成,而更改了些许,成为正确的能正常使用的页面代码
        // 自定义菜单配置,没有这个,editor.create()自动加上menu(菜单和编辑框在一起的),若用div1和div2的,菜单和编辑框是分开的
        editor.customConfig.menus = [
			    'head',  // 标题
			    'bold',  // 粗体
			    'fontSize',  // 字号
			    'fontName',  // 字体
			    'italic',  // 斜体
			    'underline',  // 下划线
			    'strikeThrough',  // 删除线
			    'foreColor',  // 文字颜色
			    'backColor',  // 背景颜色
			    'link',  // 插入链接
			    'list',  // 列表
			    'justify',  // 对齐方式
			    'quote',  // 引用
			    //'emoticon',  // 表情
			    'image',  // 插入图片
			    'table',  // 表格
			    //'video',  // 插入视频
			    'code',  // 插入代码
			    'undo',  // 撤销
			    'redo'  // 重复
        ];

        //创建编辑器
        editor.create();

        $("#save").click(function(){
            //获取内容(含标签代码)"<p>你好世界</p><span........."
            var content = editor.txt.html();
            //获取内容的文本内容
            var content2=editor.txt.text();
            $("#content").val(content);//将值赋值给隐藏控件,
            var form = new FormData(document.getElementById("form1"));
            $.ajax({
                url : "${pageContext.request.contextPath }/noticeDetail/update",
                type : "post",
                data : form,
                cache : false,
                processData : false,
                contentType : false,

                //补充:这是做着做着项目发现要加上的success属性
                success : function(result) {
                    window.location.href="${pageContext.request.contextPath }/noticeDetail/index";//动态输出跳转,路径还是要加上绝对路径的(注意绝对路径后要加上'/'否则404"项目名noticeDetail/index")!!!
                },

                error : function(result) {
                    alert("网络错误,请重试!!");
                }
            });				
        });
    })
    </script>
</body>

 

---------------noticeDetail/add  控制器-------------
@Controller
@RequestMapping(value="/noticeDetail")
public class NoticeDetailController {

	@Resource
	NoticeDetailService ndService;
	@Resource
	EmployeeService empService;
	@Resource
	DepService depService;
	@Resource
	ClassService clsService;
	List<EmployeeVo> empList;
	String depIds="";
	String clsIds="";
	
	@RequestMapping(value="/index")
	public String  index(Map map){
		empList=empService.listAllNoPage();
		List<DepartmentVo> depList=depService.findAllDep();
		depIds="";//初始化
		clsIds="";
		for (DepartmentVo depVo : depList) {
			depIds+=depVo.getDepId()+",";
		}
		List<ClassVo> clsList=clsService.list();
		for (ClassVo clsVo : clsList) {
			clsIds+=clsVo.getClassId()+",";
		}
		map.put("empList",empList);//弹框和列表在同一页面,那么传EmpList这样的值,要在一进入时传进去,而不是放在list()里,json返回没谁接收
		map.put("depList",depList);
		map.put("clsList",clsList);		
		return "qyf/noticeDetailList";//我就不显示noticeDetailList页面了,目前不重要
	}
    @RequestMapping("/list")
	@ResponseBody
	public Map list(@RequestBody Map<String,Object> params,NoticeDetailVo nd){
    ......................
    }
	@RequestMapping("/add")
	public String add(NoticeDetailVo nd,Map map){
		if(nd.getNoticeId()==0){
			System.out.println("-----------add------"+nd);//自动调用toString()
			int i=nd.getTypeId();
			depIds=depIds.substring(0, depIds.lastIndexOf(','));//将末尾多余的','去除
			clsIds=depIds.substring(0, clsIds.lastIndexOf(','));//将末尾多余的','去除
			System.out.println("depIds=="+depIds+"         clsIds=="+clsIds);
			if(i==1){
				nd.setDepIds(depIds);
				nd.setClassIds(clsIds);
			}else if(i==2){
				nd.setDepIds(depIds);
			}else if(i==4){
				nd.setClassIds(clsIds);
			}
			nd.setStatus(1);			
			ndService.add(nd);
			nd=ndService.ndById(nd.getNoticeId());
			map.put("ndVo", nd);			
		}
		return "qyf/noticeDetailAdd";//从表单提交到这方法,无需@ResponseBody注解,那么我转向其他页面,直接return其他页面
	}
    @RequestMapping("/update")
	@ResponseBody
	public String update(NoticeDetailVo nd){
		if(nd.getNoticeId()!=0){	
            System.out.println("-----------add_update------"+nd);		
			ndService.update(nd);
		}
		return "";//add页面用ajax传到update方法修改完之后要加注解@ResponseBody返回原来add页面,不论return什么(要是有传值回页面的必要,当然传某些值),加了之后都会去success属性(在里面加location.window.href能从add页面跳转List页面),否则去error里并会弹出"网络错误,请重试!!"
	}
}

----------Service类    DAO接口类、DAO配置文件(Mapper)----------------------------












了解:

MySQL中varchar最大长度是多少?【我的MySQL5.5版】

通知公告内容可能不满足于varchar255字符长度,所以:

(警告的译文:行大小太大。使用的表类型(不包括blob)的最大行大小为65535。这涉及到存储开销,请检查手册。您必须将一些列更改为文本或blob)

然后我改: 

了解:【不同方式展示他们的不同】

window.location.href的用法(动态输出跳转)

window.location.href和window.open的几种用法和区别

ajax传值给通知公告的update方法,修改之后,一定会返回ajax在的页面(add页面),所以加注解@ResponseBody,return什么都行,反正不会报错,很成功的去success属性的function里,想跳转别的页面,用“  window.location.href="........."   ”语句: 

我在编辑器加了emoji表情(那个黄色笑脸的),点击“发布”按钮,后台就报错了:

严重: Servlet.service() for servlet [SpringMVC] in context with path [/HTGlory] threw exception [Request processing failed; nested exception is org.springframework.jdbc.UncategorizedSQLException: 
### Error updating database.  Cause: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x89</...' for column 'content' at row 1
### The error may involve com.ht.qyf.mapper.NoticeDetailDAO.update-Inline
### The error occurred while setting parameters
### SQL: update NoticeDetail        SET title=?,                                           content=?           where noticeId=?;
### Cause: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x89</...' for column 'content' at row 1
; uncategorized SQLException for SQL []; SQL state [HY000]; error code [1366]; Incorrect string value: '\xF0\x9F\x98\x89</...' for column 'content' at row 1; nested exception is java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x89</...' for column 'content' at row 1] with root cause
java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x89</...' for column 'content' at row 1
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:957)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3878)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3814)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551)
	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
	at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1192)
	at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3005)
	at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_execute(FilterEventAdapter.java:440)
	at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3003)
	at com.alibaba.druid.proxy.jdbc.PreparedStatementProxyImpl.execute(PreparedStatementProxyImpl.java:136)
	at com.alibaba.druid.pool.DruidPooledPreparedStatement.execute(DruidPooledPreparedStatement.java:493)
	at sun.reflect.GeneratedMethodAccessor150.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:62)
	at com.sun.proxy.$Proxy43.execute(Unknown Source)
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:44)
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:69)
	at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:48)
	at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:105)
	at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:71)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:152)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:355)
	at com.sun.proxy.$Proxy96.update(Unknown Source)
	at org.mybatis.spring.SqlSessionTemplate.update(SqlSessionTemplate.java:251)
	at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:54)
	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52)
	at com.sun.proxy.$Proxy114.update(Unknown Source)
	at com.ht.qyf.service.NoticeDetailService.update(NoticeDetailService.java:59)
	at com.ht.qyf.service.NoticeDetailService$$FastClassBySpringCGLIB$$4c18c4e.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
	at com.ht.qyf.service.NoticeDetailService$$EnhancerBySpringCGLIB$$9641ed30.update(<generated>)
	at com.ht.qyf.controller.NoticeDetailController.add(NoticeDetailController.java:136)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:777)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:706)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)

借鉴:

存储emoji表情时,数据库存储失败 ,控制台 Caused by: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x97\

参考:

 彻底解决:java.sql.SQLException: Incorrect string value: '\xF0\x9F\x92\x94' for column 'name' at row 1【说要:修改数据表的编码为utf8mb4】

参考文章说:

要先改my.ini文件,然后重启MySQL,接着“修改数据表的编码为utf8mb4” ,再接着,我的SSM项目的jdbc.properties里的jdbc_url不加characterEncoding=UTF-8,最后就是重启项目(restart)【最终,对于我的,还是无用的,接着,我就想,通知公告,这么严肃的事儿,发什么表情!!!所以不继续处理,而是将“自定义菜单”的emoji注释掉】

----------------------------------------THE END------------------------------------

 

 

 

 

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yvette_QIU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值