handsontable合并表头

想在页面中做类似excel的操作,发现handsontable符合要求。

然后发现这个文章

http://blog.csdn.net/wynan830/article/details/9054195

该作者扩展了handsontable实现了多表头。

发现原作者链接失效了,handsontable.removeRow.js

(function (Handsontable) {
  "use strict";
  /**
   * Handsontable RemoveRow plugin. See `demo/buttons.html` for example usage
   * This plugin is not a part of the Handsontable build (to use it, you must load it after loading Handsontable)
   * See `test/removeRowSpec.js` for tests
   */
  function removeRow() {

    var eventManager = Handsontable.eventManager(this);

    function bindMouseEvents() {
      var instance = this;

      eventManager.addEventListener(instance.rootElement, 'mouseover', function (e) {
        if(checkRowHeader(e.target)) {
          var element = getElementFromTargetElement(e.target);
          if (element) {
            var btn = getButton(element);
            if (btn) {
              btn.style.display = 'block';
            }
          }
        }
      });

      eventManager.addEventListener(instance.rootElement, 'mouseout', function (e) {
        if(checkRowHeader(e.target)) {
          var element = getElementFromTargetElement(e.target);
          if (element) {
            var btn = getButton(element);
            if (btn) {
              btn.style.display = 'none';
            }
          }
        }
      });

//      instance.rootElement.on('mouseover.removeRow', 'tbody th, tbody td', function () {
//        getButton(this).show();
//      });
//
//      instance.rootElement.on('mouseout.removeRow', 'tbody th, tbody td', function () {
//        getButton(this).hide();
//      });
    }

    var getElementFromTargetElement = function (element) {
      if (element.tagName != 'TABLE') {
        if (element.tagName == 'TH' || element.tagName == 'TD') {
          return element;
        } else {
          return getElementFromTargetElement(element.parentNode);
        }
      }
      return null;
    };

    var checkRowHeader = function (element) {
      if (element.tagName != 'BODY') {
        if (element.parentNode.tagName == 'TBODY') {
          return true;
        } else {
          element = element.parentNode;
          return checkRowHeader(element);
        }
      }
      return false;
    };

    function unbindMouseEvents() {
      eventManager.clear();
    }

    function getButton(td) {
      var btn = td.querySelector('.btn');

      if (!btn) {
        var parent = td.parentNode.querySelector('th.htRemoveRow');

        if (parent) {
          btn = parent.querySelector('.btn');
        }
      }

      return btn;
    }

    this.init = function () {
      var instance = this;
      var pluginEnabled = !!(instance.getSettings().removeRowPlugin);

      if (pluginEnabled) {
        bindMouseEvents.call(this);
        Handsontable.Dom.addClass(instance.rootElement, 'htRemoveRow');
      } else {
        unbindMouseEvents.call(this);
        Handsontable.Dom.removeClass(instance.rootElement, 'htRemoveRow');
      }
    };

    this.beforeInitWalkontable = function (walkontableConfig) {
      var instance = this;

      /**
       * rowHeaders is a function, so to alter the actual value we need to alter the result returned by this function
       */
      var baseRowHeaders = walkontableConfig.rowHeaders;
      walkontableConfig.rowHeaders = function () {

        var pluginEnabled = !!(instance.getSettings().removeRowPlugin);

        var newRowHeader = function (row, elem) {
          var child
            , div;

          while (child = elem.lastChild) {
            elem.removeChild(child);
          }
          elem.className = 'htNoFrame htRemoveRow';
          if (row > -1) {
            div = document.createElement('div');
            div.className = 'btn';
            div.appendChild(document.createTextNode('x'));
            elem.appendChild(div);

            eventManager.addEventListener(div, 'mouseup', function () {
              instance.alter('remove_row', row);
            });
          }
        };

        return pluginEnabled ? Array.prototype.concat.call([], newRowHeader, baseRowHeaders()) : baseRowHeaders();
      };
    }
  }

  var htRemoveRow = new removeRow();

  Handsontable.hooks.add('beforeInitWalkontable', function (walkontableConfig) {
    htRemoveRow.beforeInitWalkontable.call(this, walkontableConfig);
  });

  Handsontable.hooks.add('beforeInit', function () {
    htRemoveRow.init.call(this)
  });

  Handsontable.hooks.add('afterUpdateSettings', function () {
    htRemoveRow.init.call(this)
  });

})(Handsontable);

handsontable.removeRow.css

/**
 * Handsontable RemoveRow extension. See `demo/buttons.html` for example usage
 */
.handsontable.htRemoveRow th.htRemoveRow {
  text-align: center;
}

.handsontable.htRemoveRow th.htRemoveRow .btn {
  background-color: #BBB;
  border-radius: 9px;
  padding: 0 6px 0 6px;
  color: #FFF;
  cursor: pointer;
  font-size: 11px;
  font-weight: bold;
  display: none;
  margin: 0 auto;
  width: 10px;
}

.handsontable.htRemoveRow th.htRemoveRow .btn:hover {
  background-color: #777;
}

  

同时添加了removeRowPlugin属性,作用是在每行前面显示一个删除按钮执行删除操作。

我的页面中不需要删除,因此把removeRowPlugin设置为false。但是表头出现了错行。

查看生成的html发现,表头中多了一列:<th class="htNoFrame htRemoveRow"></th>。

在css中添加

.handsontable th.htNoFrame.htRemoveRow {
width:0px
}

不起作用。PS:我添加的这个CSS写法是不是有问题?

在jquery.handsontable.js里原作者添加了treeToth函数,处理多表头

原代码为:

datastr += '<tr>';
 datastr += '<th class="htNoFrame htRemoveRow"></th>';
 datastr += '<th ></th>';

可见没有判断是否需要显示删除按钮列

修改为:

datastr += '<tr>';
if (userSettings.removeRowPlugin != null && userSettings.removeRowPlugin) {
       datastr += '<th class="htNoFrame htRemoveRow"></th>';
   }
datastr += '<th ></th>';

 

posted @ 2015-10-18 00:32  darksied  阅读(5452)  评论(2编辑  收藏  举报