layui(諧音:類UI) 是一款採用自身模塊規範編寫的前端 UI 框架,遵循原生 HTML/CSS/JS 的書寫與組織形式,門檻極低,拿來即用。其外在極簡,卻又不失飽滿的內在,體積輕盈,組件豐盈,從核心代碼到 API 的每一處細節都通過精心雕琢,很是適合界面的快速開發。layui 首個版本發佈於2016年金秋,她區別於那些基於 MVVM 底層的 UI 框架,卻並不是逆道而行,而是信奉返璞歸真之道。準確地說,她更可能是爲服務端程序員量身定作,你無需涉足各類前端工具的複雜配置,只需面對瀏覽器自己,讓一切你所須要的元素與交互,從這裏信手拈來。javascript
layui 兼容人類正在使用的所有瀏覽器(IE6/7除外),可做爲 PC 端後臺系統與前臺界面的速成開發方案。php
文檔:http://www.layui.com/doc/css
官網:http://www.layui.com/html
git:https://github.com/sentsin/layui前端
下載layui將dest中的內容添加到項目中java
項目:node
新建admin.htmljquery
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <title>layout 後臺大布局 - Layui</title> <link rel="stylesheet" href="js/layui/css/layui.css"> </head> <body class="layui-layout-body"> <div class="layui-layout layui-layout-admin"> <div class="layui-header"> <div class="layui-logo">layui 後臺佈局</div> <!-- 頭部區域(可配合layui已有的水平導航) --> <ul class="layui-nav layui-layout-left"> <li class="layui-nav-item"> <a href="">控制檯</a> </li> <li class="layui-nav-item"> <a href="">商品管理</a> </li> <li class="layui-nav-item"> <a href="">用戶</a> </li> <li class="layui-nav-item"> <a href="javascript:;">其它系統</a> <dl class="layui-nav-child"> <dd> <a href="">郵件管理</a> </dd> <dd> <a href="">消息管理</a> </dd> <dd> <a href="">受權管理</a> </dd> </dl> </li> </ul> <ul class="layui-nav layui-layout-right"> <li class="layui-nav-item"> <a href="javascript:;"> <img src="http://t.cn/RCzsdCq" class="layui-nav-img"> 賢心 </a> <dl class="layui-nav-child"> <dd> <a href="">基本資料</a> </dd> <dd> <a href="">安全設置</a> </dd> </dl> </li> <li class="layui-nav-item"> <a href="">退了</a> </li> </ul> </div> <div class="layui-side layui-bg-black"> <div class="layui-side-scroll"> <!-- 左側導航區域(可配合layui已有的垂直導航) --> <ul class="layui-nav layui-nav-tree" lay-filter="test"> <li class="layui-nav-item layui-nav-itemed"> <a class="" href="javascript:;">全部商品</a> <dl class="layui-nav-child"> <dd> <a href="javascript:;">列表一</a> </dd> <dd> <a href="javascript:;">列表二</a> </dd> <dd> <a href="javascript:;">列表三</a> </dd> <dd> <a href="http://www.baidu.com">超連接</a> </dd> </dl> </li> <li class="layui-nav-item"> <a href="javascript:;">解決方案</a> <dl class="layui-nav-child"> <dd> <a href="javascript:;">列表一</a> </dd> <dd> <a href="javascript:;">列表二</a> </dd> <dd> <a href="">超連接</a> </dd> </dl> </li> <li class="layui-nav-item"> <a href="">雲市場</a> </li> <li class="layui-nav-item"> <a href="">發佈商品</a> </li> </ul> </div> </div> <div class="layui-body"> <!-- 內容主體區域 --> <div style="padding: 15px;"> <table id="demo" lay-filter="test"></table> </div> </div> <div class="layui-footer"> <!-- 底部固定區域 --> © layui.com - 底部固定區域 </div> </div> <script src="js/layui/layui.all.js"></script> <script> //JavaScript代碼區域 layui.use('element', function() { var element = layui.element; }); layui.use('table', function(){ var table = layui.table; //第一個實例 table.render({ elem: '#demo' ,height: 315 ,url: '/demo/table/user/' //數據接口 ,page: true //開啓分頁 ,cols: [[ //表頭 {field: 'id', title: 'ID', width:80, sort: true, fixed: 'left'} ,{field: 'username', title: '用戶名', width:80} ,{field: 'sex', title: '性別', width:80, sort: true} ,{field: 'city', title: '城市', width:80} ,{field: 'sign', title: '簽名', width: 177} ,{field: 'experience', title: '積分', width: 80, sort: true} ,{field: 'score', title: '評分', width: 80, sort: true} ,{field: 'classify', title: '職業', width: 80} ,{field: 'wealth', title: '財富', width: 135, sort: true} ]] }); }); </script> </body> </html>
結果git
package com.zhangguo.utils; public class R { /**響應編碼*/ private int code; /**響應消息*/ private String msg; /**數據總量*/ private int count; /**數據*/ private Object data; public R() { } public R(int code, String msg, int count, Object data) { super(); this.code = code; this.msg = msg; this.count = count; this.data = data; } @Override public String toString() { return "R [code=" + code + ", msg=" + msg + ", count=" + count + ", data=" + data + "]"; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } }
package com.zhangguo.dao; import java.util.ArrayList; import java.util.List; import java.util.UUID; import com.zhangguo.entity.User; /** * 用戶數據訪問 */ public class UserDao { private static List<User> users = new ArrayList<>(); static { for (int i = 1; i <= 500; i += 3) { users.add(new User(i, "張國立" + UUID.randomUUID(), "中國北京" + UUID.randomUUID())); users.add(new User(i + 1, "張學友" + UUID.randomUUID(), "中國香港" + UUID.randomUUID())); users.add(new User(i + 2, "張慧妹" + UUID.randomUUID(), "中國珠海" + UUID.randomUUID())); } } //http://www.layui.com/demo/table/user/?page=1&limit=10 /** 得到全部用戶 */ public List<User> getPager(int page,int limit) { List<User> list = new ArrayList<>(); int start=(page-1)*limit; for (int i =start; i <start+limit&&i<users.size(); i++) { list.add(users.get(i)); } return list; } /** 得到全部用戶 */ public List<User> getAllUsers() { return users; } /** 添加用戶 */ public void addUser(User user) { if (user.getId() <= 0) { // 未設置id int index = users.size() - 1; // 得到最後一個用戶的索引號 if (index < 0) { // 如沒有一個用戶 user.setId(1); // 編號爲1 } else { user.setId(users.get(index).getId() + 1); // 得到最後一個用戶的編號+1 } } users.add(user); } /** 刪除用戶 */ public void delUser(int id) { User delUser = null; for (User user : users) { if (user.getId() == id) { delUser = user; break; } } users.remove(delUser); } public void updateUser(User obj) { User editUser = null; for (User user : users) { if (user.getId() == obj.getId()) { editUser = user; break; } } editUser.setName(obj.getName()); editUser.setCity(obj.getCity()); } }
package com.zhangguo.action; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.zhangguo.dao.UserDao; import com.zhangguo.entity.User; import com.zhangguo.test.JsonUtils; import com.zhangguo.utils.R; /** * 用戶控制器 */ @WebServlet("/UserController") public class UserController extends HttpServlet { private static final long serialVersionUID = 1L; private UserDao userDao = new UserDao(); protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("utf-8"); response.setContentType("application/json;charset=utf-8"); request.setCharacterEncoding("utf-8"); String action = request.getParameter("action"); if (action.equals("list")) { list(response); //得到全部用戶 }else if (action.equals("add")) { add(request, response); //添加新用戶 } else if (action.equals("del")) { //刪除用戶 delUser(request, response); } else if (action.equals("update")) { //更新用戶 int id =Integer.parseInt(request.getParameter("id")); String name = request.getParameter("name"); String city = request.getParameter("city"); userDao.updateUser(new User(id,name, city)); delay(); response.getWriter().print("{\"msg\":\"更新成功\"}"); } else if (action.equals("pager")) { //分頁 int page =Integer.parseInt(request.getParameter("page")); int limit =Integer.parseInt(request.getParameter("limit")); R r=new R(); r.setCode(0); r.setMsg("得到數據成功"); r.setCount(500); r.setData(userDao.getPager(page, limit)); delay(); response.getWriter().print(JsonUtils.toJson(r)); } } /**刪除用戶*/ public void delUser(HttpServletRequest request, HttpServletResponse response) throws IOException { int id =Integer.parseInt(request.getParameter("id")); userDao.delUser(id); delay(); response.getWriter().print("{\"msg\":\"刪除成功\"}"); } /**添加新用戶*/ public void add(HttpServletRequest request, HttpServletResponse response) throws IOException { String name = request.getParameter("name"); String city = request.getParameter("city"); userDao.addUser(new User(name, city)); delay(); response.getWriter().print("{\"msg\":\"添加成功\"}"); } /**得到全部用戶*/ public void list(HttpServletResponse response) throws IOException { //Java 對象 - > 字符串 序列化成JSON //字符串 -> Java對象 反序列化 String result = "["; for (User user : userDao.getAllUsers()) { result += "{\"id\":" + user.getId() + ",\"name\":\"" + user.getName() + "\",\"city\":\"" + user.getCity() + "\"},"; } if (result.substring(result.length() - 1, result.length()).equals(",")) { result = result.substring(0, result.length() - 1); } result += "]"; delay(); response.getWriter().print(result); } public void delay(){ try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <title>layout 後臺大布局 - Layui</title> <link rel="stylesheet" href="js/layui/css/layui.css"> </head> <body class="layui-layout-body"> <div class="layui-layout layui-layout-admin"> <div class="layui-header"> <div class="layui-logo">layui 後臺佈局</div> <!-- 頭部區域(可配合layui已有的水平導航) --> <ul class="layui-nav layui-layout-left"> <li class="layui-nav-item"> <a href="">控制檯</a> </li> <li class="layui-nav-item"> <a href="">商品管理</a> </li> <li class="layui-nav-item"> <a href="">用戶</a> </li> <li class="layui-nav-item"> <a href="javascript:;">其它系統</a> <dl class="layui-nav-child"> <dd> <a href="">郵件管理</a> </dd> <dd> <a href="">消息管理</a> </dd> <dd> <a href="">受權管理</a> </dd> </dl> </li> </ul> <ul class="layui-nav layui-layout-right"> <li class="layui-nav-item"> <a href="javascript:;"> <img src="http://t.cn/RCzsdCq" class="layui-nav-img"> 賢心 </a> <dl class="layui-nav-child"> <dd> <a href="">基本資料</a> </dd> <dd> <a href="">安全設置</a> </dd> </dl> </li> <li class="layui-nav-item"> <a href="">退了</a> </li> </ul> </div> <div class="layui-side layui-bg-black"> <div class="layui-side-scroll"> <!-- 左側導航區域(可配合layui已有的垂直導航) --> <ul class="layui-nav layui-nav-tree" lay-filter="test"> <li class="layui-nav-item layui-nav-itemed"> <a class="" href="javascript:;">全部商品</a> <dl class="layui-nav-child"> <dd> <a href="javascript:;">列表一</a> </dd> <dd> <a href="javascript:;">列表二</a> </dd> <dd> <a href="javascript:;">列表三</a> </dd> <dd> <a href="http://www.baidu.com">超連接</a> </dd> </dl> </li> <li class="layui-nav-item"> <a href="javascript:;">解決方案</a> <dl class="layui-nav-child"> <dd> <a href="javascript:;">列表一</a> </dd> <dd> <a href="javascript:;">列表二</a> </dd> <dd> <a href="">超連接</a> </dd> </dl> </li> <li class="layui-nav-item"> <a href="">雲市場</a> </li> <li class="layui-nav-item"> <a href="">發佈商品</a> </li> </ul> </div> </div> <div class="layui-body"> <!-- 內容主體區域 --> <div style="padding: 15px;"> <table id="users" lay-filter="test"></table> </div> </div> <div class="layui-footer"> <!-- 底部固定區域 --> © layui.com - 底部固定區域 </div> </div> <script src="js/layui/layui.all.js"></script> <script> //JavaScript代碼區域 layui.use('element', function() { var element = layui.element; }); layui.use('table', function(){ var table = layui.table; //第一個實例 table.render({ elem: '#users' ,height: 515 ,url: 'UserController?action=pager' //數據接口 ,page: true //開啓分頁 ,cols: [[ //表頭 {field: 'id', title: 'ID', width:80, sort: true, fixed: 'left'} ,{field: 'name', title: '用戶名', width:300,sort: true} ,{field: 'city', title: '城市', width:300,sort: true} ,{field: 'birthday', title: '出生日期', width: 177,sort: true} ]] }); }); </script> </body> </html>
實現商品的後臺管理功能,添加,修改,刪除,更新,上傳,富文本,前臺展現,手機端的瀏覽程序員
--商品 --編號,名稱,價格,上架時間,狀態,圖片 --建立數據庫 create database GoMallPro; use GoMallPro; --建立表 create table Product ( id int primary key identity(100000,1), name nvarchar(256) not null, price decimal(9,2), addDate datetime, [state] int default(1), picture varchar(126) ) --添加數據 INSERT INTO [GoMallPro].[dbo].[Product] ([name] ,[price] ,[addDate] ,[state] ,[picture]) select 'iPhone X',5898.5,GETDATE(),1,'pic(1).jpg' union select 'Meizu 魅藍1',999.9,'2014-01-12',1,'pic(2).jpg' union select 'ZTE U880',566.85,GETDATE(),0,'pic(3).jpg' union select '華爲 榮耀6',1487.3,'2018-04-15',1,'pic(4).jpg' union select '小米 Max 2',1398.2,'2017-12-09',0,'pic(5).jpg' SELECT [id] ,[name],[price] ,[addDate],[state],[picture] FROM [Product]
結果:
建立一個web項目,記得選擇生成web.xml文件
建立完成
在webcontent目錄下添加images圖片目錄
在webcontent目錄下添加layui 後臺模板
添加後的效果
部署運行
建立頁,未修改的模板
後臺管理
Product.java
package com.zhangguo.gomallpro.model; import java.math.BigDecimal; import java.util.Date; /** * 產品 Bean * */ public class Product { private int id; private String name; private BigDecimal price; private Date addDate; private int state; private String picture; public Product() { } public Product(int id, String name, BigDecimal price, Date addDate, int state, String picture) { super(); this.id = id; this.name = name; this.price = price; this.addDate = addDate; this.state = state; this.picture = picture; } @Override public String toString() { return "Product [id=" + id + ", name=" + name + ", price=" + price + ", addDate=" + addDate + ", state=" + state + ", picture=" + picture + "]"; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public BigDecimal getPrice() { return price; } public void setPrice(BigDecimal price) { this.price = price; } public Date getAddDate() { return addDate; } public void setAddDate(Date addDate) { this.addDate = addDate; } public int getState() { return state; } public void setState(int state) { this.state = state; } public String getPicture() { return picture; } public void setPicture(String picture) { this.picture = picture; } }
ProductDao.java
先添加依賴包sqljdbc4.jar
JDBCUitls工具類
package com.zhangguo.gomallpro.utils; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class JDBCUtils { public static String DRIVER = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; public static String URL = "jdbc:sqlserver://localhost:1433;databasename=GoMallPro"; public static String USER_NAME = "sa"; public static String PASSWORD = "sa"; static { try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { e.printStackTrace(); } } private JDBCUtils() { } /** * Get connection * * @return */ public static Connection getconnnection() { Connection con = null; try { con = DriverManager.getConnection(URL, USER_NAME, PASSWORD); } catch (SQLException e) { e.printStackTrace(); } return con; } /** * Close connection * * @param rs * @param st * @param con */ public static void close(ResultSet rs, Statement st, Connection con) { try { try { if (rs != null) { rs.close(); } } finally { try { if (st != null) { st.close(); } } finally { if (con != null) con.close(); } } } catch (SQLException e) { e.printStackTrace(); } } /** * Close connection * * @param rs */ public static void close(ResultSet rs) { Statement st = null; Connection con = null; try { try { if (rs != null) { st = rs.getStatement(); rs.close(); } } finally { try { if (st != null) { con = st.getConnection(); st.close(); } } finally { if (con != null) { con.close(); } } } } catch (SQLException e) { e.printStackTrace(); } } /** * Close connection * * @param st * @param con */ public static void close(Statement st, Connection con) { try { try { if (st != null) { st.close(); } } finally { if (con != null) con.close(); } } catch (SQLException e) { e.printStackTrace(); } } /** * insert/update/delete * * @param sql * @param args * @return */ public static int update(String sql, Object... args) { int result = 0; Connection con = getconnnection(); PreparedStatement ps = null; try { ps = con.prepareStatement(sql); if (args != null) { for (int i = 0; i < args.length; i++) { ps.setObject((i + 1), args[i]); } } result = ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { close(ps, con); } return result; } /** * query, because need to manually close the resource, so not recommended * for use it * * @param sql * @param args * @return ResultSet */ @Deprecated public static ResultSet query(String sql, Object... args) { ResultSet result = null; Connection con = getconnnection(); PreparedStatement ps = null; try { ps = con.prepareStatement(sql); if (args != null) { for (int i = 0; i < args.length; i++) { ps.setObject((i + 1), args[i]); } } result = ps.executeQuery(); } catch (SQLException e) { e.printStackTrace(); } return result; } /** * Query a single record * * @param sql * @param args * @return Map<String,Object> */ public static Map<String, Object> queryForMap(String sql, Object... args) { Map<String, Object> result = new HashMap<String, Object>(); List<Map<String, Object>> list = queryForList(sql, args); if (list.size() > 0) { result = list.get(0); } return result; } /** * Query a single record * * @param sql * @param args * @return <T> */ public static <T> T queryForObject(String sql, Class<T> clz, Object... args) { T result = null; List<T> list = queryForList(sql, clz, args); if (list.size() > 0) { result = list.get(0); } return result; } /** * Query a single record * * @param sql * @param args * @return List<Map<String,Object>> */ public static List<Map<String, Object>> queryForList(String sql, Object... args) { List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(); Connection con = null; ResultSet rs = null; PreparedStatement ps = null; try { con = getconnnection(); ps = con.prepareStatement(sql); if (args != null) { for (int i = 0; i < args.length; i++) { ps.setObject((i + 1), args[i]); } } rs = ps.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); while (rs.next()) { Map<String, Object> map = new HashMap<String, Object>(); for (int i = 1; i <= columnCount; i++) { map.put(rsmd.getColumnLabel(i), rs.getObject(i)); } result.add(map); } } catch (SQLException e) { e.printStackTrace(); } finally { close(rs, ps, con); } return result; } /** * Query a single record * * @param sql * @param args * @return List<T> */ public static <T> List<T> queryForList(String sql, Class<T> clz, Object... args) { List<T> result = new ArrayList<T>(); Connection con = null; PreparedStatement ps = null; ResultSet rs = null; try { con = getconnnection(); ps = con.prepareStatement(sql); if (args != null) { for (int i = 0; i < args.length; i++) { ps.setObject((i + 1), args[i]); } } rs = ps.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); while (rs.next()) { T obj = clz.newInstance(); for (int i = 1; i <= columnCount; i++) { String columnName = rsmd.getColumnName(i); String methodName = "set" + columnName.substring(0, 1).toUpperCase() + columnName.substring(1, columnName.length()); Method method[] = clz.getMethods(); for (Method meth : method) { if (methodName.equals(meth.getName())) { meth.invoke(obj, rs.getObject(i)); } } } result.add(obj); } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } finally { close(rs, ps, con); } return result; } }
ProductDao.java
package com.zhangguo.gomallpro.dao; import java.util.List; import com.zhangguo.gomallpro.model.Product; import com.zhangguo.gomallpro.utils.JDBCUtils; public class ProductDao { public List<Product> getPager(int page, int limit) { // 開始索引 int start = (page - 1) * limit + 1; // 結束索引 int end = page * limit; String sql = "select * from(SELECT [id] ,[name],[price] ,[addDate],[state],[picture],ROW_NUMBER() over(order by id desc) row FROM [Product]) t where t.row>=? and t.row<=?"; //執行查詢返回List<Product> return JDBCUtils.queryForList(sql, Product.class, start,end); } public static void main(String[] args) { ProductDao dao=new ProductDao(); for (Product p : dao.getPager(1, 10)) { System.out.println(p); } } }
測試結果:
decimal->BigDecimal
ProductDao.java
package com.zhangguo.gomallpro.dao; import java.util.List; import java.util.Map; import com.zhangguo.gomallpro.model.Product; import com.zhangguo.gomallpro.utils.JDBCUtils; public class ProductDao { /**產品分頁列表*/ public List<Product> getPager(int page, int limit) { // 開始索引 int start = (page - 1) * limit + 1; // 結束索引 int end = page * limit; String sql = "select * from(SELECT [id] ,[name],[price] ,[addDate],[state],[picture],ROW_NUMBER() over(order by id desc) row FROM [Product]) t where t.row>=? and t.row<=?"; //執行查詢返回List<Product> return JDBCUtils.queryForList(sql, Product.class, start,end); } /**得到總記錄數*/ public int getCount() { String sql="select COUNT(*) count from Product"; Map<String,Object> map=JDBCUtils.queryForMap(sql); return (int)map.get("count"); } //JUnit public static void main(String[] args) { ProductDao dao=new ProductDao(); System.out.println(dao.getCount()); for (Product p : dao.getPager(2, 10)) { System.out.println(p); } } }
測試:
分頁工具類R.java
package com.zhangguo.gomallpro.utils; public class R { /**響應編碼*/ private int code; /**響應消息*/ private String msg; /**數據總量*/ private int count; /**數據*/ private Object data; public String toJson(){ return JsonUtils.toJson(this); } public R() { } public static R ok(){ return ok(0,null); } public static R ok(int count, Object data){ return new R(0, "操做成功!", count, data); } public static R ok(String msg){ return new R(0,msg, 0,null); } public static R error(int count, Object data){ return new R(1, "操做失敗!", count, data); } public static R error(){ return error(0,null); } public static R error(String msg){ return new R(1, msg,0,null); } public R(int code, String msg, int count, Object data) { super(); this.code = code; this.msg = msg; this.count = count; this.data = data; } @Override public String toString() { return "R [code=" + code + ", msg=" + msg + ", count=" + count + ", data=" + data + "]"; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } }
JsonUtil工具類
package com.zhangguo.gomallpro.utils; import java.text.SimpleDateFormat; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; public class JsonUtils { /** * 序列化成json * */ public static String toJson(Object obj) { // 對象映射器 ObjectMapper mapper = new ObjectMapper(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd HH:mm:ss"); mapper.setDateFormat(sdf); String result = null; // 序列化user對象爲json字符串 try { result = mapper.writeValueAsString(obj); } catch (JsonProcessingException e) { e.printStackTrace(); } return result; } /** * 反序列化成對象 * */ public static <T> T toObject(String json,Class<T> valueType) { //對象映射器 ObjectMapper mapper=new ObjectMapper(); T result=null; try { result=mapper.readValue(json,valueType); }catch (Exception e) { e.printStackTrace(); } return result; } }
產品控制器,ProductController.java
package com.zhangguo.gomallpro.action; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.zhangguo.gomallpro.dao.ProductDao; import com.zhangguo.gomallpro.utils.R; /** * 產品控制器 */ @WebServlet("/ProductController") public class ProductController extends HttpServlet { private static final long serialVersionUID = 1L; PrintWriter out; ProductDao dao=new ProductDao(); protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //設置編碼 response.setCharacterEncoding("utf-8"); request.setCharacterEncoding("utf-8"); response.setContentType("application/json;charset=utf-8"); out=response.getWriter(); String action=request.getParameter("action"); if(action.equals("getPager")){ int page=Integer.parseInt(request.getParameter("page")); int limit=Integer.parseInt(request.getParameter("limit")); out.print(R.ok(dao.getCount(), dao.getPager(page, limit)).toJson()); }else{ out.print(R.error("不存在的動做")); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
測試服務
product.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>商品管理</title> <link rel="stylesheet" href="./plugins/layui/css/layui.css" media="all"> </head> <body> <div style="padding: 10px 0 0 10px;"> <button class="layui-btn layui-btn-sm layui-btn-normal" id="btnAdd" data-type="auto">添加</button> </div> <table id="productList" lay-filter="test"></table> <script src="./plugins/layui/layui.js"></script> <script> layui.use('table', function() { var table = layui.table; //第一個實例 table.render({ elem: '#productList' ,height:450 ,url: 'ProductController?action=getPager' //數據接口 ,page: true //開啓分頁 ,cols: [[ //表頭 {field: 'id', title: '編號', width:130, sort: true, fixed: 'left'} ,{field: 'name', title: '商品名稱', width:200} ,{field: 'price', title: '價格', width:100, sort: true} ,{field: 'picture', title: '圖片', width:130} ,{field: 'addDate', title: '上架時間', width: 160, sort: true} ,{field: 'state', title: '狀態', width: 80} ]] }); }); layui.use('jquery',function(){ var $=layui.jquery; $("#btnAdd").click(function() { //經過這種方式彈出的層,每當它被選擇,就會置頂。 layer.open({ type: 1, shade: [0.4, '#393D49'], area: ['600px', '400px'], maxmin: true, content: $("#form1"), zIndex: layer.zIndex, //重點1 success: function(layero) { layer.setTop(layero); //重點2 }, btn: ['按鈕一', '按鈕二', '按鈕三'], yes: function(index, layero) { //按鈕【按鈕一】的回調 }, btn2: function(index, layero) { //按鈕【按鈕二】的回調 //return false 開啓該代碼可禁止點擊該按鈕關閉 }, btn3: function(index, layero) { //按鈕【按鈕三】的回調 //return false 開啓該代碼可禁止點擊該按鈕關閉 }, cancel: function() { //右上角關閉回調 //return false 開啓該代碼可禁止點擊該按鈕關閉 } }); }); }); </script> </body> <fieldset id="form1" hidden="hidden"> <legend>用戶信息</legend> <p> <label for="name">姓名:</label> <input type="text" name="name" id="name" placeholder="請輸入姓名" /> <span id="nameMsg" class="red"></span> </p> <p> <label for="city">城市:</label> <input type="text" name="city" id="city" placeholder="請輸入城市" /> <span id="cityMsg" class="red"></span> </p> <p> <button type="button" id="btnSave" onclick="layer.closeAll()">保存</button> <button type="button" id="btnUpdate">更新</button> </p> </fieldset> </html>
運行結果
html
<div class="layui-upload"> <button type="button" class="layui-btn" id="test1">上傳圖片</button> <div class="layui-upload-list"> <img class="layui-upload-img" id="demo1"> <p id="demoText"></p> </div> </div>
js
layui.use('upload', function(){ var $ = layui.jquery ,upload = layui.upload; //普通圖片上傳 var uploadInst = upload.render({ elem: '#test1' ,url: 'UploadFile' ,before: function(obj){ //預讀本地文件示例,不支持ie8 obj.preview(function(index, file, result){ $('#demo1').attr('src', result); //圖片連接(base64) }); } ,done: function(res){ //若是上傳失敗 if(res.code > 0){ return layer.msg('上傳失敗'); } //上傳成功 layer.msg(res.msg); } ,error: function(){ //演示失敗狀態,並實現重傳 var demoText = $('#demoText'); demoText.html('<span style="color: #FF5722;">上傳失敗</span> <a class="layui-btn layui-btn-mini demo-reload">重試</a>'); demoText.find('.demo-reload').on('click', function(){ uploadInst.upload(); }); } }); });
添加jar包的依賴
定義上傳文件的Servlet
package com.zhangguo.gomallpro.action; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import com.zhangguo.gomallpro.utils.R; @SuppressWarnings("serial") @WebServlet("/UploadFile") public class UploadFile extends HttpServlet { @SuppressWarnings("unchecked") public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 設置編碼 response.setCharacterEncoding("utf-8"); // 物理路徑 String savePath = this.getServletConfig().getServletContext().getRealPath(""); savePath = savePath + "images\\"; File f1 = new File(savePath); if (!f1.exists()) { f1.mkdirs(); } DiskFileItemFactory fac = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(fac); upload.setHeaderEncoding("utf-8"); List<FileItem> fileList = null; try { fileList = upload.parseRequest(request); } catch (FileUploadException ex) { return; } Iterator<FileItem> it = fileList.iterator(); String name = ""; String extName = ""; while (it.hasNext()) { FileItem item = it.next(); if (!item.isFormField()) { name = item.getName(); long size = item.getSize(); String type = item.getContentType(); System.out.println(size + " " + type); if (name == null || name.trim().equals("")) { continue; } // 擴展名格式: if (name.lastIndexOf(".") >= 0) { extName = name.substring(name.lastIndexOf(".")); } File file = null; do { // 生成文件名: name = UUID.randomUUID().toString(); file = new File(savePath + name + extName); } while (file.exists()); File saveFile = new File(savePath + name + extName); try { item.write(saveFile); } catch (Exception exp) { response.getWriter().write(exp.getMessage()); exp.printStackTrace(); } } } R r = new R(); r.setCode(0); r.setMsg("上傳成功"); Map<String, String> data = new HashMap<String, String>(); data.put("src", "images/" + name + extName); data.put("name",name + extName); r.setData(data); response.getWriter().print(r.toJson()); } }
uploadify
KindEditor是一套開源的HTML可視化編輯器,主要用於讓用戶在網站上得到所見即所得編輯效果,兼容IE、Firefox、Chrome、Safari、Opera等主流瀏覽器。KindEditor使用JavaScript編寫,能夠無縫的於Java、.NET、PHP、ASP等程序接合。 KindEditor很是適合在CMS、商城、論壇、博客、Wiki、電子郵件等互聯網應用上使用
1. 體積小,加載速度快,但功能十分豐富。2. 內置自定義range,完美地支持span標記。
3. 基於插件的方式設計,全部功能都是插件,增長自定義和擴展功能很是簡單。
4. 修改編輯器風格很容易,只需修改一個CSS文件。
5. 支持大部分主流瀏覽器,好比IE、Firefox、Safari、Chrome、Opera。
Github: https://github.com/kindsoft/kindeditor
Oschina: http://git.oschina.net/luolonghao/kindeditor
下載地址:https://github.com/kindsoft/kindeditor/releases/download/v4.1.11/kindeditor-4.1.11-zh-CN.zip
1. 下載編輯器
下載 KindEditor 最新版本,下載以後打開 examples/index.html 就能夠看到演示。
下載頁面: http://www.kindsoft.net/down.php
2. 部署編輯器
解壓 kindeditor-x.x.x.zip 文件,將全部文件上傳到您的網站程序目錄裏,例如:http://您的域名/editor/
Note:
您能夠根據需求刪除如下目錄後上傳到服務器。
asp - ASP程序
asp.net - ASP.NET程序
php - PHP程序
jsp - JSP程序
examples - 演示文件
3. 修改HTML頁面
1.在須要顯示編輯器的位置添加textarea輸入框。
<textarea id="editor_id" name="content" style="width:700px;height:300px;">
<strong>HTML內容</strong>
</textarea>
Note:
id在當前頁面必須是惟一的值。
在textarea裏設置HTML內容便可實現編輯,在這裏須要注意的是,若是從服務器端程序(ASP、PHP、ASP.NET等)直接顯示內容,則必須轉換HTML特殊字符(>,<,&,」)。具體請參考各語言目錄下面的demo.xxx程序,目前支持ASP、ASP.NET、PHP、JSP。
在有些瀏覽器上不設寬度和高度可能顯示有問題,因此最好設一下寬度和高度。寬度和高度可用inline樣式設置,也可用 編輯器初始化參數 設置。
2.在該HTML頁面添加如下腳本。
<script charset="utf-8" src="/editor/kindeditor.js"></script>
<script charset="utf-8" src="/editor/lang/zh_CN.js"></script>
<script>
var editor;
KindEditor.ready(function(K) {
editor = K.create('#editor_id');
});
</script>
Note:
第一個參數可用其它CSS選擇器,匹配多個textarea時只在第一個元素上加載編輯器。
經過K.create函數的第二個參數,能夠對編輯器進行配置,具體參數請參考 編輯器初始化參數 。
var options = {
cssPath : '/css/index.css',
filterMode : true
};
var editor = K.create('textarea[name="content"]', options);
4. 獲取HTML數據
// 取得HTML內容
html = editor.html();
// 同步數據後能夠直接取得textarea的value
editor.sync();
html = document.getElementById('editor_id').value; // 原生API
html = K('#editor_id').val(); // KindEditor Node API
html = $('#editor_id').val(); // jQuery
// 設置HTML內容
editor.html('HTML內容');
Note:
KindEditor的可視化操做在新建立的iframe上執行,代碼模式下的textarea框也是新建立的,因此最後提交前須要執行 sync() 將HTML數據設置到原來的textarea。
KindEditor在默認狀況下自動尋找textarea所屬的form元素,找到form後onsubmit事件裏添加sync函數,因此用form方式提交數據,不須要手動執行sync()函數。
將依賴的jar文件放置到項目的lib目錄中,3個jar文件已在kindeditor中存在
找到用於處理上傳的jsp程序,根據須要修改
upload_json.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="java.util.*,java.io.*" %> <%@ page import="java.text.SimpleDateFormat" %> <%@ page import="org.apache.commons.fileupload.*" %> <%@ page import="org.apache.commons.fileupload.disk.*" %> <%@ page import="org.apache.commons.fileupload.servlet.*" %> <%@ page import="org.json.simple.*" %> <% /** * KindEditor JSP * * 本JSP程序是演示程序,建議不要直接在實際項目中使用。 * 若是您肯定直接使用本程序,使用以前請仔細確認相關安全設置。 * */ //文件保存目錄路徑 String savePath = pageContext.getServletContext().getRealPath("/") + "attached/"; //文件保存目錄URL String saveUrl = request.getContextPath() + "/attached/"; //定義容許上傳的文件擴展名 HashMap<String, String> extMap = new HashMap<String, String>(); extMap.put("image", "gif,jpg,jpeg,png,bmp"); extMap.put("flash", "swf,flv"); extMap.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb"); extMap.put("file", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2"); //最大文件大小 long maxSize = 1000000; response.setContentType("text/html; charset=UTF-8"); if(!ServletFileUpload.isMultipartContent(request)){ out.println(getError("請選擇文件。")); return; } //檢查目錄 File uploadDir = new File(savePath); if(!uploadDir.isDirectory()){ out.println(getError("上傳目錄不存在。")); return; } //檢查目錄寫權限 if(!uploadDir.canWrite()){ out.println(getError("上傳目錄沒有寫權限。")); return; } String dirName = request.getParameter("dir"); if (dirName == null) { dirName = "image"; } if(!extMap.containsKey(dirName)){ out.println(getError("目錄名不正確。")); return; } //建立文件夾 savePath += dirName + "/"; saveUrl += dirName + "/"; File saveDirFile = new File(savePath); if (!saveDirFile.exists()) { saveDirFile.mkdirs(); } SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); String ymd = sdf.format(new Date()); savePath += ymd + "/"; saveUrl += ymd + "/"; File dirFile = new File(savePath); if (!dirFile.exists()) { dirFile.mkdirs(); } FileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); upload.setHeaderEncoding("UTF-8"); List items = upload.parseRequest(request); Iterator itr = items.iterator(); while (itr.hasNext()) { FileItem item = (FileItem) itr.next(); String fileName = item.getName(); long fileSize = item.getSize(); if (!item.isFormField()) { //檢查文件大小 if(item.getSize() > maxSize){ out.println(getError("上傳文件大小超過限制。")); return; } //檢查擴展名 String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase(); if(!Arrays.<String>asList(extMap.get(dirName).split(",")).contains(fileExt)){ out.println(getError("上傳文件擴展名是不容許的擴展名。\n只容許" + extMap.get(dirName) + "格式。")); return; } SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); String newFileName = df.format(new Date()) + "_" + new Random().nextInt(1000) + "." + fileExt; try{ File uploadedFile = new File(savePath, newFileName); item.write(uploadedFile); }catch(Exception e){ out.println(getError("上傳文件失敗。")); return; } JSONObject obj = new JSONObject(); obj.put("error", 0); obj.put("url", saveUrl + newFileName); out.println(obj.toJSONString()); } } %> <%! private String getError(String message) { JSONObject obj = new JSONObject(); obj.put("error", 1); obj.put("message", message); return obj.toJSONString(); } %>
文件管理file_manager_json.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="java.util.*,java.io.*" %> <%@ page import="java.text.SimpleDateFormat" %> <%@ page import="org.json.simple.*" %> <% /** * KindEditor JSP * * 本JSP程序是演示程序,建議不要直接在實際項目中使用。 * 若是您肯定直接使用本程序,使用以前請仔細確認相關安全設置。 * */ //根目錄路徑,能夠指定絕對路徑,好比 /var/www/attached/ String rootPath = pageContext.getServletContext().getRealPath("/") + "attached/"; //根目錄URL,能夠指定絕對路徑,好比 http://www.yoursite.com/attached/ String rootUrl = request.getContextPath() + "/attached/"; //圖片擴展名 String[] fileTypes = new String[]{"gif", "jpg", "jpeg", "png", "bmp"}; String dirName = request.getParameter("dir"); if (dirName != null) { if(!Arrays.<String>asList(new String[]{"image", "flash", "media", "file"}).contains(dirName)){ out.println("Invalid Directory name."); return; } rootPath += dirName + "/"; rootUrl += dirName + "/"; File saveDirFile = new File(rootPath); if (!saveDirFile.exists()) { saveDirFile.mkdirs(); } } //根據path參數,設置各路徑和URL String path = request.getParameter("path") != null ? request.getParameter("path") : ""; String currentPath = rootPath + path; String currentUrl = rootUrl + path; String currentDirPath = path; String moveupDirPath = ""; if (!"".equals(path)) { String str = currentDirPath.substring(0, currentDirPath.length() - 1); moveupDirPath = str.lastIndexOf("/") >= 0 ? str.substring(0, str.lastIndexOf("/") + 1) : ""; } //排序形式,name or size or type String order = request.getParameter("order") != null ? request.getParameter("order").toLowerCase() : "name"; //不容許使用..移動到上一級目錄 if (path.indexOf("..") >= 0) { out.println("Access is not allowed."); return; } //最後一個字符不是/ if (!"".equals(path) && !path.endsWith("/")) { out.println("Parameter is not valid."); return; } //目錄不存在或不是目錄 File currentPathFile = new File(currentPath); if(!currentPathFile.isDirectory()){ out.println("Directory does not exist."); return; } //遍歷目錄取的文件信息 List<Hashtable> fileList = new ArrayList<Hashtable>(); if(currentPathFile.listFiles() != null) { for (File file : currentPathFile.listFiles()) { Hashtable<String, Object> hash = new Hashtable<String, Object>(); String fileName = file.getName(); if(file.isDirectory()) { hash.put("is_dir", true); hash.put("has_file", (file.listFiles() != null)); hash.put("filesize", 0L); hash.put("is_photo", false); hash.put("filetype", ""); } else if(file.isFile()){ String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase(); hash.put("is_dir", false); hash.put("has_file", false); hash.put("filesize", file.length()); hash.put("is_photo", Arrays.<String>asList(fileTypes).contains(fileExt)); hash.put("filetype", fileExt); } hash.put("filename", fileName); hash.put("datetime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(file.lastModified())); fileList.add(hash); } } if ("size".equals(order)) { Collections.sort(fileList, new SizeComparator()); } else if ("type".equals(order)) { Collections.sort(fileList, new TypeComparator()); } else { Collections.sort(fileList, new NameComparator()); } JSONObject result = new JSONObject(); result.put("moveup_dir_path", moveupDirPath); result.put("current_dir_path", currentDirPath); result.put("current_url", currentUrl); result.put("total_count", fileList.size()); result.put("file_list", fileList); response.setContentType("application/json; charset=UTF-8"); out.println(result.toJSONString()); %> <%! public class NameComparator implements Comparator { public int compare(Object a, Object b) { Hashtable hashA = (Hashtable)a; Hashtable hashB = (Hashtable)b; if (((Boolean)hashA.get("is_dir")) && !((Boolean)hashB.get("is_dir"))) { return -1; } else if (!((Boolean)hashA.get("is_dir")) && ((Boolean)hashB.get("is_dir"))) { return 1; } else { return ((String)hashA.get("filename")).compareTo((String)hashB.get("filename")); } } } public class SizeComparator implements Comparator { public int compare(Object a, Object b) { Hashtable hashA = (Hashtable)a; Hashtable hashB = (Hashtable)b; if (((Boolean)hashA.get("is_dir")) && !((Boolean)hashB.get("is_dir"))) { return -1; } else if (!((Boolean)hashA.get("is_dir")) && ((Boolean)hashB.get("is_dir"))) { return 1; } else { if (((Long)hashA.get("filesize")) > ((Long)hashB.get("filesize"))) { return 1; } else if (((Long)hashA.get("filesize")) < ((Long)hashB.get("filesize"))) { return -1; } else { return 0; } } } } public class TypeComparator implements Comparator { public int compare(Object a, Object b) { Hashtable hashA = (Hashtable)a; Hashtable hashB = (Hashtable)b; if (((Boolean)hashA.get("is_dir")) && !((Boolean)hashB.get("is_dir"))) { return -1; } else if (!((Boolean)hashA.get("is_dir")) && ((Boolean)hashB.get("is_dir"))) { return 1; } else { return ((String)hashA.get("filetype")).compareTo((String)hashB.get("filetype")); } } } %>
KindEditor默認提供ASP、ASP.NET、PHP、JSP上傳程序,這些程序是演示程序,建議不要直接在實際項目中使用。若是您肯定直接使用本程序,使用以前請仔細確認相關安全設置。
選擇程序語言?
// ASP
KindEditor.ready(function(K) {
K.create('#textarea_id', {
uploadJson : '../asp/upload_json.asp',
fileManagerJson : '../asp/file_manager_json.asp',
allowFileManager : true
});
});
// ASP.NET
KindEditor.ready(function(K) {
K.create('#textarea_id', {
uploadJson : '../asp.net/upload_json.ashx',
fileManagerJson : '../asp.net/file_manager_json.ashx',
allowFileManager : true
});
});
// JSP
KindEditor.ready(function(K) {
K.create('#textarea_id', {
uploadJson : '../jsp/upload_json.jsp',
fileManagerJson : '../jsp/file_manager_json.jsp',
allowFileManager : true
});
});
Note:
具體使用方法請參見各語言(asp、asp.net、php、jsp)目錄下的demo.xxx文件。
完整示例:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>kind editor Demo</title> </head> <body> <h2>富文本編輯器</h2> <div> 商品詳細: <textarea cols="80" rows="10" id="details" style="width:700px"></textarea> <button type="button" id="btnSubmit">提交</button> </div> <div id="divContent"></div> <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script> <script type="text/javascript" src="js/kindeditor4111/kindeditor-all-min.js"></script> <script type="text/javascript" src="js/kindeditor4111/lang/zh-CN.js"></script> <script> var editor; KindEditor.ready(function(K) { editor = K.create('#details',{ uploadJson : 'js/kindeditor4111/jsp/upload_json.jsp', //上傳程序 fileManagerJson : 'js/kindeditor4111/jsp/file_manager_json.jsp', //文件管理 allowFileManager : true //是否容許上傳 }); //建立一個富文本編輯器 }); $("#btnSubmit").click(function(){ $("#divContent").html(editor.html()); }); </script> </body> </html>
運行結果:
K.options = { designMode : true, fullscreenMode : false, filterMode : true, wellFormatMode : true, shadowMode : true, loadStyleMode : true, basePath : K.basePath, themesPath : K.basePath + 'themes/', langPath : K.basePath + 'lang/', pluginsPath : K.basePath + 'plugins/', themeType : 'default', langType : 'zh-CN', urlType : '', newlineTag : 'p', resizeType : 2, syncType : 'form', pasteType : 2, dialogAlignType : 'page', useContextmenu : true, fullscreenShortcut : false, bodyClass : 'ke-content', indentChar : '\t', cssPath : '', cssData : '', minWidth : 650, minHeight : 100, minChangeSize : 50, zIndex : 811213, items : [ 'source', '|', 'undo', 'redo', '|', 'preview', 'print', 'template', 'code', 'cut', 'copy', 'paste', 'plainpaste', 'wordpaste', '|', 'justifyleft', 'justifycenter', 'justifyright', 'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript', 'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/', 'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold', 'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|', 'image', 'multiimage', 'flash', 'media', 'insertfile', 'table', 'hr', 'emoticons', 'baidumap', 'pagebreak', 'anchor', 'link', 'unlink', '|', 'about' ], noDisableItems : ['source', 'fullscreen'], colorTable : [ ['#E53333', '#E56600', '#FF9900', '#64451D', '#DFC5A4', '#FFE500'], ['#009900', '#006600', '#99BB00', '#B8D100', '#60D978', '#00D5FF'], ['#337FE5', '#003399', '#4C33E5', '#9933E5', '#CC33E5', '#EE33EE'], ['#FFFFFF', '#CCCCCC', '#999999', '#666666', '#333333', '#000000'] ], fontSizeTable : ['9px', '10px', '12px', '14px', '16px', '18px', '24px', '32px'], htmlTags : { font : ['id', 'class', 'color', 'size', 'face', '.background-color'], span : [ 'id', 'class', '.color', '.background-color', '.font-size', '.font-family', '.background', '.font-weight', '.font-style', '.text-decoration', '.vertical-align', '.line-height' ], div : [ 'id', 'class', 'align', '.border', '.margin', '.padding', '.text-align', '.color', '.background-color', '.font-size', '.font-family', '.font-weight', '.background', '.font-style', '.text-decoration', '.vertical-align', '.margin-left' ], table: [ 'id', 'class', 'border', 'cellspacing', 'cellpadding', 'width', 'height', 'align', 'bordercolor', '.padding', '.margin', '.border', 'bgcolor', '.text-align', '.color', '.background-color', '.font-size', '.font-family', '.font-weight', '.font-style', '.text-decoration', '.background', '.width', '.height', '.border-collapse' ], 'td,th': [ 'id', 'class', 'align', 'valign', 'width', 'height', 'colspan', 'rowspan', 'bgcolor', '.text-align', '.color', '.background-color', '.font-size', '.font-family', '.font-weight', '.font-style', '.text-decoration', '.vertical-align', '.background', '.border' ], a : ['id', 'class', 'href', 'target', 'name'], embed : ['id', 'class', 'src', 'width', 'height', 'type', 'loop', 'autostart', 'quality', '.width', '.height', 'align', 'allowscriptaccess', 'wmode'], img : ['id', 'class', 'src', 'width', 'height', 'border', 'alt', 'title', 'align', '.width', '.height', '.border'], 'p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6' : [ 'id', 'class', 'align', '.text-align', '.color', '.background-color', '.font-size', '.font-family', '.background', '.font-weight', '.font-style', '.text-decoration', '.vertical-align', '.text-indent', '.margin-left' ], pre : ['id', 'class'], hr : ['id', 'class', '.page-break-after'], 'br,tbody,tr,strong,b,sub,sup,em,i,u,strike,s,del' : ['id', 'class'], iframe : ['id', 'class', 'src', 'frameborder', 'width', 'height', '.width', '.height'] }, layout : '<div class="container"><div class="toolbar"></div><div class="edit"></div><div class="statusbar"></div></div>' };
kindeditor API ,kindeditor使用手冊,kindeditor函數,kindeditor使用,超級大收集 變量 1. KE 惟一的全局變量,也是程序的命名空間。 數據類型:Object 2. KE.version 編輯器的版本信息。 數據類型:String 3. KE.lang 編輯器的中文信息。 數據類型:Object 4. KE.scriptPath kindeditor.js的路徑。 數據類型:String 5. KE.htmlPath 編輯器的HTML頁面路徑。 數據類型:String 注:3.4版本已廢棄。 6. KE.browser 瀏覽器類型和版本,分別爲KE.browser.VERSION、KE.browser.IE、KE.browser.WEBKIT、 KE.browser.GECKO、KE.browser.OPERA。 數據類型:Object 注:3.4之前版本直接返回字符串,分別爲"IE"、"WEBKIT"、"GECKO"、"OPERA"。 7. KE.setting 編輯器的初始化屬性和其它配置。 數據類型:Object 8. KE.g 一個編輯器的變量集,包含全部編輯器屬性,此外還包含如下變量,常常用KE.g[id]來表示。 例如:KE.g["content_1"].iframeDoc表示id爲"content_1"的編輯器的iframe document對象。 數據類型:Object 主要變量: container: 編輯器的外部element對象。 iframe: 編輯區域的iframe對象。 iframeWin: 編輯區域的iframe window對象。 iframeDoc: 編輯區域的iframe document對象。 keSel: 當前選中信息的KE.selection對象。 keRange: 當前選中信息的KE.range對象。 sel: 當前選中信息的瀏覽器原生selection對象。 range: 當前選中信息的瀏覽器原生range對象。 layoutDiv: 編輯器彈出層的div對象。3.4版本已廢棄。 hideDiv: 編輯器彈出層的parent div對象。 dialog: 彈出窗口的iframe對象。3.4版本已廢棄。 yesButton: 彈出窗口的肯定按鈕input對象。 noButton: 彈出窗口的取消按鈕input對象。 previewButton: 彈出窗口的預覽按鈕input對象。 maskDiv: 彈出窗口時灰色遮罩層的div對象。 undoStack: undo/redo的undo記錄。 redoStack: undo/redo的redo記錄。 9. KE.plugin 定義編輯器的插件。 數據類型:Object 函數 1. KE.$(id, doc) 取得element對象,doc.getElementById的別名。 參數: id:String,element的id doc:Object,element所在document對象,是可選參數,默認值爲document。 返回值: Object,element對象 2. KE.$$(name, doc) 建立element對象,doc.createElement的別名。 參數: name:String,element的tag name doc:Object,element所在document對象,是可選參數,默認值爲document。 返回值: Object,element對象 3. KE.event.add(el, event, listener) 添加一個事件。 參數: el:Object,要添加事件的element對象 event:String,事件名稱,可設置"click","change","mousedown"等。 listener:Function,事件處理回調函數。 返回值:無 4. KE.event.remove(el, event, listener) 刪除已添加的一個事件。 參數: el:Object,要添加事件的element對象 event:String,事件名稱,可設置"click","change","mousedown"等。 listener:Function,事件處理回調函數。 返回值:無 5. KE.event.input(el, func) 添加一個編輯器輸入事件。 參數: el:Object,要添加事件的element對象 func:Function,編輯器輸入內容時調用這個函數。 返回值:無 6. KE.event.ctrl(el, key, func) 添加一個Ctrl+[]事件。 參數: el:Object,要添加事件的element對象 key:String,Ctrl組合鍵的字母,支持A到Z。 func:Function,按下Ctrl+[]時調用這個函數。 返回值:無 7. KE.event.ready(func) 添加一個document的DOMContentLoaded事件。 參數: func:Function,DOM加載完成後調用這個函數。 返回值:無 8. KE.each(obj, func) 遍歷一個object。 參數: obj:Object,要遍歷的object func:Function,循環時調用這個函數,參數爲object的key和value。 返回值:無 9. KE.eachNode(node, func) 遍歷一個node。 參數: node:Object,要遍歷的parent node func:Function,循環時調用這個函數,參數爲node。 返回值:無 10. KE.format.getHtml(html, htmlTags) 把HTML轉換成XHTML,當指定htmlTags參數時,按照htmlTags規則過濾HTML標籤。 參數: html:String,HTML文本 htmlTags:Object,過濾規則,可選參數。 返回值: String,XHTML文本 11. KE.util.getDocumentElement() 取得document element對象。 參數:無 返回值: Object,element對象 12. KE.util.getDocumentWidth() 取得當前頁面的寬度。 參數:無 返回值: Int,document寬度 13. KE.util.getDocumentHeight() 取得當前頁面的高度。 參數:無 返回值: Int,document高度 14. KE.util.loadStyle(path) 在當前頁面加載一個CSS文件。 參數: path:String,CSS文件的URL路徑 返回值:無 15. KE.util.inArray(str, arr) 判斷一個字符串是否在一個數組裏。 參數: str:String arr:Array 返回值: Boolean,返回true表示在數組裏,返回false表示不在數組裏。 16. KE.util.trim(str) 刪除字符串兩邊的空格字符。 參數: str:String 返回值:String 17. KE.util.getJsKey(key) 把HTML style裏的CSS名轉換成JavaScript屬性名。例如:KE.util.getJsKey("font-size")會返回"fontSize"。 參數: key:String 返回值:String 18. KE.util.escape(html) 轉換HTML裏的特殊字符。 參數: html:String,HTML文本 返回值:String 19. KE.util.getElementPos(el) 取得指定element的座標。 參數: el:Object,element對象 返回值:Object 20. KE.util.getCoords(ev) 取得鼠標座標。 參數: ev:Object,event對象 返回值:Object 21. KE.util.setOpacity(el, opacity) 設置element的透明度。 參數: el:Object,element對象 opacity:Int,透明度,可設置0到100的數字。 返回值:無 22. KE.util.getIframeDoc(iframe) 取得iframe document對象。 參數: iframe:Object,iframe對象 返回值:Object 23. KE.util.rgbToHex(str) 把RGB格式的顏色轉換成16進制的顏色。 參數: str:String,RGB顏色標記 返回值:String 24. KE.util.createRange(doc) 建立指定document的range。 參數: doc:Object,document對象 返回值:Object,range對象 25. KE.util.getFullHtml(id, tagLineMode) 取得編輯器iframe的初始化HTML文本。 參數: id:String,編輯器的ID tagLineMode:Boolean,true時顯示模塊標籤的輪廓。 返回值:String 26. KE.util.getData(id) 取得編輯器的HTML內容。 參數: id:String,編輯器的ID 返回值:String 27. KE.util.getSrcData(id) 取得編輯器的原生HTML內容,也就是innerHTML直接返回的HTML。 參數: id:String,編輯器的ID 返回值:String 28. KE.util.getPureData(id) 取得編輯器的純文本內容,不包含HTML標籤。3.4版本開始包含img和embed標籤。 參數: id:String,編輯器的ID 返回值:String 29. KE.util.setData(id) 把編輯器的內容設置到原TEXTAREA控件裏。 參數: id:String,編輯器的ID 返回值:無 30. KE.util.focus(id) 把焦點移到編輯器裏。 參數: id:String,編輯器的ID 返回值:無 31. KE.util.selection(id) 把當前選中信息設置到KE.g[id].sel,KE.g[id].range,KE.g[id].keSel,KE.g[id].keRange裏。 參數: id:String,編輯器的ID 返回值:無 32. KE.util.select(id) 從新選中range,僅在IE有效。 參數: id:String,編輯器的ID 返回值:無 33. KE.util.pToBr(id) 按下回車鍵時生成BR標籤,僅在IE有效。 參數: id:String,編輯器的ID 返回值:無 注:3.4版本已廢棄。 34. KE.util.execCommand(id, cmd, value) 執行瀏覽器自帶的命令,詳細請參考瀏覽器API裏的document.execCommand。 參數: id:String,編輯器的ID cmd:String,瀏覽器execCommand裏的cmd參數 value:String,瀏覽器execCommand裏的value參數 返回值:無 35. KE.util.insertHtml(id, html) 把HTML內容插入到編輯區域裏的光標處。 參數: id:String,編輯器的ID html:String,HTML內容 返回值:無 注:執行本函數以前必須先執行過 KE.util.selection(id),由於要先設置KE.g[id].sel和KE.g[id].range。 36. KE.create(id, mode) 建立編輯器。 參數: id:String,編輯器的ID mode:Int,可選參數,指定1時在body下面建立編輯器,0或未指定時在TEXTAREA前面建立編輯器。 返回值:無 37. KE.remove(id, mode) 移除編輯器。 參數: id:String,編輯器的ID mode:Int,可選參數,指定1時移除在body下面的編輯器,0或未指定時移除在TEXTAREA前面的編輯器。 返回值:無 38. KE.init(config) 設置編輯器的初始化參數。 參數: config:Object,編輯器屬性的哈希數組,具體請參考編輯器屬性 返回值:無 39. KE.show(config) 初始化並建立編輯器。執行本函數時先調用KE.init設置初始化參數,而後在DOM加載完成後執行KE.create。 參數: config:Object,編輯器屬性的哈希數組,具體請參考編輯器屬性 返回值:無 類 1. KE.selection(win, doc) KindEditor的selection類,取得或設置選中部分的range。 參數: win:Object,window對象 oc:Object,document對象 成員變量: sel:Object,瀏覽器原生selection對象 range:Object,當前selection的瀏覽器原生range對象 keRange:Object,當前selection的KindEditor range對象,請參考KE.range。 方法: addRange(keRange):設置當前selection。 focus():從新選中、僅在IE有效。 2. KE.range(doc) KindEditor的range類,爲各瀏覽器提供統一的range接口。 參數: doc:Object,document對象 成員變量: startNode:Object,開始節點 startPos:Int,開始節點的位置 endNode:Object,結束節點 endPos:Int,結束節點的位置 方法: getParentElement():返回包含range的parent element。 getNodeList():返回range裏的node list。 comparePoints(how, range):比較2個keRange的位置,how能夠設置"START_TO_START", "START_TO_END", "END_TO_START","END_TO_END"。 setStart(node, pos):設置range的開始節點和位置。 setEnd(node, pos):設置range的結束節點和位置。 selectNode(node):把node設置到range,開始節點和結束節點都是node。 extractContents():提取range的內容。 cloneContents():複製range的內容。 getText():取得range的純文本內容。 3. KE.cmd(id) KindEditor的命令類,相似execCommand。 參數: id:String,編輯器的ID 成員變量: doc:Object,編輯器的iframe document對象 keSel:Int,KindEditor selection對象 keRange:Object,當前selection的KindEditor range對象 方法: wrap(tagName, attributes):用指定標籤包當前選中文本,目前只支持inline tag。tagName爲標籤名,attributes爲該標籤屬性數組。 remove(tags):在當前選中文本中,清除指定的標籤和屬性。tags爲你要刪除的標籤和屬性。
http://kindeditor.net/demo.php
使用layui彈出層時會發現kindeditor獲取不了光標,這是由於多個層與iframe元素間疊放順序的問題引發的,解決辦法以下:
代碼:
success: function(layero) { layer.setTop(layero); //頂置 editor = KindEditor.create('#details',{ uploadJson : 'js/kindeditor4111/jsp/upload_json.jsp', //上傳程序 fileManagerJson : 'js/kindeditor4111/jsp/file_manager_json.jsp', //文件管理 allowFileManager : true , //是否容許上傳 /* layui zIndex:19891014 KindEditor zIndex:811213 */ zIndex:99999999 }); //建立一個富文本編輯器
富文本框,pageContext可能遇到上傳目錄不存在的問題
https://weui.io
http://www.jqweui.cn/
http://www.dcloud.io/mui.html
示例:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>個人生活</title> <meta name="viewport" content="initial-scale=1, maximum-scale=1" /> <link rel="shortcut icon" href="/favicon.ico" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-status-bar-style" content="black" /> <link rel="stylesheet" href="js/suimobile/css/sm.min.css" /> <link rel="stylesheet" href="js/suimobile/css/sm-extend.min.css" /> </head> <body> <div class="page-group"> <!-- 你的html代碼 --> <div class="page"> <header class="bar bar-nav"> <a class="button button-link button-nav pull-left" href="/demos/card"> <span class="icon icon-left"></span> 返回 </a> <h1 class="title">個人生活</h1> </header> <nav class="bar bar-tab"> <a class="tab-item external active" href="#"> <span class="icon icon-home"></span> <span class="tab-label">首頁</span> </a> <a class="tab-item external" href="#"> <span class="icon icon-me"></span> <span class="tab-label">我</span> </a> <a class="tab-item external" href="#"> <span class="icon icon-star"></span> <span class="tab-label">收藏</span> </a> <a class="tab-item external" href="#"> <span class="icon icon-settings"></span> <span class="tab-label">設置</span> </a> </nav> <div class="content"> <!-- 這裏是頁面內容區 --> <div class="page-index" id="list"> </div> </div> </div> </div> <script type='text/javascript' src='js/suimobile/js/zepto.js' charset='utf-8'></script> <script type='text/javascript' src='js/suimobile/js/sm.min.js' charset='utf-8'></script> <script type='text/javascript' src='js/suimobile/js/sm-extend.min.js' charset='utf-8'></script> <script> $(function(){ $.init(); $.get("ProductController?action=getPager&limit=10&page=1",{},function(data){ $.each(data.data,function(index,obj){ c="<div class='card'>"; c+="<div style='background:url(\"images/"+obj.picture+"\") #fff center center' valign='bottom' class='card-header color-white no-border'>"+obj.name+"</div>"; c+="<div class='card-content'>"; c+="<div class='card-content-inner'>"; c+="<p class='color-gray'>發佈日期 "+obj.addDate+"</p>"; c+="<p>此處是內容...</p>"; c+="</div>"; c+="</div>"; c+="<div class='card-footer'>"; c+="<a href='#' class='link'>贊</a>"; c+="<a href='#' class='link'>更多</a>"; c+="</div>"; c+="</div>"; $("#list").append(c); }); }); }); </script> </body> </html>
運行結果:
若是須要演示可以使用Total Control軟件
連接: https://pan.baidu.com/s/1iFyQJ8oNWnoVrQ64rq2c6w 密碼: 5a19
圖標:http://www.fontawesome.com.cn/
layui文檔:http://www.layui.com/doc
layui文檔:http://www.layui.com/demo/
上傳jar包:https://files.cnblogs.com/files/best/%E4%B8%8A%E4%BC%A0jar.zip
KindEditor下載:連接: https://pan.baidu.com/s/1IGBFVzMPjQ5FYCEKoYOc9w 密碼: tv9v
GoMallPro項目:連接: https://pan.baidu.com/s/1wN2DRJXGoTgPv4rSnCSWlw 密碼: 13tw (SUI)