[Kimchi-devel] [PATCH 1/2] Issue#364: UI - Column Resizing Function Broken in Host Tab
Hongliang Wang
hlwang at linux.vnet.ibm.com
Tue Apr 15 01:42:47 UTC 2014
On 04/15/2014 02:26 AM, Aline Manera wrote:
> 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.
ACK. Forgot to add it back.
>
>> -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