Right Panel

From WikiSky

Jump to: navigation, search

Description

Data panel with dynamic foldable items. The class rightPanel creates instance of panel container in the parent html element provided in parameter ("parent") all elements have ability to collapse/expand. Collapsed elements on top followed by expanded elements. If element doesn't fit into the panel scrollbar appears. Multiple expanded elements share the panel space equally.

Examples

Source code

   /***********************************************
   * Data panel with dynamic foldable items (www.wikisky.org)
   * The class rightPanel creates instance of panel container
   * in the parent html element provided in parameter ("parent")
   * all elements have ability to collapse/expand. Collapsed elements on top
   * followed by expanded elements. If element doesn't
   * fit into the panel scrollbar appears. Multiple expanded elements share
   * the panel space equally.
   * Visit WIKISKY.ORG at http://www.wikisky.org/wiki/ for full source code
   ***********************************************/

   // manage right panel operations
   function rightPanel(parent) {

       this.parent=parent;
       this.toShow = false;

       this.d_main=document.createElement("DIV");
       this.style = this.d_main.style;
       this.d_main.style.visibility='hidden';
       this.d_main.style.border="0px";
       this.d_main.style.margin="0px";
       this.d_main.style.padding="0px";
       this.d_main.style.position="absolute";
       this.d_main.style.left="0px";
       this.d_main.style.top="0px";
       this.d_main.style.width="250px";
       this.d_main.style.height="20px";
       this.d_main.style.overflow="hidden";
       this.parent.appendChild(this.d_main);

       //this.left=this.d_main.offsetLeft;
       this.top=this.d_main.offsetTop;
       this.right=this.d_main.offsetLeft+this.d_main.offsetWidth;
       this.bottom=this.d_main.offsetTop+this.d_main.offsetHeight;
       this.width = this.d_main.offsetWidth;
       this.height = this.d_main.offsetHeight;
       this.minWidth = this.width;
       this.items = new Array();
       this.spaceBetweenItems = 5;
       this.onresize = rightPanel_onresize;
       this.updateWidth = rightPanel_updateWidth;
       this.getMinTitleWidth = rightPanel_getMinTitleWidth;
       this.addItem = rightPanel_addItem;
       this.show = function(b) { this.toShow=b; this.onresize(); }
   }

   function rightPanel_onresize() {
       if (!this.toShow) {
           this.d_main.style.visibility='hidden';
           return;
       }
       this.d_main.style.top = this.top+'px';
       var h=this.bottom-this.top;
       this.d_main.style.left = (this.right-this.d_main.offsetWidth)+'px';
       var exp=new Array();
       //show collapsed items first
       var pos_y=0;
       for(var i in this.items) {
           var item=this.items[i];
           if (item.visible()) {
               item.onresize();
               //alert('item='+item+', isExpanded='+item.isExpanded+', setY='+item.setY);
               if (item.isExpanded) {
                   exp.push(item);
               } else {
                   item.setY(pos_y);
                   item.resetHeight();
                   pos_y += item.getHeight()+this.spaceBetweenItems;
               }
           }
       }
       //show expanded items dividing remaining space equailly
       if (exp.length>0) {
           this.updateWidth(this.width);
           var rm = h-pos_y-2;
           var hItem = Math.round((rm - this.spaceBetweenItems*(exp.length-1))/exp.length);
           var rm2=rm,n2=0;
           for(var i=0; i<exp.length; i++) {
               var item=exp[i];
               item.setY(pos_y);
               item.resetHeight();
               if (item.getHeight()>hItem) n2++; else rm2-=item.getHeight()+this.spaceBetweenItems;
           }
           if (n2<=1) hItem=rm2; else hItem=Math.round((rm2 - this.spaceBetweenItems*(n2-1))/n2);

           //find item to apply reminder caused by rounding
           var itemToApplyRem=-1;
           var t_rm=rm;
           for(var i=0; i<exp.length; i++) {
               var item=exp[i];
               var a=item.getHeight();
               if (a>hItem) {itemToApplyRem=i; a=hItem; }
               t_rm -= a + (i+1<exp.length ? this.spaceBetweenItems : 0);
           }

           //show expanded items
           for(var i=0; i<exp.length; i++) {
               var item=exp[i];
               item.setY(pos_y);
               item.resetHeight();
               var a=item.getHeight();
               if (a>hItem) a=hItem+(i==itemToApplyRem?t_rm:0);
               pos_y += a;
               rm -= a;
               item.setHeight(a);
               if (i+1<exp.length) {
                   pos_y+=this.spaceBetweenItems;
                   rm-=this.spaceBetweenItems;
               }
           }
       } else { //if all items are collapsed
           this.updateWidth(Math.min(this.width, Math.max(this.minWidth,this.getMinTitleWidth())));
       }
       if (pos_y==0) {
           this.d_main.style.visibility='hidden';
       } else {
           this.d_main.style.visibility='visible';
           this.d_main.style.height = Math.min(h,pos_y+2)+'px';
       }
       //alert('this.height='+this.height+', h='+h);
       if (h>=0) this.d_main.style.height = (h+(document.all?2:0))+'px';
   }

   function rightPanel_updateWidth(w) {
       this.d_main.style.width=(w-(document.all?0:2))+'px';
       this.d_main.style.left = (this.right-this.d_main.offsetWidth)+'px';
       for(var i in this.items) {
           this.items[i].updateWidth(w);
       }
   }

   function rightPanel_getMinTitleWidth() {
       var minWidth=this.width;
       for(var i in this.items) {
           var item=this.items[i];
           if (item.visible()) {
               var t=item.getMinTitleWidth();
               if (minWidth>t) minWidth=t;
           }
       }
       //alert('rightPanel.getMinTitleWidth(): minWidth='+minWidth);
       return minWidth;
   }

   function rightPanel_addItem(title) {
       var t=new rightPanelItem(this, title);
       this.items.push(t);
       return t;
   }

   function rightPanelItem(parentObj, title) {
       this.parentObj = parentObj;
       this.title = title;
       this.isExpanded = false; //do not change the value from outside, use expand() and collapse() methods instead

       this.d_main=document.createElement("SPAN");
       this.d_main.style.visibility='hidden';
       this.d_main.style.border="1px solid gray";
       this.d_main.style.position="absolute";
       this.d_main.style.left="0px";
       //this.d_main.style.display="inline";
       this.parentObj.d_main.appendChild(this.d_main);

       this.d_bg=document.createElement("DIV");
       this.d_bg.style.position="absolute";
       this.d_bg.style.left="0px";
       this.d_bg.style.top="0px";
       this.d_bg.style.width="100%";
       this.d_bg.style.height="100%";
       this.d_bg.style.margin="0px";
       this.d_bg.style.backgroundColor='black';
       this.d_bg.style.opacity=0.5;
       this.d_bg.style.filter='alpha (opacity=50)';
       this.d_main.appendChild(this.d_bg);

       this.d_title=document.createElement("SPAN");
       this.d_title.parentItem=this;
       //this.d_title.style.border="1px solid green";
       this.d_title.style.position="absolute";
       this.d_title.style.left="0px";
       this.d_title.style.top="0px";
       this.d_title.style.width="100%";
       this.d_title.style.height="16px";
       this.d_title.style.overflow="hidden";
       this.d_title.style.backgroundColor="#404040";
       this.d_title.style.color="white";
       this.d_title.style.fontSize="8pt";
       this.d_title.innerHTML=' '+this.title;
       this.d_title.style.cursor='pointer';
       this.d_title.onclick=function() { this.title=='Collapse'?this.parentItem.collapse():this.parentItem.expand(); }
       this.d_main.appendChild(this.d_title);

       this.btn_close = new Image;
       this.btn_close.parentItem = this;
       this.btn_close.border=0;
       this.btn_close.style.position='absolute';
       this.btn_close.style.left = (this.parentObj.d_main.offsetWidth-19)+'px';
       this.btn_close.style.top  = '0px';
       this.btn_close.style.width = '15px';
       this.btn_close.style.height = '15px';
       this.btn_close.style.visibility=;
       this.btn_close.srcCollapse = 'img/collapse.gif';
       this.btn_close.srcExpand = 'img/expand.gif';
       this.btn_close.GALLERYIMG='no';
       this.btn_close.title = 'Collapse';
       this.btn_close.style.cursor='pointer';
       this.btn_close.onclick=function() { this.title=='Collapse'?this.parentItem.collapse():this.parentItem.expand(); }
       this.d_main.appendChild(this.btn_close);

       this.d_body=document.createElement("SPAN");
       this.d_body.parentItem=this;
       //this.d_body.style.borderBottom="1px solid red";
       this.d_body.style.position="absolute";
       this.d_body.style.left="0px";
       this.d_body.style.top=(this.d_title.offsetTop+this.d_title.offsetHeight)+"px";
       this.d_body.style.width="100%";
       this.d_body.style.overflowX="hidden";
       this.d_body.style.overflowY="auto";
       //this.d_body.style.backgroundColor="green";
       this.d_body.style.color="white";
       this.d_body.style.fontSize="8pt";
       //this.d_body.style.visibility='hidden';
       //this.d_body.innerHTML='test';
       this.d_main.appendChild(this.d_body);

       this.show = function(b) { this.d_main.style.visibility=b?:'hidden'; }
       this.visible = function(b) { return this.d_main.style.visibility!='hidden'; }
       this.setY = function(y) { this.d_main.style.top = y+'px'; }
       this.setHeight = function(h) { this.d_body.style.height = (h-this.d_body.offsetTop)+'px'; this.onresize(); }
       this.getHeight = function(h) { return this.d_title.offsetHeight+(this.isExpanded?this.d_body.offsetHeight:0); }
       this.resetHeight = function(h) { this.d_body.style.height = null; }
       this.onresize = function() {
           this.d_main.style.width=(this.parentObj.d_main.offsetWidth-(document.all?0:2))+"px";
           this.d_main.style.height=(this.getHeight()+(document.all?2:0))+"px";
           this.btn_close.src=this.isExpanded?this.btn_close.srcCollapse:this.btn_close.srcExpand;
           this.btn_close.title = this.isExpanded?'Collapse':'Expand';
           this.d_title.title = this.isExpanded?'Collapse':'Expand';
           this.d_body.style.visibility=this.isExpanded ?  : 'hidden';
       }
       this.updateWidth = function(w) {
           this.d_main.style.width=(w-(document.all?0:2))+"px";
           this.btn_close.style.left = (w-17)+"px";
       }
       this.getMinTitleWidth = function() {
           var t=this.d_title.style.width;
           this.d_title.style.width=;
           this.d_title.innerHTML=this.d_title.innerHTML;
           var r=this.d_title.offsetWidth+this.btn_close.offsetWidth+2;
           this.d_title.style.width=t;
           //alert('getMinTitleWidth(): '+r);
           return r;
       }
       this.collapse = function() { this.isExpanded=false; if (this.onCollapse) this.onCollapse(); this.parentObj.onresize(); }
       this.expand = function() { this.isExpanded=true; if (this.onExpand) this.onExpand(); this.parentObj.onresize(); }
       this.setTitle = function(t) {
           this.d_title.innerHTML=this.title=t;
           this.parentObj.onresize();
       }
       this.setBody = function(t) {
           var scrollTop = this.d_body.scrollTop;
           this.d_body.innerHTML=t;
           if (scrollTop>0) this.d_body.scrollTop=scrollTop;
           this.parentObj.onresize();
       }

       this.onresize();
   }
Personal tools