2014年1月19日 星期日

Dynamic height for each different row of RichFaces' ExtendedDataTable


Problem:

When the data in the column is many, it simply take up to multiple lines but stuff are hidden behind because of the default row height












We have issues when the size of result from getDataList() in bean.java is more than one...
<rich:column label="Details" >
       <f:facet name="header">Details</f:facet>
              <a4j:repeat rowKeyVar="rowKey"
                    value="#{bean.getDataList(resourceVar.instanceId)}"    
                    var="beanData">         
                    <a4j:commandLink actionListener="#{bean.someNavigateAction}">
                       <h:graphicImage  value="xxx.gif" />                              
                    </a4j:commandLink>        
                    <h:outputText  value="#{resourceVar.instanceId}-#{rowKey}" />      
            </a4j:repeat>
</rich:column>


(check the field with FireBug, some of the fields are hidden)













Solution:

Display a link on those grids which has hidden info, user can click the link to expand/collapse the whole row to navigate complete information.















Code:

Add styleClass named 'referenceLink' for the commandLink, since the number of commandLinks in a field vary from row to row. Then we we would be able to count them via jQuery selector. And, we add a 'More' commandLink for user to click  in order to expand/collapse the field.

.xhtml

 <h:form id="resultForm1">

        <rich:extendedDataTable id="table" 
          var="resourceVar"          
          value="#{bean.resourceDataModel}"   
          rendered="#{not empty bean.resourceDataModel}" 
          rowKeyVar="row" >

          .... other columns here     



         <rich:column label="Details">

              <f:facet name="header">Details</f:facet>             
              <a4j:repeat rowKeyVar="rowKey" 
                    value="#{bean.getDataList(resourceVar.instanceId)}"               
                    var="beanData">         
                      <a4j:commandLink styleClass="referenceLink"  actionListener="#{bean.someNavigateAction}"  > <h:graphicImage  value="xxx.gif" />                              

                      </a4j:commandLink>                   
                       <h:outputText  value="#{resourceVar.instanceId}-#{rowKey}" />                           
                       <a4j:commandLink value="More" rendered="#{rowKey==0}" styleClass="expandLink" onclick="expandRow('#{resourceVar.instanceId}');"  />         
            </a4j:repeat>


         </rich:column>

</h:form>


javascript

 // invoke right after the extendedDataTable appears, remove unnecessary 'More' expand link from each row     
function adjustResultTable(){                 
             jQuery("table[id^='resultForm1']").find("tr[id^='resultForm1']").each(function(){     
             var numOfLinks = jQuery(this).find("a[class='referenceLink']").length; // how many items need to be displayed            
              if(numOfLinks<2) // doesn't need to show 'More' expand link'                
                   jQuery(this).find("a[class='expandLink']").hide();         
              });     
}      

var itemHeight = 20; // height in px for one row     
function expandRow(rowId){   
       var thisRow = jQuery("table[id^='resultForm1']").find("tr[id*='"+rowId+"'][id^='resultForm1']");        
       var expandlink = jQuery(thisRow).find("a[class='expandLink']");        
        if(expandlink[0]){     
               if(expandlink[0].innerHTML=='More'){ // expand                
                    var numOfLinks = jQuery(thisRow).find("a[class='referenceLink']").length; // how many items need to be displayed                 
                    if(numOfLinks>1){                     
                        var rowHeight = parseInt(numOfLinks*itemHeight);                     
                        jQuery(thisRow).find("td").each(function(){ // adjust the height of each grid                        
                              jQuery(this).find("div").first().css({'height':rowHeight+'px'});                    
                        });                 
                     }                 
                    expandlink[0].innerHTML = 'Less';            
               }             
               else{ // collapse                 
                    var rowHeight = itemHeight;                 
                    jQuery(thisRow).find("td").each(function(){ // adjust the height of each grid                    
                        jQuery(this).find("div").first().css({'height':rowHeight+'px'});                 
                    });                 
                    expandlink[0].innerHTML = 'More';             
               } // end of else        
          } // end of if(expandLink[0])
}      

Other notes:
1,It doesn't work well if we simply adjust the height on the <tr> level












2.In our expandRow() javascript function, we adjust the height of each first div inside <td> inside the row step by step:
(the first td)
(the second td)

(all the height of div inside td are changed, then the expansion is finished)


3.jQuery("table[id^='resultForm1']").find("tr[id*='"+rowId+"'][id^='resultForm1']");   

I happened to notice that, for the id of <tr> for each row, the prefix would be like "resultForm1:table:xxxxx": resultForm is the id of <h:form>, table is the id of <rich:extendedDataTable>, and xxxxx would be the instanceId of the data this row represent. So we can take advantage of this pattern in javascript to find the correct row to expand/collapse.



4.This solution might look like a workaround, but I couldn't found any existing built-in solution in RichFaces extendedDataTable. The following links are the related discussion I have traced on the internet:


https://community.jboss.org/thread/231328 http://stackoverflow.com/questions/14258514/richfaces-extendeddatatable-header-size-mismatches-column-size-when-set-to-auto 
https://community.jboss.org/thread/170991https://github.com/richfaces4/components/blob/master/iteration/ui/src/main/resources/META-INF/resources/org.richfaces/extendedDataTable.js#L309
 https://community.jboss.org/thread/170991 
http://stackoverflow.com/questions/963971/how-to-conditionally-style-a-row-in-a-richdatatable
 
https://community.jboss.org/thread/234159?_sscc=t
  


沒有留言:

張貼留言