Page 2 of 8 FirstFirst 1234 ... LastLast
Results 11 to 20 of 80

Thread: Ext.ux.layout.RowFitLayout

  1. #11
    Sencha User Animal's Avatar
    Join Date
    Mar 2007
    Location
    Bédoin/Nottingham
    Posts
    30,892

    Default

    Bump!

    Someone was (or should have been!) looking for this thread!

  2. #12

    Post Maybe this class would be what I've been looking for

    Hi,

    Maybe this class is what I'm looking for. I want to do the same that the portal example but disposing panels in rows instead of columns. Read this thread:

    http://extjs.com/forum/showthread.php?t=21215

    Bye.

  3. #13
    Sencha Premium Member
    Join Date
    Sep 2007
    Posts
    23

    Default

    Wow great work. I was looking for something similar to this myself.
    Ramki

  4. #14

    Question It's half what I need

    Yesterday, I tested this new layout. I added three panels and each one fills a row. But this is half what I need. I need a row-layout, that's fine. The next step is a new layout, one like the horizontal panel in GWT library, to be used in each row. I need drag&drop panels to a row to be positioned horizontally in the row. See the Portal example of Ext2. I need the same application but in rows. So in the first row you can add 3 panels, each one with the same height but with different width.

    I've been thinking about creating a new layout using anchor layout philosophy. This layout, displays panels using HTML positioning. So, the second panel you add goes below the first one you added previously. This is what I need but in horizontal. So, when you add a new panel in a row of an row-layout, goes at the right of the previous one.

    Can someone give me some advice?

    Thanks a lot.

  5. #15
    Ext User
    Join Date
    Nov 2007
    Posts
    110

    Talking

    Thanks for sharing your work, I've tried to improve a bit on it and extended it to automatically add the needed sliders and splitbars. Just add a property 'split' to the items to be resizable.

    Here we go:
    Code:
    Ext.namespace('Ext.ux.layout'); 
     
    /** 
     * @class Ext.ux.layout.RowFitLayout 
     * @extends Ext.layout.ContainerLayout 
     * <p>Layout that distributes heights of elements so they take 100% of the 
     * container height.</p> 
     * <p>Height of the child element can be given in pixels (as an integer) or 
     * in percent. All elements with absolute height (i.e. in pixels) always will 
     * have the given height. All "free" space (that is not filled with elements 
     * with 'absolute' height) will be distributed among other elements in 
     * proportion of their height percentage. Elements without 'height' in the 
     * config will take equal portions of the "unallocated" height.</p> 
     * <p>Supports panel collapsing, hiding, removal/addition. The adapter is provided 
     * to use with Ext.SplitBar: <b>Ext.ux.layout.RowFitLayout.SplitAdapter</b>.</p> 
     * <p>Example usage:</p> 
     * <pre><code> 
     var vp = new Ext.Viewport({ 
       layout: 'row-fit', 
       items: [ 
         { xtype: 'panel', height: 100, title: 'Height in pixels', html: 'panel height = 100px' }, 
         { xtype: 'panel', height: "50%", title: '1/2', html: 'Will take half of remaining height' }, 
         { xtype: 'panel', title: 'No height 1', html: 'Panel without given height', id: '' }, 
         { xtype: 'panel', title: 'No height 2', html: 'Another panel' } 
       ] 
     }); 
     * </code></pre> 
     * Usage of the split bar adapter: 
     * <pre><code> 
     var split = new Ext.SplitBar("elementToDrag", "elementToSize", Ext.SplitBar.VERTICAL, Ext.SplitBar.TOP); 
     // note the Ext.SplitBar object is passed to the adapter constructor to set 
     // correct minSize and maxSize: 
     split.setAdapter(new Ext.ux.layout.RowFitLayout.SplitAdapter(split)); 
     * </code></pre> 
     */ 
     
    Ext.ux.layout.RowFitLayout = Ext.extend(Ext.layout.ContainerLayout, {
      // private
      monitorResize: true,
    
      // private
      trackChildEvents: ['collapse', 'expand', 'hide', 'show'],
    
      // private
      splitHeight: 5,
      rendered: false,
    
      // private
      renderItem: function(c, position, target) {
        Ext.ux.layout.RowFitLayout.superclass.renderItem.apply(this, arguments);
    
        // add event listeners
        for (var i=0, n = this.trackChildEvents.length; i < n; i++) {
          var ev = this.trackChildEvents[i];
          //c.on(this.trackChildEvents[i], this.itemListener, this);
          c.on(ev, this['_item_' + ev], this);
        }
        c.animCollapse = false; // looks ugly together with row-fit layout
    
        this.checkRelHeight(c);
      },
    
      checkRelHeight: function(c) {
    
        // store some layout-specific calculations
        if(!c.rowFit) c.rowFit = {
          hasAbsHeight: false, // whether the component has absolute height (in pixels)
          relHeight: 0, // relative height, in pixels (if applicable)
          calcRelHeight: 0, // calculated relative height (used when element is resized)
          calcAbsHeight: 0, // calculated absolute height
          height: c.height  // save height config
        };
    
        // process height config option
        if (c.height) {
          var height = c.rowFit.height || c.height;
          // store relative (given in percent) height
          if (typeof height == "string" && height.indexOf("%")) {
            c.rowFit.relHeight = parseInt(height);
          }
          else { // set absolute height
            c.setHeight(c.height);
            //c.rowFit.hasAbsHeight = true;
            c.rowFit.hasAbsHeight = !Boolean(c.split);
          }
        }
        //if(c.split) c.rowFit.hasAbsHeight = false;
        c.isResizable = c.isResizable || Boolean(c.split) || !c.rowFit.hasAbsHeight;
      },
    
      // private
      onLayout: function(ct, target) {
    
        Ext.ux.layout.RowFitLayout.superclass.onLayout.call(this, ct, target);
    
        if (this.container.collapsed || !ct.items || !ct.items.length) {
          return;
        }
    
        // first loop: determine how many elements with relative height are there,
        // sums of absolute and relative heights etc.
        var absHeightSum = 0, // sum of elements' absolute heights
            relHeightSum = 0, // sum of all percent heights given in children configs
            relHeightRatio = 1, // "scale" ratio used in case sum <> 100%
            noHeightCount = 0, // number of elements with no height given
            relHeightElements = []; // array of elements with 'relative' height for the second loop
    
        for (var i=0, n = ct.items.length; i < n; i++) {
          var c = ct.items.itemAt(i);
    
          if (!c.isVisible()) { continue; }
    
          // collapsed panel is treated as an element with absolute height
          if (c.collapsed) {
            absHeightSum += c.getFrameHeight();
          }
          else if (c.rowFit.hasAbsHeight) { // element that has an absolute height
            absHeightSum += c.height;
          }
          else { // 'relative-heighted'
            if (!c.rowFit.relHeight) { // element with no height given
              noHeightCount++;
            }
            else {
              relHeightSum += c.rowFit.relHeight;
            }
            relHeightElements.push(c);
          }
        }
    
        // if sum of relative heights <> 100% (e.g. error in config or consequence
        // of collapsing/removing panels), scale 'em so it becomes 100%
        if (noHeightCount == 0 && relHeightSum != 100) {
          relHeightRatio = 100 / relHeightSum;
        }
    
        var freeHeight = target.getStyleSize().height - absHeightSum, // "unallocated" height we have
            absHeightLeft = freeHeight; // track how much free space we have
    
        while (relHeightElements.length) {
          var c = relHeightElements.shift(), // element we're working with
              relH = c.rowFit.relHeight * relHeightRatio, // height of this element in percent
              absH = 0; // height in pixels
    
          // no height in config
          if (!relH) {
            relH = (100 - relHeightSum) / noHeightCount;
          }
    
          // last element takes all remaining space
          if (!relHeightElements.length) { absH = absHeightLeft; }
          else { absH = Math.round(freeHeight * relH / 100); }
    
          // anyway, height can't be negative
          if (absH < 0) { absH = 0; }
    
          c.rowFit.calcAbsHeight = absH;
          c.rowFit.calcRelHeight = relH;
    
          c.setHeight(absH);
          absHeightLeft -= absH;
        }
    
        for (var i=0, n = ct.items.length; i < n; i++) {
          var c = ct.items.itemAt(i);
          if(c.isSlider && c.el2resize) {
    //        this.checkRelHeight(c);
            var split = new Ext.SplitBar(c.el, c.el2resize.el, Ext.SplitBar.VERTICAL, Ext.SplitBar.TOP);
            split.setAdapter(new Ext.ux.layout.RowFitLayout.SplitAdapter(split));
            c.el2resize.sliderId = c.getId();
            c.el2resize = false;
          }
        }
    
        if(!this.rendered) { // keep watching for changes of items
          ct.on('add', this.ctAddItem, this);
          ct.on('remove', this.ctDelItem, this);
          this.rendered = true;
        }
      },
    
      // private - called from Ext.Container
      setContainer : function(ct){
        Ext.ux.layout.RowFitLayout.superclass.setContainer.call(this, ct);
        this._addSliders(ct);
      },
    
      // private
      _addSliders: function(ct) {
        var sh = ct.splitHeight || this.splitHeight;
        var skip1 = true;
        var n = ct.items.length;
        for(var i = n-1; i >= 0; i--) {
          var c = ct.items.itemAt(i);
    
          this.checkRelHeight(c);
          if(c.isResizable) { // !c.rowFit.hasAbsHeight) {
            if(skip1) {
              skip1 = false;
              continue;
            }
    
            if(c.split) {
              var slider = new Ext.Panel({height:sh, isSlider: true});
              slider.el2resize = c;
              slider.addClass('x-splitbar-y');
              ct.insert(i+1, slider);
            }
          }
        }
      },
    
      /**
       * Add event listener for container children
       * @private
       */
      itemListener: function(item) {
        item.ownerCt.doLayout();
      },
      _item_show: function(comp) {
        if(!comp.isSlider && comp.sliderId) {
          var sl = comp.ownerCt.findById(comp.sliderId);
          if(!sl.isVisible()) {
            sl.show();
            return;
          }
        }
        comp.ownerCt.doLayout();
      },
      _item_hide: function(comp) {
        if(!comp.isSlider && comp.sliderId) {
          var sl = comp.ownerCt.findById(comp.sliderId);
          if(sl.isVisible()) {
            sl.hide();
            return;
          }
        }
        comp.ownerCt.doLayout();
      },
      _item_expand: function(comp) {
        this._item_show(comp);
      },
      _item_collapse: function(comp) {
        this._item_hide(comp);
      },
    
      /**
       * Event listener for the container (on add, remove)
       * @private
       */
      ctAddItem: function(ct, comp, idx) {
        // TODO: ev. add slider & splitbar
        ct.doLayout();
      },
      ctDelItem: function(ct, comp) {
        // TODO: ev. remove slider & splitbar
        ct.doLayout();
      }
    
    });
    
    
    // Split adapter
    if (Ext.SplitBar.BasicLayoutAdapter) {
    
      /**
       * @param {Ext.SplitBar} splitbar to which adapter is applied.
       *   If supplied, will set correct minSize and maxSize.
       */
      Ext.ux.layout.RowFitLayout.SplitAdapter = function(splitbar) {
        if (splitbar && splitbar.el.dom.nextSibling) {
          var next = Ext.getCmp( splitbar.el.dom.nextSibling.id ),
              resized = Ext.getCmp(splitbar.resizingEl.id);
    
          // skip abs-height non-resizable components
          while(next && (next.collapsed || !next.isVisible() || !next.isResizable)) {
            next = Ext.getCmp(next.el.dom.nextSibling.id);
          }
    
          if (next) {
            //splitbar.maxSize = (resized.height || resized.rowFit.calcAbsHeight) +
            splitbar.maxSize = (resized.rowFit.hasAbsHeight ? resized.rowFit.calcAbsHeight : resized.getSize().height) +
                               next.getInnerHeight() - 1; // seems can't set height=0 in IE, "1" works fine
          }
          splitbar.minSize = resized.getFrameHeight() + 1;
        }
      }
    
      Ext.extend(Ext.ux.layout.RowFitLayout.SplitAdapter, Ext.SplitBar.BasicLayoutAdapter, {
    
        setElementSize: function(splitbar, newSize, onComplete) {
          var resized = Ext.getCmp(splitbar.resizingEl.id);
    
          // can't resize absent, collapsed or hidden panel
          if (!resized || resized.collapsed || !resized.isVisible()) return;
    
          // resizingEl has absolute height: just change it
          if (resized.rowFit.hasAbsHeight) {
            resized.setHeight(newSize);
          }
          // resizingEl has relative height: affects next sibling
          else {
            if (splitbar.el.dom.nextSibling) {
              var nextSibling = Ext.getCmp( splitbar.el.dom.nextSibling.id );
              // skip abs-height non-resizable components
              while(nextSibling && (nextSibling.collapsed || !nextSibling.isVisible() || !nextSibling.isResizable)) {
                nextSibling = Ext.getCmp(nextSibling.el.dom.nextSibling.id);
              }
    
              var deltaAbsHeight = newSize - resized.rowFit.calcAbsHeight, // pixels
                  nsRf = nextSibling.rowFit, // shortcut
                  rzRf = resized.rowFit,
                  // pixels in a percent
                  pctPxRatio = rzRf.calcRelHeight / rzRf.calcAbsHeight,
                  deltaRelHeight = pctPxRatio * deltaAbsHeight; // change in height in percent
    
              rzRf.relHeight = rzRf.calcRelHeight + deltaRelHeight;
    
              if (nsRf.hasAbsHeight) {
                var newHeight = nextSibling.height - deltaAbsHeight;
                nextSibling.height = newHeight;
                nextSibling.setHeight(newHeight);
              }
              else {
                nsRf.relHeight = nsRf.calcRelHeight - deltaRelHeight;
              }
            }
          }
          // recalculate heights
          resized.ownerCt.doLayout();
        } // of setElementSize
    
      }); // of SplitAdapter
    }
    
    Ext.Container.LAYOUTS['row-fit'] = Ext.ux.layout.RowFitLayout;
    still missing: better handling of add- and remove-events on the container to add/remove sliders and splitbars as well.

    Now if only someone extended the ColumnLayout to have resizable columns ;-)

    Comments?

  6. #16
    Ext User
    Join Date
    Nov 2007
    Posts
    110

    Default

    I just found a little problem, probably also with the original version and not only with my modified one:
    internet explorer doesn't scroll the content of the items in the container if too large, while firefox and opera are doing just fine here. I'm getting a rendering error in a different place with those 2 browsers, but that's another story ...
    Does anybody have an idea what's going wrong here?

  7. #17

    Default Ext.ViewPort

    Hi,


    I need to add a Ext.ViewPort to an existing jsp, basically render the viewport to a div which resides in the existing jsp page.

    I found the Ext.viewport(with all its panels within) always rendered starting at leftmost and topmost point of the browser(FireFox specifically).Is it correct to try to render a Ext.ViewPort into portion of JSP? For the viewport part seems to take over the whole screen.

    Thanks a lot,

  8. #18
    Ext User DigitalSkyline's Avatar
    Join Date
    Apr 2007
    Location
    Rochester, MI
    Posts
    461

    Default

    You could've posted in help, but anyways to answer, no ViewPort is descendant of document.body, it can not reside in a div. For this you'll need to use a panel.

    ps - Isn't JSP irrelevant to the browser/discussion?

  9. #19

    Default Ext.ViewPort

    Yep, you are right. I can not render the viewport to a div.

    What i tried is to put the viewport into a ext panel and then render the panel to a div.
    The div is within an existing JSP, my hope is to embed the previous panel to the page,
    what i saw is the panel (with viewport in it) occupy the full browser screen, which is not expected of my original attempt.

    Note:can the viewport not occupy the full screen or am i wrong in expecting it not?

  10. #20
    Ext JS Premium Member
    Join Date
    Sep 2007
    Posts
    4

    Default

    Thanks for your work. Using GridPanel as items I could't get the horizontal scrollbar to show up. I changed the doLayout method to set also the panel width and now seems to work.

    Code:
    				onLayout : function(ct, target) {
    
    					Ext.ux.layout.RowFitLayout.superclass.onLayout.call(this,
    							ct, target);
    
    					if (this.container.collapsed || !ct.items
    							|| !ct.items.length) {
    						return;
    					}
    
    					// first loop: determine how many elements with relative
    					// height are there,
    					// sums of absolute and relative heights etc.
    					var absHeightSum = 0, // sum of elements' absolute heights
    					relHeightSum = 0, // sum of all percent heights given in
    										// children configs
    					relHeightRatio = 1, // "scale" ratio used in case sum <>
    										// 100%
    					noHeightCount = 0, // number of elements with no height
    										// given
    					relHeightElements = []; // array of elements with 'relative'
    											// height for the second loop
    
    					var targetSize = target.getStyleSize();
    					
    					for (var i = 0, n = ct.items.length;i < n; i++) {
    						var c = ct.items.itemAt(i);
    
    						if (!c.isVisible()) {
    							continue;
    						}
    
    						// collapsed panel is treated as an element with
    						// absolute height
    						if (c.collapsed) {
    							var h = c.getFrameHeight();
    							absHeightSum += h;
    							c.setSize({width:targetSize.width, height: h});
    							
    						} else if (c.rowFit.hasAbsHeight) { // element that has
    															// an absolute
    															// height
    							absHeightSum += c.height;
    							c.setSize({width:targetSize.width, height: c.heigh});
    
    						} else { // 'relative-heighted'
    							if (!c.rowFit.relHeight) { // element with no
    														// height given
    								//noHeightCount++;
    								absHeightSum += c.getFrameHeight();
    								c.setSize({width:targetSize.width, height: c.heigh});
    							} else {
    								relHeightSum += c.rowFit.relHeight;
    								relHeightElements.push(c);
    							}
    							
    						}
    					}
    
    					// if sum of relative heights <> 100% (e.g. error in config
    					// or consequence
    					// of collapsing/removing panels), scale 'em so it becomes
    					// 100%
    					if (noHeightCount == 0 && relHeightSum != 100) {
    						relHeightRatio = 100 / relHeightSum;
    					}
    					
    					var freeHeight = target.getStyleSize().height
    							- absHeightSum, // "unallocated" height we have
    					absHeightLeft = freeHeight; // track how much free space we
    												// have
    
    					while (relHeightElements.length) {
    						var c = relHeightElements.shift(), // element we're
    															// working with
    						relH = c.rowFit.relHeight * relHeightRatio, // height of
    																	// this
    																	// element
    																	// in
    																	// percent
    						absH = 0; // height in pixels
    
    						// no height in config
    						if (!relH) {
    							relH = (100 - relHeightSum) / noHeightCount;
    						}
    
    						// last element takes all remaining space
    						if (!relHeightElements.length) {
    							absH = absHeightLeft;
    						} else {
    							absH = Math.round(freeHeight * relH / 100);
    						}
    
    						// anyway, height can't be negative
    						if (absH < 0) {
    							absH = 0;
    						}
    
    						c.rowFit.calcAbsHeight = absH;
    						c.rowFit.calcRelHeight = relH;
    						c.setSize({width:targetSize.width, height: absH});
    						
    						absHeightLeft -= absH;
    					}
    
    					for (var i = 0, n = ct.items.length;i < n; i++) {
    						var c = ct.items.itemAt(i);
    						if (c.isSlider && c.el2resize) {
    							// this.checkRelHeight(c);
    							var split = new Ext.SplitBar(c.el, c.el2resize.el,
    									Ext.SplitBar.VERTICAL, Ext.SplitBar.TOP);
    							split
    									.setAdapter(new Ext.ux.layout.RowFitLayout.SplitAdapter(split));
    							c.el2resize.sliderId = c.getId();
    							c.el2resize = false;
    						}
    					}
    
    					if (!this.rendered) { // keep watching for changes of
    											// items
    						ct.on('add', this.ctAddItem, this);
    						ct.on('remove', this.ctDelItem, this);
    						this.rendered = true;
    					}
    				}

Page 2 of 8 FirstFirst 1234 ... LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •