[Kimchi-devel] [PATCH 1/2] Issue#364: UI - Column Resizing Function Broken in Host Tab

Aline Manera alinefm at linux.vnet.ibm.com
Mon Apr 14 18:26:21 UTC 2014


On 04/14/2014 08:00 AM, Hongliang Wang wrote:
> It doesn't work when resizing columns in a page containing multiple
> Grid instances.
>    Fix it in this patch.
>
> Signed-off-by: Hongliang Wang <hlwang at linux.vnet.ibm.com>
> ---
>   ui/js/src/kimchi.grid.js | 879 +++++++++++++++++++++++++----------------------
>   1 file changed, 462 insertions(+), 417 deletions(-)
>
> diff --git a/ui/js/src/kimchi.grid.js b/ui/js/src/kimchi.grid.js
> index 5f94e79..e2cefcf 100644
> --- a/ui/js/src/kimchi.grid.js
> +++ b/ui/js/src/kimchi.grid.js
> @@ -1,220 +1,444 @@
> -/*
> - * Project Kimchi
> - *
> - * Copyright IBM, Corp. 2013
> - *
> - * Licensed under the Apache License, Version 2.0 (the "License");
> - * you may not use this file except in compliance with the License.
> - * You may obtain a copy of the License at
> - *
> - *     http://www.apache.org/licenses/LICENSE-2.0
> - *
> - * Unless required by applicable law or agreed to in writing, software
> - * distributed under the License is distributed on an "AS IS" BASIS,
> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> - * See the License for the specific language governing permissions and
> - * limitations under the License.
> - */

The license header should not be removed.

> -kimchi.widget.Grid = function(params) {
> -    var containerID = params['container'];
> -    var container = $('#' + containerID);
> -    var gridID = params['id'];
> -    var rowSelection = params['rowSelection'] || 'single';
> -    var rowListener = params['onRowSelected'];
> -    var htmlStr = [
> -      '<div id="', gridID, '" class="grid">',
> -        '<div class="grid-content">',
> -          '<div class="grid-header">',
> -            '<div class="grid-frozen-header-view">',
> -              '<table class="grid-frozen-header-container">',
> +kimchi.widget.Grid = function(opts) {
> +  this.opts = $.extend({}, this.opts, opts);
> +  this.createDOM();
> +  this.reload();
> +};
> +
> +kimchi.widget.Grid.prototype = (function() {
> +  var htmlStr = [
> +    '<div id="{id}" class="grid">',
> +      '<div class="grid-content">',
> +        '<div class="grid-header">',
> +          '<div class="grid-frozen-header-view">',
> +            '<table class="grid-frozen-header-container">',
> +            '</table>',
> +          '</div>',
> +          '<div class="grid-header-view">',
> +            '<div class="grid-header-wrapper">',
> +              '<table class="grid-header-container">',
>                 '</table>',
>               '</div>',
> -            '<div class="grid-header-view">',
> -              '<div class="grid-header-wrapper">',
> -                '<table class="grid-header-container">',
> -                '</table>',
> -              '</div>',
> -            '</div>',
>             '</div>',
> -          '<div class="grid-body">',
> -            '<div class="grid-frozen-body-view">',
> -              '<div class="grid-frozen-body-wrapper">',
> -                '<table class="grid-frozen-body-container">',
> -                '</table>',
> -              '</div>',
> -            '</div>',
> -            '<div class="grid-body-view">',
> -              '<div class="grid-body-wrapper">',
> -                '<table class="grid-body-container">',
> -                '</table>',
> -              '</div>',
> +        '</div>',
> +        '<div class="grid-body">',
> +          '<div class="grid-frozen-body-view">',
> +            '<div class="grid-frozen-body-wrapper">',
> +              '<table class="grid-frozen-body-container">',
> +              '</table>',
>               '</div>',
>             '</div>',
> -          '<div class="grid-resizer-leftmost hidden"></div>',
> -          '<div class="grid-resizer hidden"></div>',
> -        '</div>',
> -        '<div class="grid-footer"></div>',
> -        '<div class="grid-mask hidden">',
> -            '<div class="grid-loading">',
> -                '<div class="grid-loading-icon"></div>',
> -                '<div class="grid-loading-text">',
> -                    i18n['KCHGRD6001M'],
> -                '</div>',
> +          '<div class="grid-body-view">',
> +            '<div class="grid-body-wrapper">',
> +              '<table class="grid-body-container">',
> +              '</table>',
>               '</div>',
> -        '</div>',
> -        '<div class="grid-message hidden">',
> -          '<div class="grid-message-text">',
> -            i18n['KCHGRD6002M'],
> -            '<button class="retry-button btn-small">',
> -              i18n['KCHGRD6003M'],
> -            '</button>',
>             '</div>',
> -          '<div class="detailed-title">',
> -            i18n['KCHGRD6004M'],
> +        '</div>',
> +        '<div class="grid-resizer-leftmost hidden"></div>',
> +        '<div class="grid-resizer hidden"></div>',
> +      '</div>',
> +      '<div class="grid-footer"></div>',
> +      '<div class="grid-mask hidden">',
> +          '<div class="grid-loading">',
> +              '<div class="grid-loading-icon"></div>',
> +              '<div class="grid-loading-text">',
> +                '{loading}',
> +              '</div>',
>             '</div>',
> -          '<div class="detailed-text"></div>',
> +      '</div>',
> +      '<div class="grid-message hidden">',
> +        '<div class="grid-message-text">',
> +          '{message}',
> +          '<button class="retry-button btn-small">',
> +            '{buttonLabel}',
> +          '</button>',
> +        '</div>',
> +        '<div class="detailed-title">',
> +          '{detailedLabel}',
>           '</div>',
> -      '</div>'
> -    ];
> +        '<div class="detailed-text"></div>',
> +      '</div>',
> +    '</div>'
> +  ].join('');
> +
> +  var CONTAINER_NORMAL = 0, CONTAINER_FROZEN = 1;
> +
> +  var setupHeaders = function(header, body, fields) {
> +    var colGroup = $('<colgroup></colgroup>').appendTo(header);
> +    var headerHeader = $('<thead></thead>');
> +    var headerRow = $('<tr></tr>').appendTo(headerHeader);
> +    $.each(fields || [], function(i, field) {
> +      $('<col class="' +
> +        field['class'] +
> +      '"/>')
> +        .appendTo(colGroup);
> +      $('<th><div class="cell-text-wrapper">' +
> +        field['label'] +
> +      '</div></th>').appendTo(headerRow);
> +    });
> +    headerHeader.appendTo(header);
> +
> +    var totalWidth = 0;
> +    $('col', colGroup).each(function(index, col) {
> +      var width = $(col).width();
> +      totalWidth += width;
> +      $(col).css('width', width + 'px');
> +    });
> +    $(body).append(colGroup.clone());
> +    return totalWidth;
> +  };
> +
> +  var getValue = function(name, obj) {
> +    var result=undefined;
> +    if(!Array.isArray(name)) {
> +      name=name.parseKey();
> +    }
> +    if(name.length!=0) {
> +      var tmpName=name.shift();
> +      if(obj[tmpName]!=undefined) {
> +          result=obj[tmpName];
> +      }
> +      if(name.length!=0) {
> +          result=getValue(name,obj[tmpName]);
> +      }
> +    }
> +    return(result);
> +  };
> +
> +  var fillBody = function(container, fields) {
> +    var data = this.data;
> +    var tbody = ($('tbody', container).length && $('tbody', container))
> +      || $('<tbody></tbody>').appendTo(container);
> +    tbody.empty();
> +    $.each(data, function(i, row) {
> +      var rowNode = $('<tr></tr>').appendTo(tbody);
> +      $.each(fields, function(fi, field) {
> +        var value = getValue(field['name'], row);
> +        $('<td><div class="cell-text-wrapper"' +
> +          (field['makeTitle'] === true
> +            ? ' title="' + value + '"'
> +            : ''
> +          ) + '>' + value.toString() + '</div></td>'
> +        ).appendTo(rowNode);
> +      });
> +    });
> +  };
> +
> +  var fixTableLayout = function(style) {
> +    $.each([
> +      this.frozenHeaderContainer,
> +      this.headerContainer,
> +      this.frozenBodyContainer,
> +      this.bodyContainer
> +    ], function(i, tableNode) {
> +      $(tableNode).css('table-layout', style || 'fixed');
> +    });
> +  };
> +
> +  var initResizing = function(event) {
> +    var resizer = event.data.resizer;
> +    var pageX = event.pageX;
> +    var tailPos = $(this).width() + $(this).offset()['left'];
> +    var atResizer = Math.abs(pageX - tailPos) <= 2;
> +    var isResizing = !$(resizer).hasClass('hidden');
> +    $('body')[(atResizer || isResizing)
> +      ? 'addClass'
> +      : 'removeClass'
> +    ]('resizing');
> +  };
> +
> +  var clearResizing = function(event) {
> +    $(event.data.resizer).hasClass('hidden') &&
> +      $('body').removeClass('resizing');
> +  };
> +
> +  var stylingRow = function(row, className, add) {
> +    var index = $(row).index() + 1;
> +    $('tr', this.frozenBodyContainer)
> +      .removeClass(className);
> +    $('tr', this.bodyContainer)
> +      .removeClass(className);
> +
> +    if(add === false) {
> +      return;
> +    }
> +
> +    $('tr:nth-child(' + index + ')', this.frozenBodyContainer)
> +      .addClass(className);
> +    $('tr:nth-child(' + index + ')', this.bodyContainer)
> +      .addClass(className);
> +  };
> +
> +  var setBodyListeners = function() {
> +    if(this['opts']['rowSelection'] != 'disabled') {
> +      $('tr', this.gridBody).on('mouseover', {
> +        grid: this
> +      }, function(event) {
> +        stylingRow.call(event.data.grid, this, 'hover');
> +      });
> +
> +      $('tr', this.gridBody).on('mouseout', {
> +        grid: this
> +      }, function(event) {
> +        stylingRow.call(event.data.grid, this, 'hover', false);
> +      });
> +
> +      $('tr', this.gridBody).on('click', {
> +        grid: this
> +      }, function(event) {
> +        var grid = event.data.grid;
> +        grid.selectedIndex = $(this).index();
> +        stylingRow.call(grid, this, 'selected');
> +        grid['opts']['onRowSelected'] && grid['opts']['onRowSelected']();
> +      });
> +    }
> +
> +    $('.grid-body-view', this.domNode).on('scroll', {
> +      grid: this
> +    }, function(event) {
> +      var grid = event.data.grid;
> +      $('.grid-header .grid-header-view', grid.domNode)
> +        .prop('scrollLeft', this.scrollLeft);
> +      $('.grid-body .grid-frozen-body-view', grid.domNode)
> +        .prop('scrollTop', this.scrollTop);
> +    });
> +  };
> +
> +  var setData = function(data) {
> +    this.data = data;
> +    fillBody.call(this, this.frozenBodyContainer, this['opts']['frozenFields']);
> +    fillBody.call(this, this.bodyContainer, this['opts']['fields']);
> +    setBodyListeners.call(this);
> +  };
> +
> +  var getSelected = function() {
> +    return this.selectedIndex >= 0
> +      ? this.data[this.selectedIndex]
> +      : null;
> +  };
> +
> +  var startResizing = function(container, event) {
> +    var grid = event.data.grid;
> +    kimchi.widget.Grid.beingResized = grid;
> +    if(!($('body').hasClass('resizing')
> +        && $(grid.resizer).hasClass('hidden'))) {
> +      return;
> +    }
> +
> +    grid.columnBeingResized = container;
> +    var pageX = event.pageX;
> +    var gridOffsetX = grid.domNode.offset()['left'];
> +    var leftmostOffsetX = $(container).offset()['left'] - gridOffsetX;
> +    var left = pageX - gridOffsetX;
> +    var contentHeight = $('.grid-content', grid.domNode).height();
> +    $(grid.resizerLeftmost).css({
> +      left: leftmostOffsetX + 'px',
> +      height: contentHeight + 'px'
> +    });
> +    $(grid.resizer).css({
> +      left: left + 'px',
> +      height: contentHeight + 'px'
> +    });
> +    $(grid.resizerLeftmost).removeClass('hidden');
> +    $(grid.resizer).removeClass('hidden');
> +    event.preventDefault();
> +  };
> +
> +  var endResizing = function(event) {
> +    var grid = kimchi.widget.Grid.beingResized;
> +    if(!$('body').hasClass('resizing')) {
> +      return;
> +    }
> +    $(grid.resizerLeftmost).addClass('hidden');
> +    $(grid.resizer).addClass('hidden');
> +    $('body').removeClass('resizing');
> +    var leftmostOffset = $(grid.columnBeingResized).offset()['left'];
> +    var left = event.pageX;
> +    if(leftmostOffset > left) {
> +      return;
> +    }
> +    resizeColumnWidth.call(
> +      grid,
> +      $(grid.columnBeingResized).index(),
> +      left - leftmostOffset
> +    );
> +    fixTableLayout.call(grid);
> +    grid.columnBeingResized = null;
> +    kimchi.widget.Grid.beingResized = null;
> +  };
> +
> +  var resizeColumnWidth = function(index, width) {
> +    var width = Math.ceil(width);
> +    var widthArray = [];
> +    var totalWidth = 0;
> +    var header = this.headerContainer;
> +    var body = this.bodyContainer;
> +    if(this.containerBeingResized === CONTAINER_FROZEN) {
> +      header = this.frozenHeaderContainer;
> +      body = this.frozenBodyContainer;
> +    }
> +    $('col', header).each(function(i, colNode) {
> +      var w = index === i ? width : $(colNode).width();
> +      widthArray.push(w);
> +      totalWidth += w;
> +    });
> +    $.each([header, body], function(i, container) {
> +      container.css({
> +        'table-layout': 'fixed',
> +        width: totalWidth + 'px'
> +      });
> +      $('col:nth-child(' + (index + 1) + ')', container).css({
> +        width: width + 'px'
> +      });
> +    });
> +
> +    if(this.containerBeingResized === CONTAINER_FROZEN) {
> +      var headerView = $('.grid-header-view', this.domNode);
> +      var bodyView = $('.grid-body-view', this.domNode);
> +      $.each([headerView, bodyView], function(i, view) {
> +        view.css({
> +          left: totalWidth + 'px'
> +        });
> +      });
> +    }
> +  };
> +
> +  var positionResizer = function(event) {
> +    var grid = event.data.grid;
> +    if($(grid.resizer).hasClass('hidden')) {
> +      return;
> +    }
> +
> +    var pageX = event.pageX;
> +    var gridOffsetX = $(grid.domNode).offset()['left'];
> +    var leftMost = $(grid.resizerLeftmost).position()['left'];
> +    var offsetX = pageX - gridOffsetX;
> +    offsetX = offsetX >= leftMost ? offsetX : leftMost;
> +    $(grid.resizer).css('left', offsetX + 'px');
> +  };
> +
> +  var showMessage = function(msg) {
> +    $('.detailed-text', this.messageNode).text(msg);
> +    $(this.messageNode).removeClass('hidden');
> +  };
> +
> +  var hideMessage = function() {
> +    $(this.messageNode).addClass('hidden');
> +  };
> +
> +  var reload = function() {
> +    var data = this['opts']['data'];
> +    if(!data) {
> +      return;
> +    }
>
> -    var gridNode = $(htmlStr.join(''))
> -        .appendTo(container);
> +    $(this.messageNode).addClass('hidden');
>
> -    var height = gridNode.height();
> -    var width = gridNode.width();
> +    if($.isArray(data)) {
> +      return this.setData(data);
> +    }
> +
> +    if($.isFunction(data)) {
> +      var loadData = data;
> +      $(this.maskNode).removeClass('hidden');
> +      loadData($.proxy(function(data) {
> +        this.setData(data);
> +        $(this.maskNode).addClass('hidden');
> +      }, this));
> +    }
> +  };
>
> -    var title = params['title'];
> +  var destroy = function() {
> +    $('body').off('mousemove.grid#' + this['opts']['id'], positionResizer);
> +    $('body').off('mouseup.grid#' + this['opts']['id'], endResizing);
> +  };
> +
> +  var createDOM = function() {
> +    var containerID = this['opts']['container'];
> +    var container = $('#' + containerID);
> +    var gridID = this['opts']['id'];
> +    var rowSelection = this['opts']['rowSelection'] || 'single';
> +    var domNode = $(kimchi.template(htmlStr, {
> +      id: gridID,
> +      loading: i18n['KCHGRD6001M'],
> +      message: i18n['KCHGRD6002M'],
> +      buttonLabel: i18n['KCHGRD6003M'],
> +      detailedLabel: i18n['KCHGRD6004']
> +    })).appendTo(container);
> +    this.domNode = domNode;
> +
> +    var height = domNode.height();
> +    var width = domNode.width();
> +
> +    var title = this['opts']['title'];
>       var titleNode = null;
>       if(title) {
> -        titleNode = $('<div class="grid-caption">' + title + '</div>')
> -            .prependTo(gridNode);
> +      titleNode = $('<div class="grid-caption">' + title + '</div>')
> +        .prependTo(domNode);
>       }
>
> -    var toolbarButtons = params['toolbarButtons'];
> +    var toolbarButtons = this['opts']['toolbarButtons'];
>       var toolbarNode = null;
>       if(toolbarButtons) {
> -        toolbarNode = $('<div class="grid-toolbar"></div>');
> -        if(titleNode) {
> -            titleNode.after(toolbarNode);
> -        }
> -        else {
> -            toolbarNode.prependTo(gridNode);
> -        }
> -
> -        $.each(toolbarButtons, function(i, button) {
> -            var btnHTML = [
> -                '<button',
> -                button['id'] ? (' id="' + button['id'] + '"') : '',
> -                ' class="grid-toolbar-button',
> -                    button['class'] ? (' ' + button['class']) : '',
> -                    '"',
> -                    button['disabled'] === true ? ' disabled' : '',
> -                    '>',
> -                    button['label'],
> -                '</button>'
> -            ].join('');
> -            var btnNode = $(btnHTML).appendTo(toolbarNode);
> -            button['onClick'] &&
> -                btnNode.on('click', button['onClick']);
> -        });
> +      toolbarNode = $('<div class="grid-toolbar"></div>');
> +      if(titleNode) {
> +        titleNode.after(toolbarNode);
> +      }
> +      else {
> +        toolbarNode.prependTo(domNode);
> +      }
> +
> +      $.each(toolbarButtons, function(i, button) {
> +        var btnHTML = [
> +          '<button',
> +            button['id'] ? (' id="' + button['id'] + '"') : '',
> +            ' class="grid-toolbar-button',
> +              button['class'] ? (' ' + button['class']) : '',
> +              '"',
> +              button['disabled'] === true ? ' disabled' : '',
> +              '>',
> +              button['label'],
> +          '</button>'
> +        ].join('');
> +        var btnNode = $(btnHTML).appendTo(toolbarNode);
> +        button['onClick'] &&
> +          btnNode.on('click', button['onClick']);
> +      });
>       }
>
> -    var setupHeaders = function(header, body, fields) {
> -        var colGroup = $('<colgroup></colgroup>').appendTo(header);
> -        var headerHeader = $('<thead></thead>');
> -        var headerRow = $('<tr></tr>').appendTo(headerHeader);
> -        $.each(fields || [], function(i, field) {
> -            $('<col class="' +
> -                field['class'] +
> -            '"/>')
> -                .appendTo(colGroup);
> -            $('<th><div class="cell-text-wrapper">' +
> -                field['label'] +
> -            '</div></th>').appendTo(headerRow);
> -        });
> -        headerHeader.appendTo(header);
> -
> -        var totalWidth = 0;
> -        $('col', header).each(function(index, col) {
> -            var width = $(col).width();
> -            totalWidth += width;
> -            $(col).css('width', width + 'px');
> -        });
> -        $('colgroup', header).clone().appendTo(body);
> -        return totalWidth;
> -    };
> -
> -    var frozenHeaderContainer = $('.grid-frozen-header-container', gridNode);
> -    var frozenBodyContainer = $('.grid-frozen-body-container', gridNode);
> +    var frozenHeaderContainer = $('.grid-frozen-header-container', domNode);
> +    var frozenBodyContainer = $('.grid-frozen-body-container', domNode);
>       var frozenWidth = setupHeaders(
>           frozenHeaderContainer,
>           frozenBodyContainer,
> -        params['frozenFields']
> +        this['opts']['frozenFields']
>       );
> +    this.frozenHeaderContainer = frozenHeaderContainer;
> +    this.frozenBodyContainer = frozenBodyContainer;
>
> -    var headerContainer = $('.grid-header-container', gridNode);
> -    var bodyContainer = $('.grid-body-container', gridNode);
> -    setupHeaders(headerContainer, bodyContainer, params['fields']);
> +    var headerContainer = $('.grid-header-container', domNode);
> +    var bodyContainer = $('.grid-body-container', domNode);
> +    setupHeaders(headerContainer, bodyContainer, this['opts']['fields']);
> +    this.headerContainer = headerContainer;
> +    this.bodyContainer = bodyContainer;
>
> -    $.each([
> -        frozenHeaderContainer,
> -        headerContainer,
> -        frozenBodyContainer,
> -        bodyContainer
> -    ], function(i, tableNode) {
> -        $(tableNode).css('table-layout', 'auto');
> -    });
> +    fixTableLayout.call(this, 'auto');
>
> -    var gridContentNode = $('.grid-content', gridNode);
> +    var gridContentNode = $('.grid-content', domNode);
>       var captionHeight = titleNode && $(titleNode).height() || 0;
>       var toolbarHeight = toolbarNode && $(toolbarNode).height() || 0;
>       gridContentNode.css('top', (captionHeight + toolbarHeight) + 'px');
>
> -    var maskNode = $('.grid-mask', gridNode);
> +    var maskNode = $('.grid-mask', domNode);
>       maskNode.css('top', captionHeight + 'px');
> +    this.maskNode = maskNode;
>
> -    var messageNode = $('.grid-message', gridNode);
> +    var messageNode = $('.grid-message', domNode);
>       messageNode.css('top', captionHeight + 'px');
> +    this.messageNode = messageNode;
>
> -
> -    var getValue = function(name, obj) {
> -    var result=undefined;
> -    if(!Array.isArray(name)) {
> -        name=name.parseKey();
> -    }
> -    if(name.length!=0) {
> -        var tmpName=name.shift();
> -        if(obj[tmpName]!=undefined) {
> -            result=obj[tmpName];
> -        }
> -        if(name.length!=0) {
> -            result=getValue(name,obj[tmpName]);
> -        }
> -    }
> -    return(result);
> -    };
> -
> -    var fillBody = function(container, fields, data) {
> -        var tbody = ($('tbody', container).length && $('tbody', container))
> -            || $('<tbody></tbody>').appendTo(container);
> -        tbody.empty();
> -        $.each(data, function(i, row) {
> -            var rowNode = $('<tr></tr>').appendTo(tbody);
> -            $.each(fields, function(fi, field) {
> -                var value = getValue(field['name'], row);
> -                $('<td><div class="cell-text-wrapper"' +
> -                     (field['makeTitle'] === true
> -                         ? ' title="' + value + '"'
> -                         : ''
> -                     ) + '>' + value.toString() + '</div></td>'
> -                ).appendTo(rowNode);
> -            });
> -        });
> -    };
> -
> -    var frozenHeaderView = $('.grid-frozen-header-view', gridNode);
> -    var headerView = $('.grid-header-view', gridNode);
> -    var bodyView = $('.grid-body-view', gridNode);
> +    var headerView = $('.grid-header-view', domNode);
> +    var bodyView = $('.grid-body-view', domNode);
>       headerView.css('left', (frozenWidth) + 'px');
>       bodyView.css('left', (frozenWidth) + 'px');
>
> @@ -222,243 +446,64 @@ kimchi.widget.Grid = function(params) {
>       headerContainer.css('width', bodyWidth + 'px');
>       bodyContainer.css('width', bodyWidth + 'px');
>
> -    var fixTableLayout = function() {
> -        $.each([
> -            frozenHeaderContainer,
> -            headerContainer,
> -            frozenBodyContainer,
> -            bodyContainer
> -        ], function(i, tableNode) {
> -            $(tableNode).css('table-layout', 'fixed');
> -        });
> -    };
> -    fixTableLayout();
> -
> -    var gridHeader = $('.grid-header', gridNode);
> -    $('th', gridHeader).on('mouseover mousemove', function(event) {
> -        var pageX = event.pageX;
> -        var tailPos = $(this).width() + $(this).offset()['left'];
> -        var atResizer = Math.abs(pageX - tailPos) <= 2;
> -        var isResizing = !resizer.hasClass('hidden');
> -        $('body')[(atResizer || isResizing)
> -            ? 'addClass'
> -            : 'removeClass'
> -        ]('resizing');
> -    });
> -
> -    $('th', gridHeader).on('mouseout', function(event) {
> -        resizer.hasClass('hidden') &&
> -            $('body').removeClass('resizing');
> -    });
> -
> -    var gridBody = $('.grid-body', gridNode);
> -    var contentHeight = gridContentNode.height();
> -    var resizerLeftmost = $('.grid-resizer-leftmost', gridNode);
> -    var resizer = $('.grid-resizer', gridNode);
> -    resizerLeftmost.css('height', contentHeight + 'px');
> -    resizer.css('height', contentHeight + 'px');
> -
> -    var stylingRow = function(row, className, add) {
> -        var index = $(row).index() + 1;
> -        $('tr', frozenBodyContainer)
> -            .removeClass(className);
> -        $('tr', bodyContainer)
> -            .removeClass(className);
> -
> -        if(add === false) {
> -            return;
> -        }
> -
> -        $('tr:nth-child(' + index + ')', frozenBodyContainer)
> -            .addClass(className);
> -        $('tr:nth-child(' + index + ')', bodyContainer)
> -            .addClass(className);
> -    };
> -
> -    var selectedIndex = -1;
> -    var setBodyListeners = function() {
> -        if(rowSelection != 'disabled') {
> -            $('tr', gridBody).on('mouseover', function(event) {
> -                stylingRow(this, 'hover');
> -            });
> -
> -            $('tr', gridBody).on('mouseout', function(event) {
> -                stylingRow(this, 'hover', false);
> -            });
> -
> -            $('tr', gridBody).on('click', function(event) {
> -                selectedIndex = $(this).index();
> -                stylingRow(this, 'selected');
> -                rowListener && rowListener();
> -            });
> -        }
> -
> -        $('.grid-body-view', gridNode).on('scroll', function(event) {
> -            $('.grid-header .grid-header-view', gridNode)
> -                .prop('scrollLeft', this.scrollLeft);
> -            $('.grid-body .grid-frozen-body-view', gridNode)
> -                .prop('scrollTop', this.scrollTop);
> -        });
> -    };
> -
> -    this.frozenFields = params['frozenFields'];
> -    this.fields = params['fields'];
> -    this.setData = function(data) {
> -        this.data = data;
> -        fillBody(frozenBodyContainer, this.frozenFields, data);
> -        fillBody(bodyContainer, this.fields, data);
> -        setBodyListeners();
> -    };
> -
> -    this.getSelected = function() {
> -        return selectedIndex >= 0
> -            ? this.data[selectedIndex]
> -            : null;
> -    };
> -
> -    var columnBeingResized = null;
> -    var CONTAINER_NORMAL = 0, CONTAINER_FROZEN = 1;
> -    var containerBeingResized = CONTAINER_NORMAL;
> -    var startResizing = function(container, event) {
> -        if(!($('body').hasClass('resizing') && resizer.hasClass('hidden'))) {
> -            return;
> -        }
> -
> -        columnBeingResized = container;
> -        var pageX = event.pageX;
> -        var gridOffsetX = gridNode.offset()['left'];
> -        var leftmostOffsetX = $(container).offset()['left'] - gridOffsetX;
> -        var left = pageX - gridOffsetX;
> -        resizerLeftmost.css('left', leftmostOffsetX + 'px');
> -        resizer.css('left', left + 'px');
> -        resizerLeftmost.removeClass('hidden');
> -        resizer.removeClass('hidden');
> -        event.preventDefault();
> -    };
> -
> -    var endResizing = function(event) {
> -        if(!$('body').hasClass('resizing')) {
> -            return;
> -        }
> -        resizerLeftmost.addClass('hidden');
> -        resizer.addClass('hidden');
> -        $('body').removeClass('resizing');
> -        var leftmostOffset = $(columnBeingResized).offset()['left'];
> -        var left = event.pageX;
> -        if(leftmostOffset > left) {
> -            return;
> -        }
> -
> -        resizeColumnWidth(
> -            $(columnBeingResized).index(),
> -            left - leftmostOffset
> -        );
> -        fixTableLayout();
> -        columnBeingResized = null;
> -    };
> -
> -    var resizeColumnWidth = function(index, width) {
> -        var width = Math.ceil(width);
> -        var widthArray = [];
> -        var totalWidth = 0;
> -        var header = headerContainer;
> -        var body = bodyContainer;
> -        if(containerBeingResized === CONTAINER_FROZEN) {
> -            header = frozenHeaderContainer;
> -            body = frozenBodyContainer;
> -        }
> -        $('col', header).each(function(i, colNode) {
> -            var w = index === i ? width : $(colNode).width();
> -            widthArray.push(w);
> -            totalWidth += w;
> -        });
> -        $.each([header, body], function(i, container) {
> -            container.css({
> -                'table-layout': 'fixed',
> -                width: totalWidth + 'px'
> -            });
> -            $('col:nth-child(' + (index + 1) + ')', container).css({
> -                width: width + 'px'
> -            });
> -        });
> -
> -        if(containerBeingResized === CONTAINER_FROZEN) {
> -            $.each([headerView, bodyView], function(i, view) {
> -                view.css({
> -                    left: totalWidth + 'px'
> -                });
> -            });
> -        }
> -    };
> -
> -    $('th', frozenHeaderContainer).on('mousedown', function(event) {
> -        containerBeingResized = CONTAINER_FROZEN;
> +    fixTableLayout.call(this);
> +
> +    var gridBody = $('.grid-body', domNode);
> +    this.gridBody = gridBody;
> +    this.resizerLeftmost = $('.grid-resizer-leftmost', domNode);
> +    this.resizer = $('.grid-resizer', domNode);
> +    var gridHeader = $('.grid-header', domNode);
> +    $('th', gridHeader).on('mouseover mousemove', {
> +      resizer: this.resizer
> +    }, initResizing);
> +
> +    $('th', gridHeader).on('mouseout', {
> +      resizer: this.resizer
> +    }, clearResizing);
> +
> +    this.containerBeingResized = CONTAINER_NORMAL;
> +    $('th', frozenHeaderContainer).on('mousedown', {
> +      grid: this
> +    }, function(event) {
> +        event.data.grid.containerBeingResized = CONTAINER_FROZEN;
>           startResizing(this, event);
>       });
> -    $('th', headerContainer).on('mousedown', function(event) {
> -        containerBeingResized = CONTAINER_NORMAL;
> +    $('th', headerContainer).on('mousedown', {
> +      grid: this
> +    }, function(event) {
> +        event.data.grid.containerBeingResized = CONTAINER_NORMAL;
>           startResizing(this, event);
>       });
> -
> -    var positionResizer = function(event) {
> -        if(resizer.hasClass('hidden')) {
> -            return;
> -        }
> -
> -        var pageX = event.pageX;
> -        var gridOffsetX = gridNode.offset()['left'];
> -        var leftMost = resizerLeftmost.position()['left'];
> -        var offsetX = pageX - gridOffsetX;
> -        offsetX = offsetX >= leftMost ? offsetX : leftMost;
> -        resizer.css('left', offsetX + 'px');
> -    };
> -
> -    $('body').on('mousemove', positionResizer);
> -    $('body').on('mouseup', endResizing);
> -
> -    this.showMessage = function(msg) {
> -        $('.detailed-text', messageNode).text(msg);
> -        $(messageNode).removeClass('hidden');
> -    };
> -
> -    this.hideMessage = function() {
> -        $(messageNode).addClass('hidden');
> -    };
> -
> -    this.destroy = function() {
> -        $('body').off('mousemove', positionResizer);
> -        $('body').off('mouseup', endResizing);
> -    };
> -
> -    var data = params['data'];
> -    var self = this;
> -    var reload = function() {
> -        if(!data) {
> -            return;
> -        }
> -
> -        $(messageNode).addClass('hidden');
> -
> -        if($.isArray(data)) {
> -            self.setData(data);
> -            return;
> -        }
> -
> -        if($.isFunction(data)) {
> -            var loadData = data;
> -            maskNode.removeClass('hidden');
> -            loadData(function(data) {
> -                self.setData(data);
> -                maskNode.addClass('hidden');
> -            });
> -        }
> -    };
> -
> -    var reloadButton = $('.retry-button', gridNode);
> -    $(reloadButton).on('click', function(event) {
> -        reload();
> +
> +    $('body').on('mousemove.grid#' + this['opts']['id'], {
> +      grid: this
> +    }, positionResizer);
> +    $('body').on('mouseup.grid#' + this['opts']['id'], endResizing);
> +
> +    var data = this['opts']['data'];
> +
> +    $('.retry-button', domNode).on('click', {
> +      grid: this
> +    }, function(event) {
> +      grid.reload();
>       });
> -
> -    this.reload = reload;
> -    reload();
> -};
> +  };
> +
> +  return {
> +    opts: {
> +      container: null,
> +      id: null,
> +      rowSelection: 'single',
> +      onRowSelected: null,
> +      title: null,
> +      toolbarButtons: null,
> +      frozenFields: null,
> +      fields: null
> +    },
> +    createDOM: createDOM,
> +    setData: setData,
> +    getSelected: getSelected,
> +    reload: reload,
> +    destroy: destroy
> +  };
> +})();




More information about the Kimchi-devel mailing list