8 Replies Latest reply on Dec 28, 2007 9:25 AM by Florian Marwede

    Nice to have: Layout slide effect

    Florian Marwede Expert

      Hi!

      At the moment I'm very interested in constructing a layout where you can minimize/maximize a div by a click so it slides aside with an effect. I will explain what I mean in detail.

      Let's assume we have a simple overall layout like that:

      <h:panelGrid columns="2">
       <h:panelGrid columns="1">
       <t:htmlTag value="div" id="TreeNavigator">
       ...
       </t:htmlTag>
       <t:htmlTag value="div" id="Properties">
       ...
       </t:htmlTag>
       </h:panelGrid>
       <h:panelGrid columns="1">
       <t:htmlTag value="div" id="MainArea">
       ...
       </t:htmlTag>
       <t:htmlTag value="div" id="Messages">
       ...
       </t:htmlTag>
       </h:panelGrid>
      </h:panelGrid>
      


      In each of this four big blocks on the page is a rich:panel or a rich:tabPanel or something like that.

      Now let's assume a default state where each of these blocks have the size the developer thought it was useful to have.

      What I wanna have: The user clicks a button and the two left panels slide to the left side, where only a narrow bar (20 px width) remains. The two right panels get at the same time a bigger size so you can see more content of them.
      With a click on the narrow bar on the left side you can switch back to the default layout state and of course you can do the same thing to the other side and up and down.

      Without effect it should be easy to create that with a rich:togglepanel, I think. But can I combine that with (for example) rich:effect to have these slide effects?

      My question is: Has anyone experiences with such great layout effects at all? Has anyone create something like that (or something similar) with Richfaces components? Has anyone ideas to combine Richfaces components with other stuff to reach this aim?

      I will try that anyway, but if anyone of you is interested in that, we can try to develop a template for such a dynamic layout together for our Richfaces cookbook...

        • 1. Re: Nice to have: Layout slide effect
          Dmitry Demyankov Novice

          I'm interested in such kind of funtionality but so far got no idea it might be implemented :)

          • 2. Re: Nice to have: Layout slide effect
            Florian Marwede Expert

            Hmm...doesn't seem to be very interesting for the most of you at all ;-)

            The best idea I had so far was to copy the code from the richfaces demo. I mean the nice effect we see when we click on "View Source" and "Hide Source".
            Problem: Here we have an effect from 0% to 100% size and backwards. But for my dynamic layout I need also an effect, that scales up a panel in the way another panel makes room for it (or scales down when another panel shows up again).

            Is that possible at all with that scriptaculous BlindUp/BlindDown effects?

            • 3. Re: Nice to have: Layout slide effect
              tomek golembiewski Newbie

              I've used jQuery for this kind of effect.
              the menu is hiding or showing when You click on #menuSwiche div
              Its possible to get functionality you need with this method

              main template:

              <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
              <html xmlns="http://www.w3.org/1999/xhtml"
               xmlns:ui="http://java.sun.com/jsf/facelets"
               xmlns:h="http://java.sun.com/jsf/html"
               xmlns:f="http://java.sun.com/jsf/core"
               xmlns:a4j="http://richfaces.org/a4j"
               xmlns:rich="http://richfaces.org/rich" ><f:loadBundle basename="resources" var="msg" />
              <head>
               <meta http-equiv="Content-Type" content="text/xhtml; charset=UTF-8"/>
               <a4j:loadScript src="/js/equalcolumns.js"/>
               <a4j:loadStyle src="/css/style.css" />
               <title>
               <ui:insert name="title"/>
               </title>
               </head>
              <body>
              <rich:jQuery name="hideMenu" timing="onJScall" query="toggle('slow');return false;" />
               <rich:jQuery selector="#menuSwitch" timing="onload" query="click(function(){hideMenu('#menu');})" />
              
              <div id="container">
              <div id="header"><h1>Header</h1></div>
              
              <div id="wrapper">
              <table id="slider">
               <tr><td id="slider1"><div id="menu">
               lslslslslslslsl<br/>
               lslslslslslslsl<br/>
               aaaa<br/>
               lslslslslsl<br/>
               </div>
               </td>
               <td><div id="menuSwitch">aa</div></td>
               <td id="slider2"><ui:insert name="body"/></td>
               </tr>
              </table>
              </div>
              <div id="footer"><p>Here it goes the footer</p></div>
              </div>
              </body>
              </html>
              
              


              layout to see something:

              html,body{margin:0;padding:0}
               body{font: 76% arial,sans-serif}
               p{margin:0 10px 10px}
               a{display:block;color: #981793;padding:10px}
               div#header h1{height:80px;line-height:80px;margin:0;
               padding-left:10px;background: #EEE;color: #79B30B}
               div#content p{line-height:1.4}
               div#navigation{background:#B9CAFF}
               div#extra{background:#FF8539}
               div#footer{background: #333;color: #FFF}
               div#footer p{margin:0;padding:5px 10px}
               div#wrapper{float:right;width:100%;margin-left:-200px}
               div#content{margin-left:auto}
               div#navigation{float:left;width:auto}
               div#extra{float:left;clear:left;width:auto}
               div#footer{clear:both;width:100%}
               table#slider{width: 100%; border: solid 1px;vertical-align: top;}
               td#slider1{width: 0%;background: #EEE; vertical-align: top;}
               td#slider2{width: 100%;background: #EEE; vertical-align: top;}
               div#menu{width: 100px;background: #EEE; vertical-align: top; border: solid black 1px;}
               td#menuSwicth{width:40px;}
               div#menuSwicth{width:40px;}


              • 4. Re: Nice to have: Layout slide effect
                Florian Marwede Expert

                Thanks for your reply!

                I still have this topic in mind but in the last months too much other things to do. I'll try to expand this sample concerning to the scenario I described and post it.

                By the way...at the moment I'm thinking about the next requirement:

                Minimizing one panel, expand another to fill the room AND open a new window with the minimized panel (in full size) with one button click. So the user can drag and drop the new window on his second screen...of course there should be a possibility to do this backwards...again with one click.

                • 5. Re: Nice to have: Layout slide effect
                  Florian Marwede Expert

                  Hey folks!

                  Here a little appetizer for you:

                  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
                  <html xmlns="http://www.w3.org/1999/xhtml"
                   xmlns:ui="http://java.sun.com/jsf/facelets"
                   xmlns:h="http://java.sun.com/jsf/html"
                   xmlns:f="http://java.sun.com/jsf/core"
                   xmlns:a4j="http://richfaces.org/a4j"
                   xmlns:rich="http://richfaces.org/rich" >
                  
                  <head>
                   <meta http-equiv="Content-Type" content="text/xhtml; charset=UTF-8"/>
                   <style type="text/css">
                  <!--
                  html,body{margin:0;padding:0}
                   body{font: 76% arial,sans-serif}
                   p{margin:0 10px 10px}
                   a{display:block;color: #981793;padding:10px}
                   div#header h1{height:80px;line-height:80px;margin:0;
                   padding-left:10px;background: #EEE;color: #79B30B}
                   div#content p{line-height:1.4}
                   div#navigation{background:#B9CAFF}
                   div#extra{background:#FF8539}
                   div#footer{background: #333;color: #FFF}
                   div#footer p{margin:0;padding:5px 10px}
                   div#wrapper{float:right;width:100%;margin-left:-200px}
                   div#content{margin-left:auto}
                   div#navigation{float:left;width:auto}
                   div#extra{float:left;clear:left;width:auto}
                   div#footer{clear:both;width:100%}
                   table#slider{width: 100%; border: solid 1px;vertical-align: top;}
                   td#slider1{width: 0%;background: #EEE; vertical-align: top;}
                   td#slider2{width: 100%;background: #EEE; vertical-align: top;}
                   div#menu{width: 100px;background: #EEE; vertical-align: top; border: solid black 1px;}
                   td#menuSwitch{width:40px;}
                   div#menuSwitch{width:40px;}
                  -->
                  </style>
                   </head>
                  <body>
                  <rich:jQuery name="hideMenu" timing="onJScall" query="slideToggle('slow');return false;" />
                   <rich:jQuery selector="#menu" timing="onload" query="click(function(){hideMenu('#menu');})" />
                   <rich:jQuery selector="#menuSwitch" timing="onload" query="click(function(){hideMenu('#menuSwitch');})" />
                   <rich:jQuery selector="#menu" timing="onload" query="click(function(){hideMenu('#menuSwitch');})" />
                   <rich:jQuery selector="#menuSwitch" timing="onload" query="click(function(){hideMenu('#menu');})" />
                  <div id="container">
                  <div id="header"><h1>Header</h1></div>
                  
                  <div id="wrapper">
                   <table id="slider">
                   <tr>
                   <td id="slider1">
                   <div id="menu">
                   lslslslslslslsl<br/>
                   lslslslslslslsl<br/>
                   aaaa<br/>
                   lslslslslsl<br/>
                   </div>
                   </td>
                   </tr>
                   <tr>
                   <td>
                   <div id="menuSwitch" style="display:none">
                   lslslslslslslsl<br/>
                   lslslslslslslsl<br/>
                   aaaa<br/>
                   lslslslslsl<br/>
                   </div>
                   </td>
                   </tr>
                  </table>
                  </div>
                  <div id="footer"><p>Here it goes the footer</p></div>
                  </div>
                  </body>
                  </html>
                  


                  There's still some work to do but this is the right direction. Next post tomorrow I hope...

                  • 6. Re: Nice to have: Layout slide effect
                    tomek golembiewski Newbie

                    As You see it's trivial with JQuery. I've play around a few minutes with "appetizer" and found a funny fluctuation of a footer during animating.
                    Liitle change in css and I manage to separate the footer from animation.

                     div#wrapper{float:right;width:100%;margin-left:-200px; height: 100px}
                     div#menu{width: 100px;background: #EEE; vertical-align: top; border: solid black 1px; height: 83px}
                     div#menuSwitch{width: 100px;background: #EEE; vertical-align: top; border: solid black 1px; height: 83px}
                    BTW:
                    

                    strange it takes exactly 17px to separate :)
                    Minimizing one panel, expand another to fill the room AND open a new window with the minimized panel (in full size) with one button click. So the user can drag and drop the new window on his second screen...of course there should be a possibility to do this backwards...again with one click.

                    It should be possible with this aproach, You can add anything U like to query:
                    slideToggle('slow');return false;

                    fte:
                    slideToggle('slow');openMyNewNiceWindow();return false;

                    The point is what window You want to open, ugly standard browser window or nice dragable such that in modalPanel component.
                    Anyway IMHO its possible to do with JQuery




                    • 7. Re: Nice to have: Layout slide effect
                      Florian Marwede Expert

                      Hi and thanks for killing this fluctuation!

                      I did the following:

                      1.) Tried to remove some things we don't need to get this working sample as small as possible (I hope I didn't remove anything important.)

                      2.) Using rich:panels and sliding is only called by clicking the headers.

                      3.) onmouseover you get a pointer as cursor

                      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
                      <html xmlns="http://www.w3.org/1999/xhtml"
                       xmlns:ui="http://java.sun.com/jsf/facelets"
                       xmlns:h="http://java.sun.com/jsf/html"
                       xmlns:f="http://java.sun.com/jsf/core"
                       xmlns:a4j="http://richfaces.org/a4j"
                       xmlns:rich="http://richfaces.org/rich" >
                      
                      <head>
                       <meta http-equiv="Content-Type" content="text/xhtml; charset=UTF-8"/>
                       <style type="text/css">
                       <!--
                       html,body{margin:0;padding:0}
                       body{font: 76% arial,sans-serif}
                       h1 {height:80px;line-height:80px;margin:0;
                       padding-left:10px;background: #EEE;color: #79B30B}
                       div#footer{background: #333;color: #FFF}
                       div#footer{clear:both;width:100%}
                       div#wrapper{float:right;width:100%;margin-left:-200px; height: 100px}
                       div#panel1{width: 100px;background: #EEE; vertical-align: top; border: solid black 1px; height: 83px}
                       div#panel2{width: 100px;background: #EEE; vertical-align: top; border: solid black 1px; height: 83px}
                       -->
                       </style>
                       </head>
                      <body>
                       <rich:jQuery name="hideMenu" timing="onJScall" query="slideToggle('slow');return false;" />
                       <rich:jQuery selector="#header1" timing="onload" query="click(function(){hideMenu('#panel1');})" />
                       <rich:jQuery selector="#header2" timing="onload" query="click(function(){hideMenu('#panel2');})" />
                       <rich:jQuery selector="#header1" timing="onload" query="click(function(){hideMenu('#panel2');})" />
                       <rich:jQuery selector="#header2" timing="onload" query="click(function(){hideMenu('#panel1');})" />
                      
                      <h1>Header</h1>
                      
                      <div id="wrapper">
                      <h:panelGrid columns="1">
                       <rich:panel id="panel1">
                       <f:facet name="header">
                       <div id="header1" onmouseover="this.style.cursor='pointer'">My Panel One</div>
                       </f:facet>
                      
                       lslslslslslslsl<br/>
                       lslslslslslslsl<br/>
                       aaaa<br/>
                      
                       </rich:panel>
                       <rich:panel id="panel2" style="display:none">
                       <f:facet name="header">
                       <div id="header2" onmouseover="this.style.cursor='pointer'">My Panel Two</div>
                       </f:facet>
                       lslslslslslslsl<br/>
                       lslslslslslslsl<br/>
                       aaaa<br/>
                      
                       </rich:panel>
                      </h:panelGrid>
                      </div>
                      <div id="footer">Here it goes the footer</div>
                      
                      </body>
                      </html>


                      The next step (and most difficult, I think) is to implement the requirement I described in first posting: Both panels are visible on default and you have the possibility to minimize one panel (and maximize the other at the same time) AND then you can get to a default state again.
                      This is what I mean by saying the problem is that's only possible to slide from 0 to 100% and back and not let's say to 50%.

                      I hope it's clear what I want (i'm no native speaker).

                      • 8. Re: Nice to have: Layout slide effect
                        Florian Marwede Expert

                        Okay, it is not very difficult at all ;-) The last mentioned problem can be solved with jquery animate function.

                        <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
                        <html xmlns="http://www.w3.org/1999/xhtml"
                         xmlns:ui="http://java.sun.com/jsf/facelets"
                         xmlns:h="http://java.sun.com/jsf/html"
                         xmlns:f="http://java.sun.com/jsf/core"
                         xmlns:a4j="http://richfaces.org/a4j"
                         xmlns:rich="http://richfaces.org/rich" >
                        
                        <head>
                         <meta http-equiv="Content-Type" content="text/xhtml; charset=UTF-8"/>
                         <style type="text/css">
                         <!--
                         html,body{margin:0;padding:0}
                         body{font: 76% arial,sans-serif}
                         h1 {height:80px;line-height:80px;margin:0;
                         padding-left:10px;background: #EEE;color: #79B30B}
                         div.footer{background: #333;color: #FFF}
                         div.footer{clear:both;width:100%}
                         div#wrapper{float:right;width:100%;margin-left:-200px; height: 302px}
                         div#panel1{width: 150px; background: #EEE; vertical-align: top; border: solid black 1px; height: 284px}
                         div#panel2{width: 150px; background: #EEE; vertical-align: top; border: solid black 1px; height: 0px}
                         -->
                         </style>
                         </head>
                        <body>
                         <rich:jQuery name="panelDefault" timing="onJScall" query="animate({height: 142}, 500);return false;" />
                         <rich:jQuery name="panelMin" timing="onJScall" query="slideUp(500);return false;" />
                         <rich:jQuery name="panelNull" timing="onJScall" query="height(0);return false;" />
                         <rich:jQuery name="panelMax" timing="onJScall" query="animate({height: 284}, 500);return false;" />
                        
                         <rich:jQuery selector="#toDefaultFromPanel1" timing="onload" query="click(function(){panelNull('#panel2'); panelDefault('#panel1');panelDefault('#panel2');})" />
                         <rich:jQuery selector="#toDefaultFromPanel2" timing="onload" query="click(function(){panelNull('#panel1'); panelDefault('#panel1');panelDefault('#panel2');})" />
                         <rich:jQuery selector="#maxPanel1" timing="onload" query="click(function(){panelMax('#panel1');panelMin('#panel2'); })" />
                         <rich:jQuery selector="#maxPanel2" timing="onload" query="click(function(){panelMax('#panel2');panelMin('#panel1'); })" />
                        
                        <h1>Header</h1>
                        
                        <div id="wrapper">
                        <h:panelGrid columns="1">
                         <rich:panel id="panel1">
                         <f:facet name="header">
                         <div id="header1" onmouseover="this.style.cursor='pointer'">My Panel One</div>
                         </f:facet>
                         lslslslslslslsl<br/>
                         lslslslslslslsl<br/>
                         aaaa<br/>
                         </rich:panel>
                         <rich:panel id="panel2" style="display:none">
                         <f:facet name="header">
                         <div id="header2" onmouseover="this.style.cursor='pointer'">My Panel Two</div>
                         </f:facet>
                         lslslslslslslsl<br/>
                         lslslslslslslsl<br/>
                         aaaa<br/>
                         </rich:panel>
                        </h:panelGrid>
                        </div>
                        <div id="toDefaultFromPanel1" class="footer">Click for default from panel 1 max!</div>
                        <br />
                        <div id="toDefaultFromPanel2" class="footer">Click for default from panel 2 max!</div>
                        <br />
                        <div id="maxPanel1" class="footer">Click for max panel1!</div>
                        <br />
                        <div id="maxPanel2" class="footer">Click for max panel2!</div>
                        </body>
                        </html>


                        Next steps:

                        1.) There are lot's of combinations of click paths making no sense. We have to forbid them to avoid funny effects.

                        2.) When we wanna have not two panels but four and you wanna slide them back and forth in all combinations we need a lot of code if we do it that way I posted above. I hope it's possible to parametrize these functions to do that with little code.

                        3.) I'm afraid the fluctuation is back again with the current version...

                        4.) Of course it is not a pretty solution to put the controls to those footers. The controls should lay on nice little buttons with symbols easy to understand. But this we can do at the end I think.

                        Every suggestion, note or critique is still welcome!