dojox/grid/enhanced/plugins/CellMerge.js

  • Provides:

    • dojox.grid.enhanced.plugins.CellMerge
  • Requires:

    • dojox.grid.enhanced._Plugin in common
  • dojox.grid.enhanced.plugins.CellMerge

    • type
      Function
    • chains:
      • dojox.grid.enhanced._Plugin: (prototype)
      • dojox.grid.enhanced._Plugin: (call)
    • summary
      This plugin provides functions to merge(un-merge) adjacent cells within one row.
      Acceptable plugin paramters:
      1. mergedCells: Array
      An array of objects with structure:
      {
      row: function(Integer)|Integer
      If it's a function, it's a predicate to decide which rows are to be merged.
      It takes an integer (the row index), and should return true or false;
      start: Integer
      The column index of the left most cell that shall be merged.
      end: Integer
      The column index of the right most cell that shall be merged.
      major: Integer
      The column index of the cell whose content should be used as the content of the merged cell.
      It must be larger than or equal to the startColumnIndex, and less than or equal to the endColumnIndex.
      If it is omitted, the content of the leading edge (left-most for ltr, right most for rtl) cell will be used.
      }
    • parameters:
      • grid: (typeof )
      • args: (typeof )
    • source: [view]
        this.grid = grid;
        this._records = [];
        this._merged = {};
        if(args && dojo.isObject(args)){
         this._setupConfig(args.mergedCells);
        }
        this._initEvents();
        this._mixinGrid();
  • dojox.grid.enhanced.plugins.CellMerge.name

    • type
      String
    • summary
      Plugin name
  • dojox.grid.enhanced.plugins.CellMerge.mergeCells

    • type
      Function
    • parameters:
      • rowTester: (typeof function(Integer)|Integer)
        If it's a function, it's a predicate to decide which rows are to be merged.
        It takes an integer (the row index), and should return true or false;
      • startColumnIndex: (typeof Integer)
        The column index of the left most cell that shall be merged.
      • endColumnIndex: (typeof Integer)
        The column index of the right most cell that shall be merged.
      • majorColumnIndex: (typeof Integer)
        The column index of the cell whose content should be used as the content of the merged cell.
        It must be larger than or equal to the startColumnIndex, and less than or equal to the endColumnIndex.
        If it is omitted, the content of the leading edge (left-most for ltr, right most for rtl) cell will be used.
        return: Object | null
        A handler for the merged cells created by a call of this function.
        This handler can be used later to unmerge cells using the function unmergeCells
        If the merge is not valid, returns null;
    • source: [view]
        var item = this._createRecord({
         "row": rowTester,
         "start": startColumnIndex,
         "end": endColumnIndex,
         "major": majorColumnIndex
        });
        if(item){
         this._updateRows(item);
        }
        return item;
    • summary
      Merge cells from *startColumnIndex* to *endColumnIndex* at rows that make *rowTester* return true,
      using the content of the cell at *majorColumnIndex*
    • tags:
  • dojox.grid.enhanced.plugins.CellMerge.unmergeCells

    • type
      Function
    • parameters:
      • mergeHandler: (typeof object)
        A handler for the merged cells created by a call of function mergeCells.
    • source: [view]
        var idx;
        if(mergeHandler && (idx = dojo.indexOf(this._records, mergeHandler)) >= 0){
         this._records.splice(idx, 1);
         this._updateRows(mergeHandler);
        }
    • summary
      Unmerge the cells that are merged by the *mergeHandler*, which represents a call to the function mergeCells.
    • tags:
  • dojox.grid.enhanced.plugins.CellMerge.getMergedCells

    • type
      Function
    • source: [view]
        var res = [];
        for(var i in this._merged){
         res = res.concat(this._merged[i]);
        }
        return res;
    • summary
      Get all records of currently merged cells.
    • tags:
  • dojox.grid.enhanced.plugins.CellMerge.getMergedCellsByRow

    • type
      Function
    • parameters:
      • rowIndex: (typeof )
    • source: [view]
        return this._merged[rowIndex] || [];
    • summary
      Get the records of currently merged cells at the given row.
    • tags:
  • dojox.grid.enhanced.plugins.CellMerge._setupConfig

    • type
      Function
    • parameters:
      • config: (typeof )
    • source: [view]
        dojo.forEach(config, this._createRecord, this);
    • summary
  • dojox.grid.enhanced.plugins.CellMerge._initEvents

    • type
      Function
    • source: [view]
        dojo.forEach(this.grid.views.views, function(view){
         this.connect(view, "onAfterRow", dojo.hitch(this, "_onAfterRow", view.index));
        }, this);
    • summary
  • dojox.grid.enhanced.plugins.CellMerge._mixinGrid

    • type
      Function
    • source: [view]
        var g = this.grid;
        g.mergeCells = dojo.hitch(this, "mergeCells");
        g.unmergeCells = dojo.hitch(this, "unmergeCells");
        g.getMergedCells = dojo.hitch(this, "getMergedCells");
        g.getMergedCellsByRow = dojo.hitch(this, "getMergedCellsByRow");
    • summary
  • dojox.grid.enhanced.plugins.CellMerge._getWidth

    • type
      Function
    • parameters:
      • colIndex: (typeof )
    • source: [view]
        var node = this.grid.layout.cells[colIndex].getHeaderNode();
        return dojo.position(node).w;
    • summary
  • dojox.grid.enhanced.plugins.CellMerge._onAfterRow

    • type
      Function
    • parameters:
      • viewIdx: (typeof )
      • rowIndex: (typeof )
      • subrows: (typeof )
    • source: [view]
        try{
         if(rowIndex < 0){
          return;
         }
         var result = [], i, j, len = this._records.length,
          cells = this.grid.layout.cells;
         //Apply merge-cell requests one by one.
         for(i = 0; i < len; ++i){
          var item = this._records[i];
          var storeItem = this.grid._by_idx[rowIndex];
          if(item.view == viewIdx && item.row(rowIndex, storeItem && storeItem.item, this.grid.store)){
           var res = {
            record: item,
            hiddenCells: [],
            totalWidth: 0,
            majorNode: cells[item.major].getNode(rowIndex),
            majorHeaderNode: cells[item.major].getHeaderNode()
           };
           //Calculated the width of merged cell.
           for(j = item.start; j <= item.end; ++j){
            var w = this._getWidth(j, rowIndex);
            res.totalWidth += w;
            if(j != item.major){
             res.hiddenCells.push(cells[j].getNode(rowIndex));
            }
           }
           //If width is valid, remember it. There may be multiple merges within one row.
           if(subrows.length != 1 || res.totalWidth > 0){
            //Remove conflicted merges.
            for(j = result.length - 1; j >= 0; --j){
             var r = result[j].record;
             if((r.start >= item.start && r.start <= item.end) ||
              (r.end >= item.start && r.end <= item.end)){
              result.splice(j, 1);
             }
            }
            result.push(res);
           }
          }
         }
         this._merged[rowIndex] = [];
         dojo.forEach(result, function(res){
          dojo.forEach(res.hiddenCells, function(node){
           dojo.style(node, "display", "none");
          });
          var pbm = dojo.marginBox(res.majorHeaderNode).w - dojo.contentBox(res.majorHeaderNode).w;
          var tw = res.totalWidth;

          
          //Tricky for WebKit.
          if(!dojo.isWebKit){
           tw -= pbm;
          }

          
          dojo.style(res.majorNode, "width", tw + "px");
          //In case we're dealing with multiple subrows.
          dojo.attr(res.majorNode, "colspan", res.hiddenCells.length + 1);

       
          this._merged[rowIndex].push({
           "row": rowIndex,
           "start": res.record.start,
           "end": res.record.end,
           "major": res.record.major,
           "handle": res.record
          });
         }, this);
        }catch(e){
         console.warn("CellMerge._onAfterRow() error: ", rowIndex, e);
        }
    • summary
  • dojox.grid.enhanced.plugins.CellMerge._createRecord

    • type
      Function
    • parameters:
      • item: (typeof )
    • source: [view]
        if(this._isValid(item)){
         item = {
          "row": item.row,
          "start": item.start,
          "end": item.end,
          "major": item.major
         };
         var cells = this.grid.layout.cells;
         item.view = cells[item.start].view.index;
         item.major = typeof item.major == "number" && !isNaN(item.major) ? item.major : item.start;
         if(typeof item.row == "number"){
          var r = item.row;
          item.row = function(rowIndex){
           return rowIndex === r;
          };
         }else if(typeof item.row == "string"){
          var id = item.row;
          item.row = function(rowIndex, storeItem, store){
           try{
            if(store && storeItem && store.getFeatures()['dojo.data.api.Identity']){
             return store.getIdentity(storeItem) == id;
            }
           }catch(e){
            console.error(e);
           }
           return false;
          };
         }
         if(dojo.isFunction(item.row)){
          this._records.push(item);
          return item;
         }
        }
        return null;
    • summary
  • dojox.grid.enhanced.plugins.CellMerge._isValid

    • type
      Function
    • parameters:
      • item: (typeof )
    • source: [view]
        var cells = this.grid.layout.cells,
         colCount = cells.length;
        return (dojo.isObject(item) && ("row" in item) && ("start" in item) && ("end" in item) &&
         item.start >= 0 && item.start < colCount &&
         item.end > item.start && item.end < colCount &&
         cells[item.start].view.index == cells[item.end].view.index &&
         cells[item.start].subrow == cells[item.end].subrow &&
         !(typeof item.major == "number" && (item.major < item.start || item.major > item.end)));
    • summary
  • dojox.grid.enhanced.plugins.CellMerge._updateRows

    • type
      Function
    • parameters:
      • item: (typeof )
    • source: [view]
        var min = null;
        for(var i = 0, count = this.grid.rowCount; i < count; ++i){
         var storeItem = this.grid._by_idx[i];
         if(storeItem && item.row(i, storeItem && storeItem.item, this.grid.store)){
          this.grid.views.updateRow(i);
          if(min === null){ min = i; }
         }
        }
        if(min >= 0){
         this.grid.scroller.rowHeightChanged(min);
        }
    • summary
  • dojox.grid.enhanced.plugins.CellMerge.grid

    • summary
  • dojox.grid.enhanced.plugins.CellMerge._records

    • summary
  • dojox.grid.enhanced.plugins.CellMerge._merged

    • summary
  • dojox.grid.enhanced.plugins

    • type
      Object
    • summary
  • dojox.grid.enhanced

    • type
      Object
    • summary
  • dojox.grid

    • type
      Object
    • summary
  • dojox

    • type
      Object
    • summary