• 一个GridView客户端扩展脚本库


    近期有个项目频繁使用到GridView控件,于是动手写了个针对GridView的客户端脚本库,用来优化GridView的用户体验,包括行选择(单行选定,多行选定),行点击(单击,双击),行操作(删除,移动)等。兼容包括IE在内的多种内核浏览器。

    示例文件下载:https://files.cnblogs.com/wfyfngu/ClientTableDemo.zip

    下面是使用该库的一个典型用法。

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head>
      
    <title>ClientTable.js Test</title>
      
    <!--引入GridView样式文件-->
      
    <link rel="stylesheet" type="text/css" href="/css/grid.css" />
      
    <!--ClientTable必须的文件-->
      
    <script type="text/javascript" src="/script/RINDEX.js"></script>
      
    <script type="text/javascript" src="/script/ClientTable.js"></script>
    </head>

    <body>

      
    <asp:GridView id="gridview1" runat="server">
        
    <EmptyDataTemplate>
          
    <center>There're no items to show in this view.</center>
        
    </EmptyDataTemplate>
      
    </asp:GridView>

    <script type="text/javascript">
    // 实例化一个ClientTable对象
    var ETABLE = new ClientTable('gridview1'nullnull);
    // 例化一个ClientTable对象,隐藏表格的第一和第二列
    //
     var ETABLE = new ClientTable('gridview1', null, [0,1]);
    //
     捕捉行选中事件
    ETABLE.onSelectChange = function(row) {
     
    // 弹出最后一个被选中的行的索引
     alert(row.rowIndex);
    };
    </script>

    </body>

    </html>

    下面附上各个文件的代码。

    RINDEX.js


    /**
     * @author wfyfngu
     * @create Apri 25, 2008
     
    */


    /**
     * @namespace RINDEX
     
    */
    if (typeof RINDEX == 'undefined'
        RINDEX 
    = {};

    /**
     * @namespace RINDEX.Widget
     
    */
    if (typeof RINDEX.Widget == 'undefined'
        RINDEX.Widget 
    = {};


    /**
     * RINDEX 控件公共实用类
     * @class RINDEX.Utility
     * @static
     
    */
    RINDEX.Utility 
    = {

        
    /**
         * 获取一个值,该值指示当前的浏览器是否是IE
         * @field isIE
         * @type Boolean
         
    */
        isIE: document.all 
    ? true : false,
        
        
    /**
         * 获取一个 HTML 元素
         * @method getObject
         * @param obj {HTMLElement || String} 要获取的元素或元素的ID
         * @return HTMLElement
         
    */
        getObject: 
    function(obj){
            
    if (typeof obj == 'string') {
                
    if (this.isIE) 
                    obj 
    = document.all(obj);
                
    else 
                    obj 
    = document.getElementById(obj);
            }
            
    return obj;
        },
        
        
    /**
         * 生成具有指定标签的 HTML 元素
         * @method createObject
         * @param tag {String} 要生成的元素的标签
         * @param id {String || Null} 生成的元素的ID
         * @return HTMLElement
         
    */
        createObject: 
    function(tag, id){
            
    var obj = document.createElement(tag);
            
    if (obj) {
                
    if (id != null
                    obj.id 
    = id;
                
    return obj;
            }
            
    //return document.body;
            return null;
        },
        
        
    /**
         * 追加指定的 CSS 样式到目标 HTML 对象
         * @method addCSS
         * @param obj {HTMLElement} 要追加样式的目标对象
         * @param className {String} CSS 样式名称
         * @return void
         
    */
        addCSS: 
    function(obj, className){
            
    try {
                
    var css = obj.className;
                
    var index = css.indexOf(className);
                
    if (index < 0
                    css 
    += ' ' + className;
                
                obj.className 
    = css;
            } 
            
    catch (e) {
                
    // TODO : 删除下一行
                confirm('Exception:' + e);
            }
        },
        
        
    /**
         * 从目标 HTML 对象删除指定的 CSS 样式
         * @method addCSS
         * @param obj {HTMLElement} 要删除样式的目标对象
         * @param className {String} CSS 样式名称
         * @return void
         
    */
        removeCSS: 
    function(obj, className){
            
    try {
                
    var css = obj.className;
                
    var cssArr = css.split(' ');
                
                
    var nwCss = '';
                
                
    for (var i = 0; i < cssArr.length; i++) {
                    
    if (cssArr[i] == className) 
                        
    continue;
                    nwCss 
    += cssArr[i] + ' ';
                }
                
                obj.className 
    = nwCss;
                
            } 
            
    catch (e) {
                
    // TODO : 删除下一行
                confirm('Exception:' + e);
            }
        },
        
        
    /**
         * 使用指定的数值格式化表格
         * @method formatTable
         * @param tableObject {HtmlTableElement} 要格式化的表格
         * @param border {Number} 表格的边框宽度
         * @param cellSpacing {Number} 表格单元格的间距
         * @param cellPadding {Number} 表格中单元格的边距
         * @param align {String} 表格的对齐方式
         * @return void
         
    */
        formatTable: 
    function(tableObject, border, cellSpacing, cellPadding, align){
            
    if (border == null || isNaN(parseInt(border))) 
                border 
    = 0;
            
    else 
                border 
    = parseInt(border);
            
            
    if (cellSpacing == null || isNaN(parseInt(cellSpacing))) 
                cellSpacing 
    = 0;
            
    else 
                cellSpacing 
    = parseInt(border);
            
            
    if (cellPadding == null || isNaN(parseInt(cellPadding))) 
                cellPadding 
    = 0;
            
    else 
                cellPadding 
    = parseInt(border);
            
            tableObject.border 
    = border;
            tableObject.cellPadding 
    = cellSpacing;
            tableObject.cellSpacing 
    = cellPadding;
            
    if (align) 
                tableObject.align 
    = align;
        },
        
        
    /**
         * 还原因单击,双击或其它交互引起的任何控件格式的改变
         * 通常运用于FireFox等非IE内核的浏览器
         * @method refreshControl
         * @return void
         
    */
        refreshControl: 
    function(){
            
    var sel;
            
    if (window.getSelection) {
                sel 
    = window.getSelection();
            }
            
    else 
                
    if (document.getSelection) {
                    sel 
    = document.getSelection();
                }
                
    else 
                    
    if (document.selection) {
                        sel 
    = document.selection;
                    }
            
            
    if (sel) {
                
    if (sel.empty) {
                    sel.empty();
                }
                
    else 
                    
    if (sel.removeAllRanges) {
                        sel.removeAllRanges();
                    }
                    
    else 
                        
    if (sel.collapse) {
                            sel.collapse();
                        }
            }
        },
        
        
    /**
         * @method toString
         * @return String
         
    */
        toString: 
    function(){
            
    return '[Object:RINDEX.Utility]';
        }
        
    };

    /*==============================================================================================*/

    /**
     * @class RINDEX.Lang
     * @static
     
    */
    RINDEX.Lang 
    = {
        
        
    /**
         * 检查指定的对象是否是数组
         * @param {Object} input 要检查的对象
         * @return Boolean
         
    */
        isArray : 
    function(input) {
            
    if (input && input.slice &&input.push)
                
    return true;
            
    return false;
        },
        
        
    /**
         * 检查指定的对象是否是数字
         * @param {Object} input 要检查的对象
         * @return Boolean
         
    */
        isNumber : 
    function(input) {
            
    return typeof input == 'number' && isFinite(input);
        },
        
        
    /**
         * 从父类复制方法到指定的子类
         * @param subClass {Function}  子类
         * @param superClass {Function} 父类
         
    */
        extend : 
    function(subClass, superClass) {
            
    if (!subClass||!superClass) {
                
    throw new Error("Call RINDEX.Lang.extend failed, not all arguments are included.");
            }
            
    var F = function() {};
            F.prototype
    =superClass.prototype;
            subClass.prototype
    =new F();
            subClass.prototype.constructor
    =subClass;
            subClass.superclass
    =superClass.prototype;
            
    if (superClass.prototype.constructor == Object.prototype.constructor) {
                superClass.prototype.constructor
    =superClass;
            }
        },
        
        
    /**
         * @private
         
    */
        toString : 
    function() {
            
    return '[RINDEX.Lang]';
        }

        
    };

    /*==============================================================================================*/

    /**
     * 可以用来表示一个平面坐标中某一特定位置的类
     * @class RINDEX.Position
     * @param {number} x X坐标
     * @param {number} y Y坐标
     
    */
    RINDEX.Position 
    = function(x,y) {
        
        
    /**
         * X坐标
         * @field x
         * @type Number
         
    */
        
    this.x = x;
        
        
    /**
         * Y坐标
         * @field y
         * @type Number
         
    */
        
    this.y = y;
        
        
    if(!RINDEX.Lang.isNumber(this.x))
            
    this.x = 0;
        
    if(!RINDEX.Lang.isNumber(this.y))
            
    this.y = 0;
            
    };

    ClientTable.js

    // JScript File

    if(typeof RINDEX == 'undefined' || typeof RINDEX.Widget == 'undefined')
        
    throw new Error('Required file "RIndex.js" was missing.');

    ClientTable 
    = function(tableToConvert, excludeRowClassNameArr, hiddenColumnIndexArr) {
      
      
    this.table = RINDEX.Utility.getObject(tableToConvert);
        
        
    this.selectedRows = [];
        
        
    this.disabled = false;
        
        
    /**
         * @field multiSelection
         * 获取一个值,该值指示是否可以同时选中多行
         *@type Boolean
         
    */
        
    this.multiSelection = true;
        
        
    this.excludeClassName = excludeRowClassNameArr;
        
    this.hiddenColumnIndex = hiddenColumnIndexArr; // 要隐藏的列

        
    if(this.table != null) {
          
    this.table.onselectstart = function() {return false;};
          RINDEX.Utility.formatTable(
    this.table);
          RINDEX.Utility.addCSS(
    this.table,'editTable');
          
    this._init();
        }
      
    };


    ClientTable.prototype 
    = {

      
    // Events
      onRowSelected : function(row) {
            
    return true;
        },
        
      onSelectChange : 
    function(row) {
            
    return true;
        },
        
        onDblClick : 
    function(row) {
            
    return true;
        },

      _init : 
    function() {
        
    this._format();
        
    if(!this.disabled) {
          
    this._attachEvent();
        }
      },
      
      _format : 
    function() {
        
    if(this.table.rules)
          
    this.table.rules = 'none';
        
    var rowCount = this.table.rows.length;
        
    var cellCount = null;
        
    var tblHeader, tblRow;
        
        
    // Hide the haeder row
        tblHeader = this.table.rows[0];
        
    if(0 in tblHeader.cells) {
          
    if(tblHeader.cells[0].tagName.toUpperCase() == 'TH') {
            
    this._hidColume(this.table.rows[0]);
          }
        }
        
        
    // Hide all other rows
        for(var i=1; i<rowCount; i++) {
          tblRow 
    = this.table.rows[i];
          
    this._hidColume(tblRow);
          
          
    if(this._skipRow(tblRow))
            
    continue;
          
    if(cellCount == null) {
            cellCount 
    = tblRow.cells.length;
          }
          
    for(var cell=0; cell<cellCount; cell++){
            tblRow.cells[cell].className 
    = 'item-' + ((i+1)%2);
          }
        }
      },
      
      _hidColume : 
    function(rowEL) {
        
    if(this.hiddenColumnIndex && this.hiddenColumnIndex.length) {
          
    var indexCount = this.hiddenColumnIndex.length;
          
    if(indexCount>0) {
          
            
    if(this._skipRow(rowEL)) {
              rowEL.childNodes[
    0].colSpan -= indexCount;
            } 
    else {
              
    for(var cell=0; cell<rowEL.cells.length; cell++) {
                
    for(var index=0; index<indexCount; index++){
                  
    if(this.hiddenColumnIndex[index] == cell) {
                    rowEL.cells[cell].style.display 
    = 'none';
                  }
                }
              }
            }
            
          }
        }
      },
      
      _attachEvent : 
    function(event) {
        
    var rowCount = this.table.rows.length;
        
    var tblRow; var self = this;
        event 
    = event || window.event;
        
    for(var i=1; i<rowCount; i++) {
          tblRow 
    = this.table.rows[i];
          
    if(this._skipRow(tblRow))
            
    continue;
          tblRow.onclick 
    = function(event) {
            self.select(
    this, event);
          };
          tblRow.ondblclick 
    = function() {
            self.onDblClick(
    this);
          };
        } 
      },
      
      _skipRow : 
    function(rowEL) {
        
    if(rowEL.className && this.excludeClassName && this.excludeClassName.length) {
          
    for(var i=0; i<this.excludeClassName.length; i++) {
            
    if(this.excludeClassName == rowEL.className)
              
    return true;
          }
        }
        
    return false;
      },
      
      select : 
    function(row, event) {
        
            event 
    = event || window.event;
                
            
    if(RINDEX.Lang.isNumber(row))
                row 
    = this.table.rows[row];
                
            
    if(this.multiSelection == false) {
            
              
    if(this.selectedRows.length > 0) {
                
    if(this.selectedRows[0!= row) {
                  
    this.unSelect(this.selectedRows[0]);
                  
    this.selectedRows = [row];
                  
    this._appendSelectStyle(row);
                  
    this.onRowSelected(row);
                        
    this.onSelectChange(row);
                }
              } 
    else {
                
    this.selectedRows = [row];
                
    this._appendSelectStyle(row);
                
    this.onRowSelected(row);
                    
    this.onSelectChange(row);
              }
            }
            
            
    else {
                
                
    var contains = false;
                
    for(var i=0; i<this.selectedRows.length; i++) {
                    
    if(this.selectedRows[i] == row) {
                        contains 
    = true;
                        
    break;
                    }
                }

                
    if(event.ctrlKey) {
                    
                    
    if(!contains) {
                        
    this.selectedRows.push(row);
                        
    this._appendSelectStyle(row);
                        
    this.onRowSelected(row);
                        
    this.onSelectChange(row);
                    } 
    else {
                        
    this.unSelect(row);
                    }
                }
                
                
    else if(event.shiftKey) {
                
                  
    var baseRow = 0;
                  
    if(this.selectedRows.length > 0)
                    baseRow 
    = this.selectedRows[this.selectedRows.length-1].rowIndex
                    
                  
    var nwArr = [];
                  
    var rowIndex = row.rowIndex;
                  
                  
    if(baseRow < rowIndex) {
                        
    for(var value = rowIndex; value>=baseRow; value--) {
                                nwArr.push(value);
                        }
                    } 
    else {
                        
    for(var value = rowIndex; value<=baseRow; value++) {
                                nwArr.push(value);
                        }
                    }

                    
    this._clearAllSelection();
                    
                    
    for(var i=0; i<nwArr.length; i++) {
                      
    this.selectedRows.push(this.table.rows[nwArr[i]]);
                      
    this._appendSelectStyle(this.table.rows[nwArr[i]]);
                    }
                    
                    
    this.onSelectChange(row);
                    
                }
                
                
    else {
                    
                    
    this._clearAllSelection();
                    
                    
    this.selectedRows.push(row);
                    
    this._appendSelectStyle(row);
                    
    this.onRowSelected(row);
                    
    this.onSelectChange(row);
                }
                
            }
            
            RINDEX.Utility.refreshControl();
            
        },
        
        unSelect : 
    function(row) {
          
    if(this.disabled) return row;
            
    if(RINDEX.Lang.isNumber(row))
                row 
    = this.table.rows[row];
                
            
    var index = -1;
            
    for(var i=0; i<this.selectedRows.length; i++) {
                
    if(this.selectedRows[i] == row) {
                    index 
    = i;
                    
    break;
                }
            }
            
            
    if(index > -1) {
                
    this.selectedRows =
                    
    this.selectedRows.slice(0,index).concat(this.selectedRows.slice(index+1));
                
    this._clearSelectStyle(row);
                
    this.onSelectChange(row);
            }
                
        },
        
        moveUp : 
    function(rowEL) { 
          
    var currentRowIndex = rowEL.rowIndex;
          
    if(currentRowIndex<2)
            
    return;
          
    var nwRow = this.table.insertRow(currentRowIndex-1);
          
    var tempCell, rawCell;
          
    for(var i=0; i<rowEL.cells.length; i++) {
            rawCell 
    = rowEL.cells[i];
            tempCell 
    = nwRow.insertCell(i);
            tempCell.innerHTML 
    = rawCell.innerHTML;
            tempCell.className 
    = rawCell.className;
          }
          
    this.remove(rowEL);
          
    this._attachEvent();
          
    this.select(nwRow);
        },
        
        moveDown : 
    function(rowEL) {
          
    var currentRowIndex = rowEL.rowIndex;
          
    if(currentRowIndex==this.table.rows.length-1)
            
    return;
          
    var nwRow = this.table.insertRow(currentRowIndex+2);
          
    var tempCell, rawCell;
          
    for(var i=0; i<rowEL.cells.length; i++) {
            rawCell 
    = rowEL.cells[i];
            tempCell 
    = nwRow.insertCell(i);
            tempCell.innerHTML 
    = rawCell.innerHTML;
            tempCell.className 
    = rawCell.className;
          }
          
    this.remove(rowEL);
          
    this._attachEvent();
          
    this.select(nwRow);
        },
        
        remove : 
    function(row) {
          
    if(this.disabled) return row;
            
    if(RINDEX.Lang.isNumber(row))
                row 
    = this.table.rows[row];
            
    try {
                
    this.unSelect(row);
                
    this.table.deleteRow(row.rowIndex);
                
    this._format();
            } 
    catch(e) {
                
    //
            }
        },
        
        removeSelectedRows : 
    function() {
          
    if(this.disabled) return;
            
    while(this.selectedRows.length > 0)
                
    this.remove(this.selectedRows[0]);
        },
        
        getCellText : 
    function(cellIndex) {
          
    var rowCount = this.selectedRows.length;
          
    var arr = new Array(rowCount);
          
    for(var i=0; i<rowCount; i++) {
            
    if(document.all)
              arr[i] 
    = this.selectedRows[i].cells[cellIndex].innerText;
            
    else
              arr[i] 
    = this.selectedRows[i].cells[cellIndex].textContent;
          }
          
    return arr;
        },
        
        changeHeaderText : 
    function(textArr) {
          
    var headerRow = this.table.rows[0];
          
    var cellCount = headerRow.cells.length-1;
          
    var tempCellEL;
          
    for(var i=0; i<textArr.length; i++) {
            
    if(i > cellCount)
              
    continue;
            tempCellEL 
    = headerRow.cells[i];
            
    if(tempCellEL.tagName.toUpperCase() == 'TH') {
              tempCellEL.innerHTML 
    = textArr[i];
            }
          }
        },
        
        _appendSelectStyle : 
    function(row) {
            
            
    for(var cell=0; cell<row.cells.length; cell++) {
                RINDEX.Utility.addCSS(row.cells[cell], 
    'selected');
            }
            
        },
        
        _clearSelectStyle : 
    function(row) {
            
            
    for(var cell=0; cell<row.cells.length; cell++) {
                RINDEX.Utility.removeCSS(row.cells[cell], 
    'selected');
            }
            
        },
        
        _clearAllSelection : 
    function() {
            
    for(var i=0; i<this.selectedRows.length; i++) {
                
    this._clearSelectStyle(this.selectedRows[i]);
            }
            
    this.selectedRows.length = 0;
        },

      toString : 
    function() {
        
    return '[ClientTable]';
      }

    };

    grid.css

    .editTable {
        border-collapse
    :collapse;
        cursor
    : default;
        width
    : 100%;
        empty-cells
    : show;
    }

    .editTable th,
    .editTable td 
    {
        font-size
    : 12px;
        padding
    : 3px 5px;
    }

    .editTable th 
    {
        text-align
    : left;
        font-weight
    : bold;
        line-height
    : 20px;
        height
    : 20px;
        background-color
    : #f5fafa;
        border-right
    : 1px solid #C1DAD7;
        border-bottom
    : 1px solid #C1DAD7;
        border-left
    : 1px solid #C1DAD7;
        
    /*border-color: #FFF #C1DAD7 #C1DAD7 #FFF;*/
        white-space
    : nowrap;
    }

    .editTable td.item-0,
    .editTable td.item-1 
    {
        border-bottom
    : 1px solid #ccc;
        
    /*text-align: left;*/
    }

    .editTable td.item-0 
    {
        background-color
    : #fff;
        color
    : #555;
        empty-cells
    : show;
        font-family
    : "Lucida Sans Unicode", "Lucida Sans",  "Trebuchet MS", Verdana, Tahoma;
    }

    .editTable td.item-1 
    {
        background-color
    : #F5FAFA;
        color
    : #555;
        empty-cells
    : show;
        font-family
    :  "Lucida Sans Unicode", "Lucida Sans",  "Trebuchet MS", Verdana, Tahoma;
    }

    .editTable td.selected 
    {
        color
    : #fff;
        background-color
    : #ff8c00;
    }

    table tr.tfooter
    {
        background-color
    : ButtonFace;
        border
    : 1px solid;
        border-color
    : buttonhighlight buttonshadow buttonshadow buttonhighlight;
    }

    table tr.tfooter td 
    {
        text-align
    : right;
    }
  • 相关阅读:
    Windows安装nginx服务
    高血压食谱 芹菜苦瓜可以降压吗
    非IT,零经验,零基础怎么备考信息系统项目管理师/高项考试?
    为什么要用urlencode()函数进行url编码
    Redis哨兵机制
    Qt 自定义QToolButton 自己互斥同时工具按钮之间实现互斥
    QItemSelectionModel获取QModelIndexList程序崩溃
    Qt QListView scrollTo定位指定项 和 LayoutMode布局的简单用法
    Sublime Text3 离线安装中文插件
    VSCODE导出PDF的数学公式
  • 原文地址:https://www.cnblogs.com/wfyfngu/p/1381923.html
Copyright © 2020-2023  润新知