jQuery UI and Splitter

2020-06-03 06:32发布

问题:

Using jQuery UI, how can I use a Splitter kind of feature like the one at http://methvin.com/splitter/3csplitter.html?

I am asking this as I need 2 things to be implemented on my page; Portlet (Draggable) :: http://jqueryui.com/sortable/#portlets and Vertical Splitter :: http://methvin.com/splitter/3csplitter.html

I am not sure how good coding practice it is if I am including 2 separate libraries (even though both are jQuery based); like http://host.sonspring.com/portlets/ for Portlets and http://methvin.com/splitter/3csplitter.html for Splitter

回答1:

Here is an example on how to create the splitter using jQuery UI:

HTML:

<div class="wrap">
    <div class="resizable resizable1"></div>
    <div class="resizable resizable2"></div>
</div>

Script:

$(function () 
{
    $(".resizable1").resizable(
    {
        autoHide: true,
        handles: 'e',
        resize: function(e, ui) 
        {
            var parent = ui.element.parent();
            var remainingSpace = parent.width() - ui.element.outerWidth(),
                divTwo = ui.element.next(),
                divTwoWidth = (remainingSpace - (divTwo.outerWidth() - divTwo.width()))/parent.width()*100+"%";
                divTwo.width(divTwoWidth);
        },
        stop: function(e, ui) 
        {
            var parent = ui.element.parent();
            ui.element.css(
            {
                width: ui.element.width()/parent.width()*100+"%",
            });
        }
    });
});

This is a popular script. I've added little modifications for the fluid layout.

jsFiddle example



回答2:

I used Dmitriy's answer as the base of my implementation. Note that there is nothing stopping that particular implementation from doubling the bounding box when the slider is dragged to the right.

I needed a simple non-moveable splitter for now (with the view to making the panes resizable in the future), and my application is already using jQuery, so I achieved this by changing part of his code as follows:

$(function () 
{
    $(".resizable1").resizable(
    {
        autoHide: false,
        containment: "#wrap",
        ...

I also changed the css cursor style (among other things) to prevent the resizable cursor from being displayed as follows:

.ui-resizable-e { 
    cursor: default; 
    ...

Thanks Dmitriy!



回答3:

My first thought was: first you select all the boxes except the last. Those get a splitter to their right side. Then, when the splitter is moved, only the two boxes touching the splitter are resized.

This is an example you can copy paste; it works as is. This can be used for any number of columns; just make sure you also adapt the css.

I added some buttons to expand 1 box; also a reset button.

<!DOCTYPE HTML> 
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>jQuery UI 4-Column Splitter</title>
    <link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/themes/smoothness/jquery-ui.css" />
    <style>
      body {
        padding: 0;
        margin: 0;
      }
      .wrap {
        width: 100%;
        white-space: nowrap;
        background-color: #c0c0c0;
      }
      .resizable {
          width: 25%;
          height: 120px;
          display: inline-block;
          overflow: hidden;
      }
      .ui-resizable-e { 
          cursor: e-resize; 
          width: 10px; 
          top: 0; 
          bottom: 0; 
          background-color: gray;
          z-index: 10;
      }
    </style>
  </head>
  <body>
    <div class="wrap">
      <div class="resizable"> HELLO  </div>
      <div class="resizable"> WORLD </div>
      <div class="resizable"> FOO </div>
      <div class="resizable"> BAR </div>
    </div>
    <div id="controls">
      <input type="button" value="expand 0" data-index="0" class="expand">
      <input type="button" value="expand 1" data-index="1" class="expand">
      <input type="button" value="expand 2" data-index="2" class="expand">
      <input type="button" value="expand 3" data-index="3" class="expand">
      <input type="button" value="reset" class="reset">
    </div>

    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/jquery-ui.min.js"></script>
    <style type="text/css" media="all">
    </style>
    <script type="text/javascript">
      $(function () {
        // settings
        var minWidth = 15;
        var splitterWidth = 10;  // this sh ould match the css value

        var splitter   =  $('.ui-resizable-e');
        var container =   $('.wrap');
        var boxes =       $('.resizable');

        var subBoxWidth = 0;


        $(".resizable:not(:last)").resizable({
          autoHide: false,
          handles: 'e',
          minWidth: minWidth,

          start: function(event, ui) {
            // We will take/give width from/to the next element; leaving all other divs alone.
            subBoxWidth = ui.element.width() + ui.element.next().width();
            // set maximum width
            ui.element.resizable({
              maxWidth: subBoxWidth - splitterWidth - minWidth
            });
          },

          resize: function(e, ui) {
            var index = $('.wrap').index( ui.element );
            ui.element.next().width(
              subBoxWidth - ui.element.width()
            );
          },

        });
        // collapses all the other boxes to the minimum width; expands the chosen box to what ever width is left
        $('.expand').click(function () {
          var index = $(this).data('index');
          var boxesToCollapse = boxes.length - 1;
          var widthLeft = container.width() - boxesToCollapse * (minWidth + splitterWidth);
          for (var i=0; i<boxes.length; i++) {
            boxes.eq(i).width( i==index ? widthLeft : minWidth);
          }
        });
        $('.reset').click(function () {
          boxes.removeAttr('style');
        });
      });
    </script>

  </body>
</html>


回答4:

The Splitter component part of the Shield UI framework allows you to use a mixture of horizontal and vertical splitters.