Search code examples
javascriptcsslayoutpanelalloy-ui

Resizable panels in AlloyUI


I am learning AlloyUI, but don't know how to set resizable panels in main layout. I tried this method to resize table, but it didn't work and I didn't see any error in console. Can anybody help how to make div elements resizable in AlloyUI?

Here is my basic layout, where are 3 main panels resizable using jQuery UI:

http://jsfiddle.net/vLeve252/

Here is my code, where I tried to make table resizable in panel:

main.html

    <!-- main css -->
    <link rel="stylesheet" type="text/css" href="resources/styles/main.css" media="all" /> 

    <script src="http://cdn.alloyui.com/2.0.0/aui/aui-min.js"></script>
    <link href="http://cdn.alloyui.com/2.0.0/aui-css/css/bootstrap.min.css" rel="stylesheet"/>

</head>

<body>

<div id="layout">

    <div id="filter">

    <table id="tabl" style="width:100%">
    <tr>
      <td>Jill</td>
      <td>Smith</td> 
      <td>50</td>
    </tr>
    <tr>
      <td>Eve</td>
      <td>Jackson</td> 
      <td>94</td>
    </tr>
    </table>        

    </div>

    <div id="graph"></div>
    <div id="details"></div>

</div> 

<script>
    YUI().use(
  'resize',
  'overlay',
  function (Y) {
    var overlay = new Y.Overlay({
      width: "200px",
      srcNode: "#tabl",
      visible: false,
      align: {node:".example", points:["tc", "bc"]}
   });
   overlay.plug(Y.Plugin.Resize);
  }
);

    </script>

</body>

main.css

#filter{
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 20%;
    height: 100%;
    overflow: auto;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    -ms-box-sizing: border-box;
    -o-box-sizing: border-box;
    box-sizing: border-box;

    border-right:  solid 1px #aaa;
}

#details {
    position: absolute;
    left: 20%;
    bottom: 0;
    height: 20%;
    width: 100%;
    border-top:  solid 1px #aaa;
}

edit

I would like to achieve the same result as here, but using AlloyUI not jQuery UI


Solution

  • To make divs (or any type of Node) resizeable, you need to plug() the Plugin.Resize class into your Node.

    It isn't necessary to use an Overlay. Instead you can get the divs as Node using YUI.one(). Then you can plug() in the Resize plug-in. The javascript to do that would look something like this:

    YUI().use('resize-plugin', 'node', function (Y) {
       Y.one('#filter').plug(Y.Plugin.Resize);
       Y.one('#graph').plug(Y.Plugin.Resize);
       Y.one('#details').plug(Y.Plugin.Resize);
    });
    

    Edit:

    However, to make a layout similar to the jQuery one that you posted in this jsFiddle is a bit of a tall order. My first recommendation would be to use jQuery. The jQuery solution seems to be simple and well thought out, and it can coexist with YUI/AlloyUI on the same page, so use jQuery for the layout and YUI/AlloyUI for whatever else you want.

    If you absolutely must not use jQuery, you can do something like this:

    HTML

    <div id="layout">
        <div id="graph"></div>
        <div id="details"></div>
    </div>
    

    CSS

    #layout {
        position: absolute;
        right: 0;
        height: 300px;
        width: 300px;
    }
    
    #graph {
        position: absolute;
        height: 200px;
        width: 100%;
        background: orange;
    }
    
    #details {
        position: absolute;
        bottom: 0;
        height: 100px;
        width: 100%;
        background: navy;
    }
    

    javascript

    YUI().use('resize-constrain', 'resize-plugin', 'node', function (Y) {
    
        var graphNode = Y.one('#graph');
        var detailsNode = Y.one('#details');
    
        graphNode.plug(Y.Plugin.Resize, {
            handles: ['b']
        });
    
        graphNode.resize.plug(Y.Plugin.ResizeConstrained, {
            constrain: '#layout'
        });
    
        graphNode.resize.on('resize:resize', function (event) {
            var graphHeight = parseInt(graphNode.getStyle('height'), 10);
            detailsNode.setStyle('height', (300 - graphHeight) + 'px');
        });
    });
    

    Explantion:

    1. Plug one Node with a Resize plugin in order to make it resizable.
    2. Plug that Resize plugin with a ResizeConstrianed plugin in order to only allow resizing within the width of the outer div.
    3. On the resize:resize event:

      • Get the height of the graph div as an Integer.
      • Subtract it from the total height to determine the new height of the details div.
      • Set the details div to the new height.

    For the sake of completeness, I've included a runnable example with a 3 panel resizable layout much like the jQuery example:

    YUI().use('resize-constrain', 'resize-plugin', 'node', function (Y) {
    
        var graphNode = Y.one('#graph');
        var detailsNode = Y.one('#details');
    
        graphNode.plug(Y.Plugin.Resize, {
            handles: ['b']
        });
    
        graphNode.resize.plug(Y.Plugin.ResizeConstrained, {
            constrain: '#rightPanel'
        });
    
        graphNode.resize.on('resize:resize', function (event) {
            var graphHeight = parseInt(graphNode.getStyle('height'), 10);
            detailsNode.setStyle('height', (300 - graphHeight) + 'px');
        });
    
        var filterNode = Y.one('#filter');
        var rightPanelNode = Y.one('#rightPanel');
    
        filterNode.plug(Y.Plugin.Resize, {
            handles: ['r']
        });
    
        filterNode.resize.plug(Y.Plugin.ResizeConstrained, {
            constrain: '#mainLayout'
        });
    
        filterNode.resize.on('resize:resize', function (event) {
            var filterWidth = parseInt(filterNode.getStyle('width'), 10);
            var rightPanelResizedWidth = (600 - filterWidth) + 'px';
            rightPanelNode.setStyle('width', rightPanelResizedWidth);
            // YUI sets the height using the `style` attribute, so it must be overwritten using `setStyle()` becuase the CSS has been overriden.
            graphNode.setStyle('width', rightPanelResizedWidth);
        });
    });
    #mainLayout {
        position: absolute;
        height: 300px;
        width: 600px;
    }
    
    #rightPanel {
        position: absolute;
        right: 0;
        height: 300px;
        width: 300px;
    }
    
    #graph {
        position: absolute;
        height: 200px;
        width: 100%;
        background: orange;
    }
    
    #details {
        position: absolute;
        bottom: 0;
        height: 100px;
        width: 100%;
        background: navy;
    }
    
    #filter {
        position: absolute;
        left: 0;
        height: 100%;
        width: 300px;
        background: darkcyan;
    }
    <script src="https://cdn.rawgit.com/stiemannkj1/0214fdc4cccaa77d6e504320cf70a571/raw/63d260364730fb067f103c00862c7e65685256df/yui-3.18.1_build_yui_yui-min.js"></script>
    <div id="mainLayout">
        <div id="rightPanel">
            <div id="graph"></div>
            <div id="details"></div>
        </div>
        <div id="filter"></div>
    </div>