发表于 2017-2-3 13:58

申请会员ID:renwuqiangg【申请通过】

1、申 请 I D :renwuqiangg2、个人邮箱:renwuqiangg@126.com
我自己写的mulselect-grid插件,是插件是基于extjs3的。可以实现的功能是对grid进行多选(可配合ctrl和shift),拖拽多选,点击标题行或第一列选择一列或一行,就像execl那样。并可以按ctrl+c复制到建贴板(仅支持ie)。
Ext.ns('Ext.rr.grid');
Ext.rr.grid.MultiCellSelectionModel = Ext.extend(Ext.grid.CellSelectionModel, {

    selections : [], // 选择区缓存

    constructor : function() {
      Ext.rr.grid.MultiCellSelectionModel.superclass.constructor.call(this);
    },
    initEvents : function() {
      Ext.rr.grid.MultiCellSelectionModel.superclass.initEvents.call(this);   
    },

    // 根据行列以及是否按住Ctrl键或者shift键,执行多选操作的逻辑
    handleMouseDown : function(grid, row, col, event) {
      if(event.button !== 0 || this.isLocked())
            return;
      
      if(event.shiftKey&&this.selection!=null){
                if(col == 0){
                        var r1 = Math.min(this.selection.cell,row);
                        var r2 = Math.max(this.selection.cell,row);
                        if(!event.ctrlKey)
                                        this.clearAllSelections();
                        for (var i = r1; i < r2+1; i++) {
                              this.selectRow(i,true);
                        }
                }else{
                        this.selectMatrix(row, col, event.ctrlKey);
                }
      }else{               
                if(this.selection!=null&&this.selections]]){
                        var tmp = ,this.selection.cell];
                            this.select(row,col);
                            if(event.ctrlKey){
                                    //选了新的cell且按住ctrl的话,上一个cell虽然的选中状态,但是【选中】样式会被清除,这里把样式补回来
                                    this.grid.getView().onCellSelect(tmp, tmp);
                            }
                }else
                        this.select(row,col);
                if(col == 0)
                        this.selectRow(row,event.ctrlKey);
                else
                        this.selectCell(row, col, event.ctrlKey);            
      }
    },
    handleKeyDown : function(e){
      var key = e.getKey(),
      g = this.grid,
      v = g.getView(),
      selections = this.selections,
      sm = this;
      // Ctrl+c
      if(e.ctrlKey&&key==67){
                var row_flag = [];//未选的行index
                var col_flag = [];//未选的列index
                for (var i = 0; i < selections.length; i++) {
                        if(selections==null){
                              row_flag = 0;
                              continue;
                        }
                        var flag = false;
                        for (var j = 0; j < selections.length; j++) {
                              if(selections==1){
                                        flag = true;
                                        break;
                              }
                        }
                        if(!flag)
                              row_flag = 0;
                }
                for (var i = 0; i < g.getColumnModel().getColumnCount(); i++) {
                        var flag = false;
                        for (var r = 0; r < selections.length; r++) {
                              if(selections==null){
                                        continue;
                              }else if(selections==1){
                                        flag = true;
                                        break;
                              }
                        }
                        if(!flag)
                              col_flag = 0;
                }
                var str = "";
                for ( var i = 0; i < selections.length; i++) {                     
                        if(selections==null||row_flag==0) continue;
                        for ( var j = 0; j < selections.length; j++) {
                              if(selections==1){
                                        str+=v.getCell(i,j).firstChild.innerText;
                              }
                              if(j<selections.length-1&&col_flag!=0){
                                        str+="\t";
                              }
                        }
                        str+="\r\n";
                        }
                var clipboard = window.clipboardData;
                var i=0;
                copyStr = function (){
                        clipboard.clearData();
                        clipboard.setData("Text",str);
                        
                        if(++i>10) return;
                        var text = clipboard.getData('Text');
                        if(text!=null) return;
                        setTimeout("copyStr()",20);
                }
                copyStr(str);
      }
    },
    // 清楚选择区内所以单元格被选中的样式
    clearAllSelections : function(){   
      for(var i = 0; i < this.selections.length; i++){
                if(this.selections==null) continue;
                for ( var j = 0; j < this.selections.length; j++) {
                              if(this.selections==1){
                                        this.grid.view.onCellDeselect(i, j); // GridView的内置方法,改变某单元格样式
                              }
                        }
      }
      this.selections = [];
    },
    // 选中某个单元格
    selectCell : function(rowIndex, colIndex, keepExisting){
      if(!keepExisting)
            this.clearAllSelections();
      if(this.selections==null){
                this.selections = [];
      }
      if(this.selections == 1){
                this.grid.view.onCellDeselect(rowIndex, colIndex);// 调用父类的方法,去掉【选中】样式
                this.selections = 0;
               
      }else{
                this.grid.getView().onCellSelect(rowIndex, colIndex);// 调用父类的方法,增加 【选中】样式
                this.selections = 1;
      }
    },
    // 选中某一行
    selectRow : function(rowIndex, keepExisting){
      var clen = this.grid.getColumnModel().getColumnCount();
      if(!keepExisting)// 是否清空所有已选择的单元格
            this.clearAllSelections();
      for(var c = 0; c < clen; c++){
            this.selectCell(rowIndex, c, true);
      }
    },
    selectCol: function(colIndex, event){
            if(!event.ctrlKey)
                  this.clearAllSelections();
                  
            if(event.shiftKey && this.selection!=null){
                  var c1 = Math.min(colIndex,this.selection.cell);
                  var c2 = Math.max(colIndex,this.selection.cell);
                  for ( var i = 0; i < this.grid.getStore().getCount(); i++) {
                              for ( var j = c1; j < c2+1; j++) {
                                        this.selectCell(i, j, true);
                              }
                        }
            }else{                  
                  if(this.selection!=null){
                        var tmp = ,this.selection.cell];
                            this.select(0,colIndex);
                            if(event.ctrlKey){
                                    //选了新的cell且按住ctrl的话,上一个cell虽然的选中状态,但是【选中】样式会被清除,这里把样式补回来
                                    this.grid.getView().onCellSelect(tmp, tmp);
                            }
                }else{
                        this.select(0,colIndex);
                }
                  for(var i = 0;i < this.grid.getStore().getCount(); i++){
                            this.selectCell(i, colIndex, true);
                  }
            }
    },
    // 选中矩形区域内所有的单元格,以上一次被选择的单元格或者cell为起点,
    selectMatrix : function(row, col, keepExisting,cell){
            cell=cell||this.selection.cell;
      if(!keepExisting)
            this.clearAllSelections();

            var r1 = Math.min(row,cell);
            var r2 = Math.max(row,cell);
            var c1 = Math.min(col,cell);
            var c2 = Math.max(col,cell);
            
            for ( var i = r1; i < r2+1; i++) {
                  for ( var j = c1; j < c2+1; j++) {                              
                        this.selectCell(i,j,true);
                        }
                }
    }

});
Ext.rr.grid.MulSelectCommonGrid = Ext.extend(Ext.rr.grid.DynamicGridPanel,{
      pageSize:20,
      storeCfg:{},
      dataUrl:null,      
      columns : [],
      forceFitColumn : true,
      initComponent:function(){
                Ext.applyIf(this.storeCfg,{
                        xtype:'groupingstore',
                        url:this.dataUrl || this.storeUrl||this.url,
                        autoDestroy: true,
                        groupDir : this.groupDir ? this.groupDir : "ASC",
                        reader : new Ext.data.JsonReaderEx(),
                        baseParams : this.baseParams ? this.baseParams : {}
                });
                var store = this.store || Ext.create(this.storeCfg);
                delete this.storeCfg;
                this.plugins.push(this.summaryPlugin||new Ext.ux.grid.GroupSummary());
                Ext.apply(this,{
                        store:store,
                        // sm: this.checkboxSelModel || new
                        // Ext.grid.RowSelectionModel({singleSelect:true}),
                        sm:new Ext.rr.grid.MultiCellSelectionModel(),
                        pageSize:this.pageSize || this.limit,
                        bbar:new Ext.PagingToolbar({
                        pageSize: this.pageSize || this.limit,
                        store: store,
                        displayInfo: true,
                        displayMsg : "第{0}条到{1}条,共{2}条",
                        emptyMsg:"没有记录",
                        plugins : new Ext.ux.PagingToolbar.PageCount(),
                        items:['-',{
                              text : '过滤配置',
                              menu : {
                                        items:[{
                                                text:'自动过滤:打开',
                                                enableToggle: true,
                                                handler:this.setAutoFilter,
                                                      scope:this
                                        },'-',{
                                                      text:'本地过滤:关闭' ,
                                                      enableToggle: true,
                                                      handler: this.setLocalFilter,
                                                      scope : this
                                                },'-',{
                                          text: '查看过滤条件',
                                          tooltip: '查看所有的过滤条件',
                                          handler: this.filterCondition,
                                          scope : this
                                        },'-',{
                                          text: '清除过滤条件',
                                          tooltip: '清除所有的过滤条件',
                                          handler: this.clearfilter,
                                          scope : this
                                        },'-',{
                                                text:'进行过滤',
                                                handler:this._doFilter,
                                                scope:this
                                        }]                              
                              }
                        },'-',{
                              text : '分组配置',
                              menu : {
                                        items:[{
                                                      text:'远程分组:关闭',
                                                      enableToggle: true,
                                                      handler:this.setRemoteGroup,
                                                      scope:this
                                                },'-',{
                                                      text:'分组方向:升序',
                                                      handler:this.setGroupDir,
                                                      scope:this
                                                },'-',{
                                                      text:'清除分组',
                                                      handler:this.clearGroup,
                                                      scope:this
                                                }]
                              }
                        },'-',{
                                        text:'远程排序:关闭',
                                        enableToggle: true,
                                        handler:this.setRemoteSort,
                                        scope:this
                              }]
                  }),
                        view: this.view || new Ext.grid.GroupingView({
                              hideGroupedColumn : true,
                  forceFit: this.forceFitColumn,
                  groupByText:"按这个字段分组",
                  showGroupsText:"通过分组显示"
                }),
                loadMask : {msg:"数据加载中..."}
                });
                Ext.rr.grid.MulSelectCommonGrid.superclass.initComponent.apply(this, arguments);
                this.on("headerclick", function(grid,columnIndex, e ) {
            grid.getSelectionModel().selectCol(columnIndex,e);               
            return false;
      });
                var isDown = false;
                var lastXY = [];
                var nearestCell = null;//最近的
                this.on("mousedown", function(e ) {
                        isDown = true;
                        lastXY = e.getXY();
      });
                this.on("mouseup", function(e ) {
                        isDown = false;
                        nearestCell = null;
                });
                this.on("mouseover", function(e ) {
                        if(isDown){
                              var col = 0;
                              var row = 0;
                              var view = this.getView();
                              
                              for (; col < this.getColumnModel().config.length; col++) {
                                        var div = view.getCell(0,col).firstChild;
                                        var x = div.getBoundingClientRect().right;
                                        if(x>e.getXY()){
                                                break;
                                        }
                              }
                              for (; row < this.getStore().getCount(); row++) {
                                        var div = view.getCell(row,0).firstChild;
                                        var y = div.getBoundingClientRect().bottom;
                                        if(y>e.getXY()){
                                                break;
                                        }
                              }
                              if(nearestCell==null){
                                        nearestCell = ,this.getSelectionModel().selection.cell];
                              }
                              if(nearestCell!=row||nearestCell!=col){
                                        if(e.ctrlKey){
                                                this.getSelectionModel().selectMatrix(nearestCell,nearestCell,true);
                                                this.getSelectionModel().selectMatrix(row,col,true);
                                        }else{
                                                this.getSelectionModel().selectMatrix(nearestCell,nearestCell,false);
                                                this.getSelectionModel().selectMatrix(row,col,false);
                                        }
                                        nearestCell = ;
                              }
                              
                        }
                });
      },
      setRemoteGroup:function(button,state){
                var store = this.store;
                var sortLocal = store.remoteGroup = !store.remoteGroup;
                var text = '远程分组:' + (sortLocal ? '打开' : '关闭');
                button.setText(text);
                store.lastOptions.params["start"] = 0;
                store.applyGroupField();
                if(!sortLocal){
                        if(store.baseParams){
                delete store.baseParams.groupBy;
                delete store.baseParams.groupDir;
            }
            var lo = store.lastOptions;
            if(lo && lo.params){
                delete lo.params.groupBy;
                delete lo.params.groupDir;
            }
                }
                store.reload();
      },
      setGroupDir:function(button,state){
                var store = this.store;
                store.groupDir = store.groupDir == "ASC" ? "DESC" : "ASC";
                var text = '分组方向:' + (store.groupDir == "ASC" ? '升序' : '降序');
                button.setText(text);
                if(store.remoteGroup){
                        store.lastOptions.params.groupDir = store.groupDir;
                        store.reload();
                        store.sort();
                }else{
                        store.sort();
                        store.fireEvent('datachanged', store);
                }
      },
      clearGroup:function(){
               this.store.clearGrouping();
      },
      setRemoteSort:function(button, state){
                var store = this.store;
                var sortLocal = store.remoteSort = !store.remoteSort;
                var text = '远程排序:' + (sortLocal ? '打开' : '关闭');
                button.setText(text);
                store.hasMultiSort = true;
                store.lastOptions.params["start"] = 0;
                store.reload();
      },
      setAutoFilter:function(button, state){
                var filterPlugin = this.filters;
                var autoFilter = filterPlugin.autoReload = !filterPlugin.autoReload;
                var text = '自动过滤:' + (autoFilter ? '打开' : '关闭');
                button.setText(text);
      },
      setLocalFilter:function(button,state){
                var filterPlugin = this.filters;
                var local = filterPlugin.local = !filterPlugin.local;
      var text = '本地过滤:' + (local ? '打开' : '关闭');
      filterPlugin.bindStore(this.getStore());
      button.setText(text);
      this.getStore().reload();
      },
      filterCondition:function(){
            var _filterData = this.filters.getFilterData();
            var comparisons = {'gt':'大于','lt':'小于','eq':'等于'};
            var cm = this.getColumnModel();
            var _s = "";
            var v ;
            Ext.each(_filterData,function(obj){
                  var cson = obj.data.comparison ? comparisons : '';
                  if(obj.data.type=='list'){
                            v = cson+obj.data.text;
                  }else{
                            v = cson+obj.data.value;
                  }
                  _s += cm.getColumnHeader(cm.findColumnIndex(obj.field))+":"+v+"<br/>"
            });
      Ext.Msg.alert('过滤条件',_s);
      },
      clearfilter:function(){
            var filterPlugin = this.filters;
      filterPlugin.clearFilters();
      if(!filterPlugin.autoReload)
                filterPlugin.deferredUpdate.delay(filterPlugin.updateBuffer);
      },
      _doFilter:function(){
                   var filterPlugin = this.filters;
                filterPlugin.deferredUpdate.delay(filterPlugin.updateBuffer);
      }
});

Ext.reg('mulselectcommongrid',Ext.rr.grid.MulSelectCommonGrid);
使用方法:将你项目中的xtype:grid改为xtype:mulselectcommongrid即可

Hmily 发表于 2017-2-6 15:35

这个我看不懂,解说一下?

LzSkyline 发表于 2017-2-7 10:58

楼主写的是基于extjs这个前端库开发的一款 支持多选行的前端表格组件,自写了一个控件模块

Hmily 发表于 2017-2-7 11:44

LzSkyline 发表于 2017-2-7 10:58
楼主写的是基于extjs这个前端库开发的一款 支持多选行的前端表格组件,自写了一个控件模块

质量如何?

LzSkyline 发表于 2017-2-7 16:04

Hmily 发表于 2017-2-7 11:44
质量如何?

我没有用过extjs, 不知道代码中那些是官网或社区的示例, 如果这些全是LZ写的话还是比较有水平的

Hmily 发表于 2017-2-7 16:14

ID:renwuqiangg
邮箱:renwuqiangg@126.com

申请通过,欢迎光临吾爱破解论坛,期待吾爱破解有你更加精彩,ID和密码自己通过邮件密码找回功能修改,请即时登陆并修改密码!
登陆后请在一周内在此帖报道,否则将删除ID信息。

ps:登录后请把文章整理发布到编程区吧。

renwuqiangg 发表于 2017-2-9 13:29

Hmily 发表于 2017-2-7 16:14
ID:renwuqiangg
邮箱:



报道!
这些代码的确是我自己写的,当时公司有这个需求,我找了好多地方都没有现成的,就自己写了个插件。
水平并不高,但我会努力的~
页: [1]
查看完整版本: 申请会员ID:renwuqiangg【申请通过】