2

我想使用 jQuery 中的 resizable 函数来调整闪亮应用程序中的列宽。不幸的是,我不确定如何将选项传递给 jqui_resizable 函数,以便我可以传递also_resize 函数,或者设置 maxHeight/minHeight。

理想情况下,我希望列具有设定的高度(即全屏),但同步可调整大小的宽度(这也占据了屏幕的整个宽度)。

下面是我非常简单的尝试来展示我想要的东西。不幸的是,它不起作用,因为在给定列宽的情况下,调整一列的大小以使其更大会将另一列向下移动一行。

任何关于如何做到这一点的想法将不胜感激!谢谢!

library(shiny)
library(shinyjqui)

ui <- fluidPage(
  fluidRow(

    jqui_resizable(column(6,"text")),
    jqui_resizable(column(6,"more text"))



  )
)

server <- function(input, output, session) {

}

shinyApp(ui, server)

4

1 回答 1

2

这是基于此 codepen的解决方案。

文件resizableColumns.js

$(document).ready(function() {
  (function($, window, document, undefined) {

    $.widget('ce.resizableGrid', {

      _create: function() {
        this.resizing = false;
        this._on({
          'mousedown .resizable-column-handle': '_resizeStartHandler',
          'mousemove': '_resizeHandler',
          'mouseup': '_resizeStopHandler',
          'mouseleave': '_resizeStopHandler'
        });
      },

      _init: function() {
        this._createHelpers();
      },

      _createHelpers: function() {
        this.element.addClass('resizable-grid');
        this.element.find('> .row:not(.resizable-row)').each(function(rowIndex, rowElement) {
          var row = $(rowElement);
          row.addClass('resizable-row');
          row.find('> [class^="col-"]:not(.resizable-column)').each(function(columnIndex, columnElement) {
            var column = $(columnElement);
            column.addClass('resizable-column');
            column.append(
              $('<div>', {
                class: 'resizable-column-handle resizable-column-handle-w',
                'data-is-west': 'true'
              }),
              $('<div>', {
                class: 'resizable-column-handle resizable-column-handle-e',
                'data-is-west': 'false'
              })
            );
          });
        });
      },

      _resizeStartHandler: function(event) {
        this.resizing = {};
        this.resizing.handle = $(event.currentTarget).addClass('resizable-column-handle-resizing');
        this.resizing.column = this.resizing.handle.closest('.resizable-column').addClass('resizable-column-resizing');
        this.resizing.row = this.resizing.column.closest('.resizable-row').addClass('resizable-row-resizing');
        this.resizing.handleIsWest = this.resizing.handle.data('isWest');
        this.resizing.directionIsWest = this._getResizingDirectionIsWest(event.pageX);
        this.resizing.columnSize = this._getColumnSize(this.resizing.column);
        this.resizing.siblings = this._getResizingSiblings(this.resizing.column);
        this.resizing.offsets = this._getResizingOffsets();
        this.element.addClass('resizable-grid-resizing');
      },

      _resizeHandler: function(event) {
        if(!this.resizing) {
          return;
        }
        this.resizing.directionIsWest = this._getResizingDirectionIsWest(event.pageX);
        var resizingOffsetSize = this._getResizingOffsetSize(event.pageX);
        if(resizingOffsetSize && (this.resizing.columnSize !== resizingOffsetSize)) {
          if(resizingOffsetSize > this.resizing.columnSize) {
            var widestColumn = this._getWidestColumn(this.resizing.siblings),
              widestColumnSize = this._getColumnSize(widestColumn);
            this._setColumnSize(widestColumn, (widestColumnSize - 1));
            this._setColumnSize(this.resizing.column, resizingOffsetSize);
          } else {
            var narrowestColumn = this._getNarrowestColumn(this.resizing.siblings),
              narrowestColumnSize = this._getColumnSize(narrowestColumn);
            this._setColumnSize(narrowestColumn, (narrowestColumnSize + 1));
            this._setColumnSize(this.resizing.column, resizingOffsetSize);
          }
          this.resizing.columnSize = resizingOffsetSize;
        }
      },

      _resizeStopHandler: function(event) {
        if(!this.resizing) {
          return;
        }
        this.resizing.handle.removeClass('resizable-column-handle-resizing');
        this.resizing.column.removeClass('resizable-column-resizing');
        this.resizing.row.removeClass('resizable-row-resizing');
        this.element.removeClass('resizable-grid-resizing');
        this.resizing = false;
      },

      _getResizingDirectionIsWest: function(x) {
        var resizingDirectionIsWest;
        if(!this.resizing.directionLastX) {
          this.resizing.directionLastX = x;
          resizingDirectionIsWest = null;
        } else {
          if(x < this.resizing.directionLastX) {
            resizingDirectionIsWest = true;
          } else {
            resizingDirectionIsWest = false;
          }
          this.resizing.directionLastX = x;
        }
        return resizingDirectionIsWest;
      },

      _getResizingSiblings: function(column) {
        return ((this.resizing.handleIsWest) ? column.prevAll() : column.nextAll());
      },

      _getResizingOffsetSize: function(x) {
        var that = this,
          resizingOffsetSize;
        $.each(this.resizing.offsets, function(index, offset) {
          if((that.resizing.directionIsWest && ((x <= offset.end) && (x >= offset.start))) || (!that.resizing.directionIsWest && ((x >= offset.start) && (x <= offset.end)))) {
            resizingOffsetSize = offset.size;
          }
        });
        return resizingOffsetSize;
      },

      _getResizingOffsets: function() {
        var that = this,
          row = this.resizing.row.clone(),
          css = {
            'height': '1px',
            'min-height': '1px',
            'max-height': '1px'
          };
        row.removeClass('resizable-row resizable-row-resizing').css(css);
        row.children().empty().removeClass('resizable-column resizable-column-resizing').css(css);
        this.resizing.row.parent().append(row);
        var column = row.children().eq(this.resizing.row.children().index(this.resizing.column)),
          totalSize = this._getColumnSize(column);
        this._getResizingSiblings(column).each(function() {
          totalSize += (that._getColumnSize($(this)) - 1);
          that._setColumnSize($(this), 1);
        });
        var size = ((this.resizing.handleIsWest) ? totalSize : 1),
          sizeEnd = ((this.resizing.handleIsWest) ? 1 : totalSize),
          sizeOperator = ((this.resizing.handleIsWest) ? -1 : 1),
          offset = 0,
          offsetOperator = ((this.resizing.handleIsWest) ? 1 : 0);
        var columnGutter = ((column.outerWidth(true) - column.width()) / 2),
          columnWidth = ((this.resizing.handleIsWest) ? false : true);
        var resizingOffsets = [];
        while(true) {
          this._setColumnSize(column, size);
          this._setColumnOffset(column, offset);
          var left = (Math.floor((column.offset()).left) + columnGutter + ((columnWidth) ? column.width() : 0));
          resizingOffsets.push({
            start: (left + ((columnGutter * 3) * -1)),
            end: (left + (columnGutter * 3)),
            size: size
          });
          if(size === sizeEnd) {
            break;
          }
          size += sizeOperator;
          offset += offsetOperator;
        }
        row.remove();
        return resizingOffsets;
      },

      _getWidestColumn: function(columns) {
        var that = this,
          widestColumn;
        columns.each(function() {
          if(!widestColumn || (that._getColumnSize($(this)) > that._getColumnSize(widestColumn))) {
            widestColumn = $(this);
          }
        });
        return widestColumn;
      },

      _getNarrowestColumn: function(columns) {
        var that = this,
          narrowestColumn;
        columns.each(function() {
          if(!narrowestColumn || (that._getColumnSize($(this)) < that._getColumnSize(narrowestColumn))) {
            narrowestColumn = $(this);
          }
        });
        return narrowestColumn;
      },

      _getColumnSize: function(column) {
        var columnSize;
        $.each($.trim(column.attr('class')).split(' '), function(index, value) {
          if(value.match(/^col-/) && !value.match(/-offset-/)) {
            columnSize = parseInt($.trim(value).replace(/\D/g, ''), 10);
          }
        });
        return columnSize;
      },

      _setColumnSize: function(column, size) {
        column.toggleClass([
          ['col', 'sm', this._getColumnSize(column)].join('-'), ['col', 'sm', size].join('-')
        ].join(' '));
      },

      _getColumnOffset: function(column) {
        var columnOffset;
        $.each($.trim(column.attr('class')).split(' '), function(index, value) {
          if(value.match(/^col-/) && value.match(/-offset-/)) {
            columnOffset = parseInt($.trim(value).replace(/\D/g, ''), 10);
          }
        });
        return columnOffset;
      },

      _setColumnOffset: function(column, offset) {
        var currentColumnOffset,
          toggleClasses = [];
        if((currentColumnOffset = this._getColumnOffset(column)) !== undefined) {
          toggleClasses.push(['col', 'sm', 'offset', currentColumnOffset].join('-'));
        }
        toggleClasses.push(['col', 'sm', 'offset', offset].join('-'));
        column.toggleClass(toggleClasses.join(' '));
      },

      _destroy: function() {
        this._destroyHelpers();
      },

      _destroyHelpers: function() {
        this.element.find('.resizable-column-handle').remove();
        this.element.find('.resizable-column').removeClass('resizable-column resizable-column-resizing');
        this.element.find('.resizable-row').removeClass('resizable-row resizable-row-resizing');
        this.element.removeClass('resizable-grid resizable-grid-resizing');
      }
    });

  })(jQuery, window, document);

  $('#layout').resizableGrid();

});

文件resizableColumns.css

.container {
  margin-top: 50px;
}

.row {
  background-color: rgba(189, 195, 199, 0.25);
}

.row:hover {
  background-color: rgba(189, 195, 199, 0.5);
}

.row > .col-sm-1,
.row > .col-sm-2,
.row > .col-sm-3,
.row > .col-sm-4,
.row > .col-sm-5,
.row > .col-sm-6,
.row > .col-sm-7,
.row > .col-sm-8,
.row > .col-sm-9,
.row > .col-sm-10,
.row > .col-sm-11,
.row > .col-sm-12 {
  min-height: 100px;
}

.row > .col-sm-1:before,
.row > .col-sm-2:before,
.row > .col-sm-3:before,
.row > .col-sm-4:before,
.row > .col-sm-5:before,
.row > .col-sm-6:before,
.row > .col-sm-7:before,
.row > .col-sm-8:before,
.row > .col-sm-9:before,
.row > .col-sm-10:before,
.row > .col-sm-11:before,
.row > .col-sm-12:before {
  content: '';
  display: block;
  position: absolute;
  top: 0;
  right: 15px;
  bottom: 0;
  left: 15px;
  background-color: rgba(52, 152, 219, 0.25);
}

.row > .col-sm-1:hover:before,
.row > .col-sm-2:hover:before,
.row > .col-sm-3:hover:before,
.row > .col-sm-4:hover:before,
.row > .col-sm-5:hover:before,
.row > .col-sm-6:hover:before,
.row > .col-sm-7:hover:before,
.row > .col-sm-8:hover:before,
.row > .col-sm-9:hover:before,
.row > .col-sm-10:hover:before,
.row > .col-sm-11:hover:before,
.row > .col-sm-12:hover:before {
  background-color: rgba(52, 152, 219, 0.5);
}

/* Resizable Grid */

.resizable-grid > .resizable-row > .resizable-column > .resizable-column-handle {
  z-index: 100;
  display: none;
  position: absolute;
  top: 0;
  height: 100%;
  width: 6px;
  cursor: col-resize;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  -ms-touch-action: none;
  touch-action: none;
}

.resizable-grid > .resizable-row > .resizable-column > .resizable-column-handle-w {
  left: 12px;
}

.resizable-grid > .resizable-row > .resizable-column > .resizable-column-handle-e {
  right: 12px;
}

.resizable-grid > .resizable-row > .resizable-column:first-child:not(:last-child) > .resizable-column-handle-e,
.resizable-grid > .resizable-row > .resizable-column:not(:first-child):not(:last-child) > .resizable-column-handle-w,
.resizable-grid > .resizable-row > .resizable-column:not(:first-child):not(:last-child) > .resizable-column-handle-e,
.resizable-grid > .resizable-row > .resizable-column:last-child:not(:first-child) > .resizable-column-handle-w {
  display: block;
}

.resizable-grid-resizing {
  cursor: col-resize;
}

.resizable-grid > .resizable-row-resizing > .resizable-column:not(.resizable-column-resizing) {
  opacity: 0.5;
}

将文件resizableColumns.jsresizableColumns.css放在app 文件夹的www子文件夹中。应用程序:

library(shiny)

ui <- fluidPage(
  tags$head(
    tags$script(src = "https://code.jquery.com/ui/1.12.1/jquery-ui.js"),
    tags$link(rel = "stylesheet", href = "resizableColumns.css"),
    tags$script(src = "resizableColumns.js")
  ),
  tags$div(
    id = "layout",
    fluidRow(
      column(
        width = 3,
        h3("column1")
      ),
      column(
        width = 3,
        h3("column2")
      ),
      column(
        width = 3,
        h3("column3")
      ),
      column(
        width = 3,
        h3("column4")
      )
    )
  )
)

server <- function(input, output){}

shinyApp(ui, server)
于 2020-04-25T15:06:22.600 回答