EasyUI 官方网站:http://www.jeasyui.com/index.phpjavascript
EasyUI API:http://www.jeasyui.com/documentation/index.phpphp
最近使用JQuery的EasyUI进行对表格进行CRUD操做,看到官网上的示例演示特别简单,可是在实际操做中发现并无那么简单。如下就是在本身写的时候出现的一些问题。css
UI页面以下:html
这个示例有三个页面:java
<!DOCTYPE html> <html lang = "en"> <head> <meta charset = "UTF-8"> <title>Title</title> <link rel = "stylesheet" type = "text/css" href = "easyui/themes/default/easyui.css"> <link rel = "stylesheet" type = "text/css" href = "easyui/themes/icon.css"> <script type = "text/javascript" src = "js/jquery-2.1.4.min.js"></script> <script src = "easyui/jquery.easyui.min.js"></script> <script src = "easyui/easyui-lang-zh_CN.js"></script> <script src = "easyui/jquery.edatagrid.js"></script> <script src = js/datepicker/WdatePicker.js></script> </head> <style> #memo_id p { padding-left: 10px; } </style> <script> $(function () { $("#sys_mng_id div:first a").click(function () { if ($("#tabs_id").tabs("exists", $(this).text())) { $("#tabs_id").tabs("select", $(this).text()); } else { $("#tabs_id").tabs("add", { title: $(this).text(), selected: true, closable: true, content: $(this).text() }) } }); $("#tabs_id").tabs({ // tools: [{ // iconCls: "icon-add", // handler: function () { // alert("添加"); // } // }, { // iconCls: "icon-save", // handler: function () { // alert("正在保存"); // } // }], onBeforeClose: function (title) { return window.confirm("您肯定要关闭 " + title + " 选项卡吗?"); } }); }) </script> <body class = "easyui-layout"> <div data-options = "region:'north',split:false,border:false" style = "height:15%;text-align: center;"> <h1>初次学习JQuery组件--EasyUi</h1> </div> <div data-options = "region:'south',split:false,border:true" style = "height:5%;text-align: center">©Flying版权全部 </div> <div id = "memo_id" data-options = "region:'east',title:'备注',split:false,collapsible:true,border:false" style = "width:20%;"> <h1 style = "text-align: center">今天新闻</h1> <p>网站建设中...</p> <p>网站建设中...</p> <p>网站建设中...</p> <p>网站建设中...</p> <p>网站建设中...</p> <p>网站建设中...</p> </div> <div id = "sys_mng_id" class = "easyui-accordion" data-options = " region:'west',title:'系统菜单',split:false,collapsible:true,selected:-1,multiple:false,border:false" style = "width:20%;overflow: auto"> <div title = "部门管理" data-options = "iconCls:'icon-save',href: 'http://localhost:8080/SSMProjectMaven/tree.html'"></div> <div title = "人事管理" data-options = "iconCls:'icon-reload'">此处内容</div> <div title = "客户管理" data-options = "iconCls:'icon-remove'">此处内容</div> <div title = "权限管理" data-options = "iconCls:'icon-edit'">此处内容</div> <div title = "报表管理" data-options = "iconCls:'icon-print'">此处内容</div> <div title = "帮助" data-options = "iconCls:'icon-help'">此处内容</div> </div> <div id = "tabs_id" data-options = "region:'center',border:false" style = "padding:5px;background:#eee;"> </div> <script> $(function () { $("body").layout("panel", "center").panel({ href: "http://localhost:8080/SSMProjectMaven/student.html" }); }) </script> </body> </html>
在我是把student.html和tree.html页面嵌入到该主页面中的。node
我发现使用EasyUI的panel的href属性嵌入另外一个页面时,只会加载href指向页面的body中的内容,jquery
也就是说若是你在子页面中在body以外引入了javascript外部文件,可是在主页面中没有引入该文件,那么该子页面在主页面中将不能正常工做。在body以外设置的CSS属性亦是如此。因此在子页面中设置的CSS属性应该尽可能放在body标签内,或者使用内联样式。ajax
WdatePicker组件的使用参见该篇博客:http://my.oschina.net/u/2608182/blog/731627数据库
<!DOCTYPE html> <html lang = "en"> <head> <meta charset = "UTF-8"> <title>Title</title> <link rel = "stylesheet" type = "text/css" href = "easyui/themes/default/easyui.css"> <link rel = "stylesheet" type = "text/css" href = "easyui/themes/icon.css"> <script type = "text/javascript" src = "js/jquery-2.1.4.min.js"></script> <script src = "easyui/jquery.easyui.min.js"></script> <script src = "easyui/easyui-lang-zh_CN.js"></script> <script src = "easyui/jquery.edatagrid.js"></script> <script src = js/datepicker/WdatePicker.js></script> </head> <body> <style> #dlg div { margin-top: 10px; } #search_form input { border-radius: 5px; border: 1px solid #95B8E7; height: 20px; } </style> <table id = "dgg"></table> <div id = "dlg" style = "text-align: center"> <form id = "search_form"> <div> <label for = "name">姓名:</label> <input type = "text" id = "name" class = "easyui-textbox" data-options = "required:false"> </div> <div> <label for = "birthday">生日:</label> <!-- 这里感受EasyUI的datebox插件很差用故使用了WdatePicker插件 --> <input id = "birthday" class = "Wdate" onfocus = "WdatePicker({ skin:'whyGreen', isShowWeek:false, readOnly:true, highLineWeekDay:true, dateFmt:'yyyy-MM-dd'})"> </div> </form> </div> <script> $(function () { $("#dlg").dialog({ title: "搜索", closed: true, modal: true, width: 300, height: 150, buttons: [{ iconCls: "icon-search", text: "搜索", handler: function () { $("#dgg").edatagrid("load", { name: $("#name").val(), /* Tips: 这里须要注意,若是是使用EasyUI的datebox插件的话, $("#birthday").val()这句代码将取不出来值, 要取出值必须使用如下语句: $("#birthday").datebox("getValue"); 若是使用WDatePicker插件的话不存在这个问题 */ birthday: $("#birthday").val() }); $("#dlg").dialog("close"); } }, { iconCls: "icon-cancel", text: "取消", handler: function () { $("#dlg").dialog("close"); } }] }); $("#dgg").edatagrid({ title: '学生信息', /* Tips: * 这里若是要使用edatagrid插件自带的saveRow,distroyRow等相似方法的话, * idField属性必须指定,不然在使用这些方法的时候插件将不会自动发送主键 * (例如这里我设置的是Student类的属性sid做为数据库里的主键)参数到服务器, * 通过测试,貌似插件根本不会向服务器发送请求,除非这里指定了idField属性 * */ idField: 'sid', fit: true, method: "GET", url: "http://localhost:8080/SSMProjectMaven/student/ajax_page.do", columns: [[ /* * 该列将显示以多选框形式显示 * */ {field: 'sid', checkbox: true}, { field: 'name', title: 'name', sortable: false, align: "center", width: 50, editor: { type: 'validatebox', options: { required: true } } }, { field: 'birthday', title: 'birthday', align: "center", width: 50, editor: { type: 'datebox', options: { required: false, editable: false } } } ]], toolbar: [{ iconCls: 'icon-add', text: "添加", handler: function () { $('#dgg').edatagrid('addRow'); } }, '-', { iconCls: 'icon-save', text: "保存", handler: function () { $('#dgg').edatagrid('saveRow'); } }, '-', { iconCls: 'icon-undo', text: "撤销当前编辑行", handler: function () { $('#dgg').edatagrid('cancelRow'); } }, '-', { iconCls: 'icon-remove', text: "删除选中行", /* Tips: * 这里的删除记录我没有选择使用edatagrid插件自带的destroyRow方法, * 缘由是我发现若是我选择了多条记录同时删除的话,例如我选择了10条记录 * 选择删除,该插件就会向服务器发送10次请求,每一个请求都附带一个idField * 属性设置的sid,不能实现一次请求批量删除记录,大大增长了服务器的压力。 * 我这里实现的是一次请求向服务器发送全部用户选择的记录的sid,后台实现 * 记录批量删除。 * */ handler: function () { var rows = $('#dgg').edatagrid('getChecked'); if (rows.length == 0) { $.messager.alert("警告", "您没有选择任何行", 'warning'); return false; } $.messager.confirm("确认", "您肯定要删除已经选择的 " + rows.length + " 行吗?", function (flag) { if (flag) { var indexs = []; for (var i = 0; i < rows.length; i++) { indexs.push(rows[i].sid); } $.ajax({ url: "http://localhost:8080/SSMProjectMaven/student/deletes.do", type: "GET", /* * Tips: * 这里真的要注意了,费了我好长时间解决这个问题。 * 这里的data就是要向服务器发送的参数,这里因为 * idss的值是一个数组,若是data属性的设置以下: * data:{'idss':indexs} * JQuery在解析这个Json对象的时候向服务器最终发送的参数以下: * 解析以后的参数(带有中括号[]):idss[]:179,idss[]:195,idss[]:196 * 编码以后的参数(带有"%5B%5D"字符):idss%5B%5D=179&idss%5B%5D=195&idss%5B%5D=196 * 然而我服务器设置的用来接收此参数的变量名是idss啊, * 而且也不能把变量名设置成idss[]啊。 * 后来通过查看JQuery的API以及查找了网上相关资料,JQuery有以下两个方法 * $("form").serialize(),$.param(), * serialize方法用于把表单内容序列化为Json数据结构的数据, * 可是咱们想服务器发送参数是用相似于aaa=xxx&bbb=xxx的字符串, * 因此咱们就须要使用$.param()方法把Json对象解析成咱们须要的请求格式的字符串。 * 可是$.param()方法有两种用法, * 1. $.param({'idss': indexs}),这种方法在解析数组的时候将会产生"%5B%5D"的字符 * $.ajax()的data参数使用的就是这种方式。 * 2. $.param({'idss': indexs}, true),这种方法就不会产生"%5B%5D"字符这样的问题, * 解析出来的参数就是咱们须要的格式:idss=179&idss=195&idss=196 * 因为$.ajax()的data参数默认使用第一种方式解析Json对象,因此咱们就只有 * 手动调用JQuery的$.param()函数来解决"%5B%5D"字符问题 * */ data: $.param({'idss': indexs}, true), dataType: "json", success: function (data) { if (data.status == 1) { /* Tips: * 下面紧接着的一小段被我注释掉的代码也须要注意一下。 * 举个例子: * 假如rows数组里包含了5条行数据,那么rows的下标就是从0到4. * 下标依次对应于表格里的第1至5条行数据,当我调用了如下这个方法 * $('#dgg').edatagrid("deleteRow", 0) * 我移除掉了表格里的第一条行数据,那么同时rows数组的rows[0]对象 * 也会被移除掉,这时rows数组的长度也会减1,下标变成从0到3, * 在这种状况下若使用以下代码: * for (var i = 0; i < rows.length; i++) { * var rowIndex = $('#dgg').edatagrid("getRowIndex", rows[i]); * $('#dgg').edatagrid("deleteRow", rowIndex); * } * 将不会移除掉表格里的起初的第1至5条数据,只会移除掉表格里的第1,3,5条数据, * 第2,4条数据不会被移除,但实际上数据库里的记录是被删除掉的。 * 使用以下注释掉的代码便可解决该问题。 * 可是这里我选择了调用$("#dgg").edatagrid("reload")这个方法重载当前页 * */ // var n = rows.length; // for (var i = 0; i < n; i++) { // var rowIndex = $('#dgg').edatagrid("getRowIndex", rows[0]); // $('#dgg').edatagrid("deleteRow", rowIndex); // } $("#dgg").edatagrid("reload"); } $.messager.alert("提示", data.msg, 'info'); }, error: function () { $.messager.alert("错误", "删除失败", 'error'); } }); } }); } }, '-', { iconCls: 'icon-search', text: "查找", handler: function () { $("#search_form").form("clear"); $("#dlg").dialog("open"); } }], /* * 由于没有使用edatagrid自带的destroyRow方法因此如下紧接着的注释掉的代码 * 也没有用了。 * PS:同时感受自带的方法灵活性不够,限制太多。 * */ // destroyMsg: { // norecord: { // 在没有记录选择的时候执行 // title: '警告', // msg: '当前没有选择任何行' // } // , // confirm: { // 在选择一行的时候执行 // title: '确认', // msg: '您肯定要删除选中行?' // } // // }, checkOnSelect: false, selectOnCheck: false, rowStyler: function (index) { if (index % 2 != 0) { return "background-color:#E0E3E6"; } } , fitColumns: true, singleSelect: true, pagination: true, pageList: [10, 20, 30, 50], pageSize: 10, rownumbers: true, saveUrl: "http://localhost:8080/SSMProjectMaven/student/ajax_add.do", updateUrl: "http://localhost:8080/SSMProjectMaven/student/update.do" // destroyUrl: "http://localhost:8080/SSMProjectMaven/student/delete.do" }); $("#dgg").edatagrid("getPager").pagination({ layout: ['list', 'first', 'prev', 'links', 'next', 'last', 'sep', 'refresh'] }); }) </script> </body> </html>
<!DOCTYPE html> <html lang = "en"> <head> <meta charset = "UTF-8"> <title>Tree</title> <link rel = "stylesheet" type = "text/css" href = "easyui/themes/default/easyui.css"> <link rel = "stylesheet" type = "text/css" href = "easyui/themes/icon.css"> <script type = "text/javascript" src = "js/jquery-2.1.4.min.js"></script> <script src = "easyui/jquery.easyui.min.js"></script> <script src = "easyui/easyui-lang-zh_CN.js"></script> </head> <body> <ul id = "tt"></ul> <script> $(function () { $("#tt").tree({ animate: true, lines: true, url: "http://localhost:8080/SSMProjectMaven/node/findAllTopRoot.do", method: "GET", onlyLeafCheck: true, checkbox: true, onLoadError: function () { alert("加载失败"); } } ); }) </script> </body> </html>
咱们在使用EasyUI时,插件的加载均可以使用HTML方式加载,或者使用JavaScript代码加载,当咱们使用HTML加载时,须要在容器中添加相似easyui-xxxx的类ID,当咱们使用纯JavaScript代码加载时应尽可能不要在容器中添加相似easyui-xxxx的类ID。不然在某些状况下将会出现问题。json
举个例子以下:
<table id = "dgg" class = "easyui-edatagrid"></table><!--注意这里我添加了一个"easyui-edatagrid"类ID--> <script> $(function () { //这里又经过使用JavaScript代码加载插件 $("#dgg").edatagrid({ //一系列的属性设置 }) //当咱们须要自定义表格的pagination时,以下 $("#dgg").edatagrid("getPager").pagination({ layout: ['list', 'first', 'prev', 'links', 'next', 'last', 'sep', 'refresh'] }); </script>
当咱们将该页面经过另外一个页面的panel的href属性嵌入到panel中时,如下的这段代码将会失效:
$("#dgg").edatagrid("getPager").pagination({ layout: ['list', 'first', 'prev', 'links', 'next', 'last', 'sep', 'refresh'] });
可是若是咱们单独打开这个子页面时,以上的那段代码是有效的。真不知道这是否是一个Bug。
解决方式就是去除这个类ID(在使用纯JavaScript加载插件的状况下才去除,若使用HTML方式加载请加上这个类ID):
class = "easyui-edatagrid"
以下这段代码:
<!--这里给div添加了一个样式--> <div style="text-align:center"><ul id = "tt"></ul></div> <script> $(function () { $("#tt").tree({ animate: true, lines: true, url: "http://localhost:8080/SSMProjectMaven/node/findAllTopRoot.do", method: "GET", onlyLeafCheck: true, checkbox: true, onLoadError: function () { alert("加载失败"); } } ); }) </script>
给Tree的容器div添加了以下的样式:
text-align:center
产生的效果以下(父节点与子节点错位):
而实际的状况应以下:
解决方式就是去掉容纳Tree的容器div的以下的CSS样式,便可恢复正常:
text-align:center
EasyUI 官方网站:http://www.jeasyui.com/index.php