jQuery EasyUI框架中的Datagrid數(shù)據(jù)表格組件結(jié)構(gòu)詳解
基礎(chǔ)DOM結(jié)構(gòu)
什么叫“完整的基礎(chǔ)DOM結(jié)構(gòu)”,這里“基礎(chǔ)”的意思是指這個(gè)結(jié)構(gòu)不依賴具體數(shù)據(jù),不依賴Datagrid的view屬性,只要存在Datagrid實(shí)例就會(huì)存在這樣的基礎(chǔ)DOM結(jié)構(gòu);而“完整”的意思是指在凍結(jié)列,凍結(jié)行,標(biāo)題,footer,分頁(yè)這些功能塊都存在時(shí)候的DOM結(jié)構(gòu)。
要搞清楚Datagrid的工作原理,這個(gè)DOM結(jié)構(gòu)必須要爛熟于胸的,我們直接來(lái)看這個(gè)“基礎(chǔ)完整DOM結(jié)構(gòu)”是什么樣子的:
<!-- datagrid的最外層容器,可以使用$(target).datagrid('getPanel')或者$.data(target,'datagrid').panel得到這個(gè)DOM對(duì)象,這個(gè)DOM上其實(shí)承載了panel組件--> <div class="panel datagrid"> <!-- datagrid的標(biāo)題區(qū)域容器,對(duì)應(yīng)于panel組件的header部分,可以使用$(target).datagrid('getPanel').panel('header')得到這個(gè)DOM對(duì)象--> <div class="panel-header"> <div class="panel-title"></div> <div class="panel-tool"></div> </div> <!-- datagrid的主體區(qū)域容器,對(duì)應(yīng)于panel組件的body部分,可以使用$(target).datagrid('getPanel').panel('body')得到這個(gè)DOM對(duì)象--> <div class="datagrid-wrap panel-body"> <!--工具欄--> <div class="datagrid-toolbar"></div> <!-- datagrid視圖部分的容器,這是datagrid組件DOM結(jié)構(gòu)的核心,其基礎(chǔ)視圖結(jié)構(gòu)跟datagrid的view屬性無(wú)任何關(guān)系。--> <!-- 對(duì)應(yīng)dc.view --> <div class="datagrid-view"> <!-- div.datagrid-view1負(fù)責(zé)展示凍結(jié)列部分(包含行號(hào)或者frozenColumns)的數(shù)據(jù)--> <!-- 對(duì)應(yīng)dc.view1 --> <div class="datagrid-view1"> <!--列標(biāo)題部分--> <div class="datagrid-header"> <!-- 對(duì)應(yīng)dc.header1 --> <div class="datagrid-header-inner"> <!--樣式里有htable關(guān)鍵字,h代表header的意思--> <table class="datagrid-htable"> <tbody> <tr class="datagrid-header-row"></tr> </tbody> </table> </div> </div> <!--列數(shù)據(jù)部分--> <div class="datagrid-body"> <!-- 對(duì)應(yīng)dc.body1 --> <div class="datagrid-body-inner"> <!--frozenRows部分(有數(shù)據(jù)才會(huì)有這個(gè)table,故不屬于基礎(chǔ)DOM結(jié)構(gòu)),固定行是1.3.2版本之后才加的功能,注意datagrid-btable-frozen關(guān)鍵樣式,btable代碼body table的意思--> <table class="datagrid-btable datagrid-btable-frozen"></table> <!--普通rows部分(有數(shù)據(jù)才會(huì)有這個(gè)table,故不屬于基礎(chǔ)DOM結(jié)構(gòu))--> <table class="datagird-btable"></table> </div> </div> <!--footer部分--> <div class="datagrid-footer"> <!-- 對(duì)應(yīng)dc.footer1 --> <div class="datagrid-footer-inner"> <!--ftable代表footer table的意思--> <table class="datagrid-ftable"></table> </div> </div> </div> <!-- div.datagrid-view2負(fù)責(zé)展示非凍結(jié)列部分的數(shù)據(jù),大家注意到凍結(jié)列和普通列視圖是分開的,也就是說(shuō)凍結(jié)列和普通列是在不同表格中展示的,這樣會(huì)產(chǎn)生一個(gè)問(wèn)題,那就是兩個(gè)表格行高之間的同步問(wèn)題。--> <!-- 對(duì)應(yīng)dc.view2 --> <div class="datagrid-view2"> <!--列標(biāo)題部分--> <div class="datagrid-header"> <!-- 對(duì)應(yīng)dc.header2 --> <div class="datagrid-header-inner"> <table class="datagrid-htable"> <tbody> <tr class="datagrid-header-row"></tr> </tbody> </table> </div> </div> <!--列數(shù)據(jù)部分,注意這里并無(wú)datagrid-body-inner這個(gè)子元素,而凍結(jié)列對(duì)應(yīng)的body卻是有的,這個(gè)是細(xì)微區(qū)別--> <!-- 對(duì)應(yīng)dc.body2 --> <div class="datagrid-body"> <!--frozenRows部分有數(shù)據(jù)才會(huì)有這個(gè)table,故不屬于基礎(chǔ)DOM結(jié)構(gòu),固定行是1.3.2版本之后才加的功能,--> <table class="datagrid-btable datagrid-btable-frozen"></table> <table class="datagrid-btable"></table> </div> <!--footer部分--> <div class="datagrid-footer"> <!-- 對(duì)應(yīng)dc.footer2 --> <div class="datagrid-footer-inner"> <table class="datagrid-ftable"></table> </div> </div> </div> </div> <!--分頁(yè)部分--> <div class="datagrid-pager pagination"></div> </div> </div>
對(duì)于這個(gè)DOM結(jié)構(gòu),我在html代碼里面已經(jīng)做了簡(jiǎn)單說(shuō)明,這里提一下綁定于Datagrid宿主table上的對(duì)象的dc屬性,這個(gè)dc屬性存儲(chǔ)了對(duì)DOM結(jié)構(gòu)里不同部分的引用,獲取dc屬性的方法:
$.data(target,'datagrid').dc;
而dc屬性跟DOM的對(duì)應(yīng)關(guān)系,我也在html中做了詳細(xì)注釋,請(qǐng)大家自行查看,這些都是我們深入認(rèn)識(shí)Datagrid組件的基礎(chǔ)。
默認(rèn)視圖分析
上面對(duì)Datagrid組件的骨架做了很詳細(xì)的描述。有了骨架還并不完整,還得有血有肉有衣服穿才行。強(qiáng)大的Datagrid組件允許我們自己定義如何在基礎(chǔ)骨架上長(zhǎng)出健壯誘人的身體,我們只要定義Datagrid的視圖就可以實(shí)現(xiàn)。
在大多數(shù)情況下,我們并無(wú)特別要求,Datagrid給我們提供了默認(rèn)的視圖,默認(rèn)視圖被使用在90%以上的場(chǎng)景,所以對(duì)默認(rèn)視圖的分析顯得非常有必要。注意視圖里面定義了哪些接口,哪些方法,如果要自己寫視圖的話,最好把這些接口和方法都寫齊全。
var view = { /** * 填充表格主體數(shù)據(jù)(生成數(shù)據(jù)部分的各行tr) * @param {DOM object} target datagrid宿主table對(duì)應(yīng)的DOM對(duì)象 * @param {DOM object} container 數(shù)據(jù)主體容器。包含兩個(gè)可能的值,即: * 1.frozen部分body1,對(duì)應(yīng)的DOM對(duì)象為:div.datagrid-view>div.datagrid-view1>div.datagrid-body>div.datagrid-body-inner * 2.常規(guī)部分body2,對(duì)應(yīng)的DOM對(duì)象為:div.datagrid-view>div.datagrid-view2>div.datagrid-body * @param {boolean} frozen 是否是凍結(jié)列 * @return {undefined} 未返回值 */ render: function(target, container, frozen) { var data = $.data(target, "datagrid"); var opts = data.options; var rows = data.data.rows; var fields = $(target).datagrid("getColumnFields", frozen); if(frozen) { //如果grid不顯示rownumbers并且也沒(méi)有frozenColumns的話,直接退出。 if(!(opts.rownumbers || (opts.frozenColumns && opts.frozenColumns.length))) { return; } } //定義表格字符串,注意這里使用了數(shù)組的join方式代替了傳統(tǒng)的"+"運(yùn)算符,在大多瀏覽器中,這樣效率會(huì)更高些。 var html = ["<table class=\"datagrid-btable\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\"><tbody>"]; for(var i = 0; i < rows.length; i++) { //striped屬性,用于設(shè)置grid數(shù)據(jù)是否隔行變色,當(dāng)然了實(shí)現(xiàn)原理很簡(jiǎn)單。 var cls = (i % 2 && opts.striped) ? "class=\"datagrid-row datagrid-row-alt\"" : "class=\"datagrid-row\""; /** * 表格的rowStyler屬性用于處理數(shù)據(jù)行的css樣式,當(dāng)然了這個(gè)樣式僅僅是作用于tr標(biāo)簽上。 * 這地方使用call了方法來(lái)設(shè)置上下文,如果rowStyler函數(shù)內(nèi)部使用了this的話,則this指向datagrid的宿主table對(duì)應(yīng)的DOM對(duì)象。 */ var style = opts.rowStyler ? opts.rowStyler.call(target, i, rows[i]) : ""; var styler = style ? "style=\"" + style + "\"" : ""; /** * rowId:行的唯一標(biāo)示,對(duì)應(yīng)于tr的id屬性,其由以下幾部分組成: * 1.字符竄常量:"datagrid-row-r"; * 2.全局索引index:該索引值從1開始遞增,同一個(gè)datagrid組件實(shí)例擁有唯一值,如果同一頁(yè)面內(nèi)有多個(gè)datagrid實(shí)例,那么其值從1遞增分配給每個(gè)datagrid實(shí)例; * 3.凍結(jié)列標(biāo)識(shí)frozen:該標(biāo)識(shí)用于標(biāo)示是否是凍結(jié)列(包含行號(hào)和用戶指定的frozenColumns),"1"代表凍結(jié)列,"2"代表非凍結(jié)列; * 4.行數(shù)索引:該值才是真正代表“第幾行”的意思,該值從0開始遞增 * 如頁(yè)面內(nèi)第一個(gè)datagrid實(shí)例的非凍結(jié)列第10行數(shù)據(jù)的rowId為"datagrid-row-r1-2-9" */ var rowId = data.rowIdPrefix + "-" + (frozen ? 1 : 2) + "-" + i; html.push("<tr id=\"" + rowId + "\" datagrid-row-index=\"" + i + "\" " + cls + " " + styler + ">"); /** * 調(diào)用renderRow方法,生成行數(shù)據(jù)(行內(nèi)的各列數(shù)據(jù))。 * 這里的this就是opts.view,之所以用call方法,只是為了傳參進(jìn)去。這里我們使用this.renderRow(target,fields,frozen,i,rows[i])來(lái)調(diào)用renderRow方法應(yīng)該也是可以的。 */ html.push(this.renderRow.call(this, target, fields, frozen, i, rows[i])); html.push("</tr>"); } html.push("</tbody></table>"); //用join方法完成字符創(chuàng)拼接后直接innerHTML到容器內(nèi)。 $(container).html(html.join("")); }, /** * [renderFooter description] * @param {DOM object} target datagrid宿主table對(duì)應(yīng)的DOM對(duì)象 * @param {DOM object} container 可能為dc.footer1或者dc.footer2 * @param {boolean} frozen 是否為frozen區(qū) * @return {undefined} 未返回值 */ renderFooter: function(target, container, frozen) { var opts = $.data(target, "datagrid").options; //獲取footer數(shù)據(jù) var rows = $.data(target, "datagrid").footer || []; var columnsFields = $(target).datagrid("getColumnFields", frozen); //生成footer區(qū)的table var footerTable = ["<table class=\"datagrid-ftable\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\"><tbody>"]; for(var i = 0; i < rows.length; i++) { footerTable.push("<tr class=\"datagrid-row\" datagrid-row-index=\"" + i + "\">"); footerTable.push(this.renderRow.call(this, target, columnsFields, frozen, i, rows[i])); footerTable.push("</tr>"); } footerTable.push("</tbody></table>"); $(container).html(footerTable.join("")); }, /** * 生成某一行數(shù)據(jù) * @param {DOM object} target datagrid宿主table對(duì)應(yīng)的DOM對(duì)象 * @param {array} fields datagrid的字段列表 * @param {boolean} frozen 是否為凍結(jié)列 * @param {number} rowIndex 行索引(從0開始) * @param {json object} rowData 某一行的數(shù)據(jù) * @return {string} 單元格的拼接字符串 */ renderRow: function(target, fields, frozen, rowIndex, rowData) { var opts = $.data(target, "datagrid").options; //用于拼接字符串的數(shù)組 var cc = []; if(frozen && opts.rownumbers) { //rowIndex從0開始,而行號(hào)顯示的時(shí)候是從1開始,所以這里要加1. var rowNumber = rowIndex + 1; //如果分頁(yè)的話,根據(jù)頁(yè)碼和每頁(yè)記錄數(shù)重新設(shè)置行號(hào) if(opts.pagination) { rowNumber += (opts.pageNumber - 1) * opts.pageSize; } /** * 先拼接行號(hào)列 * 注意DOM特征,用zenCoding可表達(dá)為"td.datagrid-td-rownumber>div.datagrid-cell-rownumber" */ cc.push("<td class=\"datagrid-td-rownumber\"><div class=\"datagrid-cell-rownumber\">" + rowNumber + "</div></td>"); } for(var i = 0; i < fields.length; i++) { var field = fields[i]; var col = $(target).datagrid("getColumnOption", field); if(col) { var value = rowData[field]; //獲取用戶定義的單元格樣式,入?yún)ǎ簡(jiǎn)卧裰?,?dāng)前行數(shù)據(jù),當(dāng)前行索引(從0開始) var style = col.styler ? (col.styler(value, rowData, rowIndex) || "") : ""; //如果是隱藏列直接設(shè)置display為none,否則設(shè)置為用戶想要的樣式 var styler = col.hidden ? "style=\"display:none;" + style + "\"" : (style ? "style=\"" + style + "\"" : ""); cc.push("<td field=\"" + field + "\" " + styler + ">"); //如果當(dāng)前列是datagrid組件保留的ck列時(shí),則忽略掉用戶定義的樣式,即styler屬性對(duì)datagrid自帶的ck列是不起作用的。 if(col.checkbox) { var styler = ""; } else { var styler = ""; //設(shè)置文字對(duì)齊屬性 if(col.align) { styler += "text-align:" + col.align + ";"; } //設(shè)置文字超出td寬時(shí)是否自動(dòng)換行(設(shè)置為自動(dòng)換行的話會(huì)撐高單元格) if(!opts.nowrap) { styler += "white-space:normal;height:auto;"; } else { /** * 并不是nowrap屬性為true單元格就肯定不會(huì)被撐高,這還得看autoRowHeight屬性的臉色 * 當(dāng)autoRowHeight屬性為true的時(shí)候單元格的高度是根據(jù)單元格內(nèi)容而定的,這種情況主要是用于表格里展示圖片等媒體。 */ if(opts.autoRowHeight) { styler += "height:auto;"; } } } //這個(gè)地方要特別注意,前面所拼接的styler屬性并不是作用于td標(biāo)簽上,而是作用于td下的div標(biāo)簽上。 cc.push("<div style=\"" + styler + "\" "); //如果是ck列,增加"datagrid-cell-check"樣式類 if(col.checkbox) { cc.push("class=\"datagrid-cell-check "); } //如果是普通列,增加"datagrid-cell-check"樣式類 else { cc.push("class=\"datagrid-cell " + col.cellClass); } cc.push("\">"); /** * ck列光設(shè)置class是不夠的,當(dāng)突然還得append一個(gè)input進(jìn)去才是真正的checkbox。此處未設(shè)置input的id,只設(shè)置了name屬性。 * 我們注意到formatter屬性對(duì)datagird自帶的ck列同樣不起作用。 */ if(col.checkbox) { cc.push("<input type=\"checkbox\" name=\"" + field + "\" value=\"" + (value != undefined ? value : "") + "\"/>"); } //普通列 else { /** * 如果單元格有formatter,則將formatter后生成的DOM放到td>div里面 * 換句話說(shuō),td>div就是如來(lái)佛祖的五指山,而formatter只是孫猴子而已,猴子再怎么變化翻跟頭,始終在佛祖手里。 */ if(col.formatter) { cc.push(col.formatter(value, rowData, rowIndex)); } //操,這是最簡(jiǎn)單的簡(jiǎn)況了,將值直接放到td>div里面。 else { cc.push(value); } } cc.push("</div>"); cc.push("</td>"); } } //返回單元格字符串,注意這個(gè)函數(shù)內(nèi)部并未把字符串放到文檔流中。 return cc.join(""); }, /** * 刷新行數(shù)據(jù),只有一個(gè)行索引(從0開始),調(diào)用的updateRow方法,這里直接跳過(guò)。 * @param {DOM object} target datagrid實(shí)例的宿主table對(duì)應(yīng)的DOM對(duì)象 * @param {number} rowIndex 行索引(從0開始) * @return {undefined} 未返回?cái)?shù)據(jù) */ refreshRow: function(target, rowIndex) { this.updateRow.call(this, target, rowIndex, {}); }, /** * 刷新行數(shù)據(jù),該接口方法肩負(fù)著同步行高,重新計(jì)算和布局grid面板等重任 * @param {DOM object} target datagrid實(shí)例的宿主table對(duì)應(yīng)的DOM對(duì)象 * @param {number} rowIndex 行索引(從0開始) * @param {json object} 行數(shù)據(jù) * @return {undefined} 未返回?cái)?shù)據(jù) */ updateRow: function(target, rowIndex, row) { var opts = $.data(target, "datagrid").options; var rows = $(target).datagrid("getRows"); $.extend(rows[rowIndex], row); var style = opts.rowStyler ? opts.rowStyler.call(target, rowIndex, rows[rowIndex]) : ""; function updateTableRow(frozen) { var fields = $(target).datagrid("getColumnFields", frozen); //這個(gè)地方查找grid的數(shù)據(jù)主體表格(可能包含凍結(jié)列對(duì)應(yīng)的主體表格和普通列對(duì)應(yīng)的主體表格) //getTr這個(gè)函數(shù),我在博客上介紹過(guò),請(qǐng)參考:http://www.easyui.info/archives/396.html var tr = opts.finder.getTr(target, rowIndex, "body", (frozen ? 1 : 2)); var checked = tr.find("div.datagrid-cell-check input[type=checkbox]").is(":checked"); //這里調(diào)用了renderRow方法來(lái)重新獲取當(dāng)前行的html字符串 tr.html(this.renderRow.call(this, target, fields, frozen, rowIndex, rows[rowIndex])); tr.attr("style", style || ""); //更新的時(shí)候保留checkbox狀態(tài)(包含兩層信息:一是有ck列;二是ck列被之前就被選中) if(checked) { tr.find("div.datagrid-cell-check input[type=checkbox]")._propAttr("checked", true); } }; //更新凍結(jié)列對(duì)應(yīng)的行 updateTableRow.call(this, true); //更新普通列對(duì)應(yīng)的行 updateTableRow.call(this, false); //重新布局表格面板 $(target).datagrid("fixRowHeight", rowIndex); }, insertRow: function(target, rowIndex, row) { var state = $.data(target, "datagrid"); //options var opts = state.options; //document of datagrid var dc = state.dc; var data = state.data; //兼容無(wú)效的rowIndex,默認(rèn)設(shè)置為在最后一行追加 if(rowIndex == undefined || rowIndex == null) { rowIndex = data.rows.length; } //為啥不跟上面的條件并到一起 if(rowIndex > data.rows.length) { rowIndex = data.rows.length; } /** * 下移rows * @param {boolean} frozen 是否為frozen部分 * @return {undefined} 無(wú)返回值 */ function moveDownRows(frozen) { //1:凍結(jié)列部分;2:普通列部分 var whichBody = frozen ? 1 : 2; for(var i = data.rows.length - 1; i >= rowIndex; i--) { var tr = opts.finder.getTr(target, i, "body", whichBody); //注意這地方設(shè)置了tr的"datagrid-row-index"和"id"屬性 tr.attr("datagrid-row-index", i + 1); tr.attr("id", state.rowIdPrefix + "-" + whichBody + "-" + (i + 1)); //計(jì)算行號(hào) if(frozen && opts.rownumbers) { //因rowIndex從0開始,以及須插入位置以下的tr要統(tǒng)一下移,所以新行號(hào)為i+2 var rownumber = i + 2; //有分頁(yè)的話,行號(hào)還要加上分頁(yè)數(shù)據(jù) if(opts.pagination) { rownumber += (opts.pageNumber - 1) * opts.pageSize; } tr.find("div.datagrid-cell-rownumber").html(rownumber); } } }; /** * 插入了,要插兩個(gè)地方的哦(如果你是男人,你可以笑一下) * @param {boolean} frozen 是否是frozen部分 * @return {undefined} 未返回值 */ function doInsert(frozen) { var whichBody = frozen ? 1 : 2; //這行代碼,不知道是干嘛的,怕插入得太快而早早繳械,所以才故意拖延時(shí)間的么? var columnFields = $(target).datagrid("getColumnFields", frozen); //構(gòu)造新插入行的id屬性 var trId = state.rowIdPrefix + "-" + whichBody + "-" + rowIndex; var tr = "<tr id=\"" + trId + "\" class=\"datagrid-row\" datagrid-row-index=\"" + rowIndex + "\"></tr>"; if(rowIndex >= data.rows.length) { //如果已經(jīng)有記錄,則插入tr即可 if(data.rows.length) { //嗯哼,getTr的這個(gè)用法不多哦,未傳入行索引,第三個(gè)參數(shù)為"last",隨便的意淫一下就知道是獲取最后一行了 //然后再在最后一行后插入一行,注意了,這里用的后入式 opts.finder.getTr(target, "", "last", whichBody).after(tr); } //如果表格尚無(wú)記錄,則要生成表格,同時(shí)插入tr else { var cc = frozen ? dc.body1 : dc.body2; cc.html("<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\"><tbody>" + tr + "</tbody></table>"); } } //在rowIndex + 1前準(zhǔn)確無(wú)誤地插入,注意了,這里是前入式。 else { opts.finder.getTr(target, rowIndex + 1, "body", whichBody).before(tr); } }; //下移frozen部分 moveDownRows.call(this, true); //下移普通列部分 moveDownRows.call(this, false); //插入frozen區(qū) doInsert.call(this, true); //插入普通區(qū) doInsert.call(this, false); //總數(shù)加1 data.total += 1; //維護(hù)data.rows數(shù)組,這地方是插入一個(gè)數(shù)組元素了 data.rows.splice(rowIndex, 0, row); //刷新,其中包含了重新布局grid面板等復(fù)雜得一筆的操作 //插入本是件很簡(jiǎn)單愉快的事情,可是你得為其后果負(fù)上沉重的代價(jià) this.refreshRow.call(this, target, rowIndex); }, /** * 刪除行接口 * @param {DOM object} target datagrid實(shí)例的宿主table對(duì)應(yīng)的DOM對(duì)象 * @param {number} rowIndex 行索引 * @return {undefined} 未返回值 */ deleteRow: function(target, rowIndex) { var state = $.data(target, "datagrid"); var opts = state.options; var data = state.data; function moveUpRows(frozen) { var whichBody = frozen ? 1 : 2; for(var i = rowIndex + 1; i < data.rows.length; i++) { var tr = opts.finder.getTr(target, i, "body", whichBody); //"datagrid-row-index"和"id"屬性減一 tr.attr("datagrid-row-index", i - 1); tr.attr("id", state.rowIdPrefix + "-" + whichBody + "-" + (i - 1)); if(frozen && opts.rownumbers) { var rownumber = i; if(opts.pagination) { rownumber += (opts.pageNumber - 1) * opts.pageSize; } tr.find("div.datagrid-cell-rownumber").html(rownumber); } } }; //移除行 opts.finder.getTr(target, rowIndex).remove(); //上移frozen區(qū) moveUpRows.call(this, true); //上移普通區(qū) moveUpRows.call(this, false); //記錄數(shù)減一 data.total -= 1; //維護(hù)data.rows數(shù)據(jù) data.rows.splice(rowIndex, 1); }, /** * 默認(rèn)的onBeforeRender事件 為空 * @param {DOM object} target datagrid實(shí)例的宿主table對(duì)應(yīng)的DOM對(duì)象 * @param {array} rows 要插入的數(shù)據(jù) * @return {undefined} 默認(rèn)未返回值 */ onBeforeRender: function(target, rows) {}, /** * 默認(rèn)的onAfterRender 隱藏footer里的行號(hào)和check * @param {DOM object} target datagrid實(shí)例的宿主table對(duì)應(yīng)的DOM對(duì)象 * @return {undefined} 未返回值 */ onAfterRender: function(target) { var opts = $.data(target, "datagrid").options; if(opts.showFooter) { var footer = $(target).datagrid("getPanel").find("div.datagrid-footer"); footer.find("div.datagrid-cell-rownumber,div.datagrid-cell-check").css("visibility", "hidden"); } } };
- Python SqlAlchemy動(dòng)態(tài)添加數(shù)據(jù)表字段實(shí)例解析
- java使用JDBC動(dòng)態(tài)創(chuàng)建數(shù)據(jù)表及SQL預(yù)處理的方法
- 如何將Oracle的一個(gè)大數(shù)據(jù)表快速遷移到 Sqlserver2008數(shù)據(jù)庫(kù)(圖文教程)
- Angualrjs和bootstrap相結(jié)合實(shí)現(xiàn)數(shù)據(jù)表格table
- bootstrap table 數(shù)據(jù)表格行內(nèi)修改的實(shí)現(xiàn)代碼
- MySQL中大數(shù)據(jù)表增加字段的實(shí)現(xiàn)思路
- mysql中數(shù)據(jù)庫(kù)與數(shù)據(jù)表編碼格式的查看、創(chuàng)建及修改
- Android實(shí)現(xiàn)仿excel數(shù)據(jù)表格效果
- MySQL清空數(shù)據(jù)表的方法實(shí)例與分析
- MySQL中復(fù)制數(shù)據(jù)表中的數(shù)據(jù)到新表中的操作教程
- Oracle的數(shù)據(jù)表中行轉(zhuǎn)列與列轉(zhuǎn)行的操作實(shí)例講解
- 詳解數(shù)據(jù)庫(kù)中跨庫(kù)數(shù)據(jù)表的運(yùn)算
相關(guān)文章
jQuery EasyUi 驗(yàn)證功能實(shí)例解析
本文給大家分享jquery easyui驗(yàn)證功能的實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下2017-01-01jquery關(guān)于圖形報(bào)表的運(yùn)用實(shí)現(xiàn)代碼
jquery 關(guān)于圖形報(bào)表的運(yùn)用實(shí)現(xiàn)代碼,需要的朋友可以參考下。2011-01-01在網(wǎng)站上應(yīng)該用的30個(gè)jQuery插件整理
jQuery插件是網(wǎng)頁(yè)設(shè)計(jì)師最喜歡的。從圖像滑塊,圖像畫廊和導(dǎo)航插件,它們是如此眾多,如此多樣,如此驚人的和互動(dòng)可以制作美化網(wǎng)站2011-11-11jQuery實(shí)現(xiàn)驗(yàn)證用戶登錄
這篇文章主要為大家詳細(xì)介紹了jQuery實(shí)現(xiàn)驗(yàn)證用戶登錄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12jquery實(shí)現(xiàn)表格行拖動(dòng)排序
這篇文章主要為大家詳細(xì)介紹了jquery實(shí)現(xiàn)表格行拖動(dòng)排序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02基于Jquery實(shí)現(xiàn)仿百度百科右側(cè)導(dǎo)航代碼附源碼下載
本篇文章給大家介紹基于jquery實(shí)現(xiàn)仿百度百科右側(cè)導(dǎo)航代碼附源碼下載,對(duì)百度百科右側(cè)導(dǎo)航代碼相關(guān)內(nèi)容感興趣的朋友可以參考下本文2015-11-11jquery操作select常見(jiàn)方法大全【7種情況】
這篇文章主要介紹了jquery操作select常見(jiàn)方法,結(jié)合實(shí)例形式總結(jié)分析了jQuery操作select常見(jiàn)的7種情況與相關(guān)操作技巧,需要的朋友可以參考下2019-05-05