14 Replies Latest reply on Apr 30, 2007 3:11 PM by sergeysmirnov

    show details when clicking on a table row?

    baz

      Hello,
      i do have a running app which is initially generated with seamgen. So it uses richfaces together with the seam application framework. Now i have to make this app more user responsive.
      What should be done is:
      Whenever the user clicks on a table row (or is inside an input element of the row) the details of the row should be shown on the same page.

      At the moment this is achieved through a link on every page.

      The outline of the page is like this:

      [...]
      <rich:panel>
      [...]
       <h:outputText value="#{detailbean.detail1}"
      [...]
      <rich:panel>
      [...]
      <rich:dataTable var="row"
       value="#{masterList.resultList}"
       rendered="#{not empty masterList.resultList}">
      [...]
       </rich:column>
       <rich:column>
       #{row..data1}
       </rich:column>
       <rich:column>
       <s:link value="View">
       <f:param name="detailId" value="#{row.details.id}"/>
       </s:link>
       </rich:column>
      [...]
      </rich:dataTable>
      [...]
      


      deteilbean is an EntityHome object instanciated through the page parameter detailId

      Whenever the user clicks on the View-link the page is reloaded and the corresponding detail is shown at the top of the page.
      I have to make this dynamic. The user clicks on a row and the row is highlighted plus the details are shown.

      For highlighting i can use the rich:datatable attribute onRowClick
      onRowClick="this.style.backgroundColor='#F1F1F1'"
      How to reset this row when an other row is clicked?

      But how can i get the current row in an action[listener] issued from a4j:support for this row.
      <h:inputText value="#{row.data1}">
       <a4j:support action="???" event="onClick" reRender="opanel"></a4j:support>
       </h:inputText>
      

      Questions:
      How to get the object from the current row?
      This should function by only clicking on a row. How can i achieve this?

      Or i am thinking in a complete wrong direction?
      Ciao,
      Carsten

        • 1. Re: show details when clicking on a table row?

          I cannot say that the direction is completely wrong (or wrong completely). rich:dataTable has not selection model out-of-the-box. So, it is your job to provide it in your particular application. The strategy how to accomplish it might be vary. You can write a javascript that scan DOM tree and reset the selection, you can assign the javascript object and store the information about selection there, you can store state in the hidden field for further use or not. What strategy to select is up to you.

          Getting the object from the current row with Ajax command component is the same as for non-ajax ones. If your data extends DataModel, the information about current row presents in the event.

          • 2. Re: show details when clicking on a table row?
            zenshai

            Hi,

            I am working on a similar problem. I have managed to find here on the forums how to send information about a selected row to the server. Now all i need is to color that row so that the user knows its selected. The live-demo uses something like

            onRowClick="this.style.backgroundColor='#cc0106'"

            however when I try to implement logic like check what the color of the row is before i change it i find that the this.style object is null. Perhaps im approaching this the wrong way.

            Maybe you can clarify your reply above a little:

            When you say:

            "SergeySmirnov" wrote:
            You can write a javascript that scan DOM tree and reset the selection, you can assign the javascript object and store the information about selection there, you can store state in the hidden field for further use or not.


            What would I be scanning the DOM for?
            What do you mean by "assign the javascript object"?
            Is there a javascript object for each row? and if there is does it have an index property I can use to remember which row is selected?


            • 3. Re: show details when clicking on a table row?
              tbrown_01923

              var styleHolder ;
              var clickedRow ;

              function onOver(elmt) {
              styleHolder = elmt.className;
              elmt.className = 'Over'
              }

              function onOut(elmt) {
              if(elmt.className != 'Selected') {
              elmt.className = styleHolder;
              }
              }

              function onClick(elmt) {
              for(var n = 0; n &lt; elmt.parentElement.children.length; n++) {
              elmt.parentElement.children[n].className = (n % 2 == 0) ? 'Odd' : 'Even' ;
              }
              elmt.className = 'Selected'
              // implment your code to store value such as

              var val = findDescendantByName(elmt, 'selectValue') ;
              clickedRow = val.value ;
              }

              <rf:dataTable ...
              onRowMouseOver="onOver(this)"
              onRowMouseOut="onOut(this)"
              onRowClick="onClick(this)"
              />

              • 4. Re: show details when clicking on a table row?
                tbrown_01923

                oops... too anxious on submit. I used classes to apply styles for mouseover and selected rows. Any time you are over a row remember what the style was before...

                The only gotcha is my default row styles vary between odd and even. Before and row is selected (onclick) I need to deselect previous rows... so I need to reset the classes thus the for loop in the onClick Handler.

                • 5. Re: show details when clicking on a table row?
                  zenshai

                  Many thanks, you saved me a whole lot of of time.

                  • 6. Re: show details when clicking on a table row?
                    zenshai

                    only thing is im getting an error in onClick:

                    elmt.parentElement has no properties


                    trying to figure it out myself, but if anyone can help it would be greatly appreciated.

                    • 7. Re: show details when clicking on a table row?
                      zenshai

                      found the problem, its "parentNode.childNodes", your version only works in IE .

                      Thanks again.

                      • 8. Re: show details when clicking on a table row?
                        baz

                        @Zenshai

                        I have managed to find here on the forums how to send information about a selected row to the server.


                        Would you be so kind to send me a pointer to the information, or even better share your solution with us?
                        Ciao,
                        Carsten

                        • 9. Re: show details when clicking on a table row?
                          zenshai

                          Sure, sorry about that, for some reason I thought your question was answered.

                          This is the method I have in the backing bean:

                          public void rowSelected(ActionEvent event) {
                           Integer currIndex = getTable().getRowIndex();
                           List allData = (List) getTable().getValue();
                           this.currRow = (TableRow) allData.get(currIndex);
                           System.out.println("@#@#@#@#@#@#@: ROW: "+currRow.getRequestId()+" "+currRow.getCreator()+" "+currRow.getState()+" "+currRow.getDescription());
                           }


                          TableRow is just a POJO i made, with only properties and getters/setters for each column.

                          And this is what my table looks like:

                          <rich:dataTable
                           onRowMouseOver="onRowOver(this)"
                           onRowMouseOut="onRowOut(this)"
                           onRowClick="onRowClick(this)"
                           cellpadding="0" cellspacing="0"
                           width="700" border="0" value="#{ajaxhelper.requestList}" var="row"
                           binding="#{ajaxhelper.table}" >
                           <a4j:support event="onRowClick" actionListener="#{ajaxhelper.rowSelected}"/>
                           <rich:column>
                           <f:facet name="header">
                           <h:outputText value="Request ID"/>
                           </f:facet>
                           <h:outputText value="#{row.requestId}"/>
                          ........
                          </rich:dataTable>


                          • 10. Re: show details when clicking on a table row?
                            tbrown_01923

                            My version is only intended to work in IE at this point. The otehr way of resetting the rows is getting the Table node by call document.getElelementById...

                            To which I use a helper method (assuming many forms, but elements are uniquely ID'd across them...)

                            function findFormElement(elementId) {
                            var i = 0 ;
                            for(i = 0; i &lt; document.forms.length; i++) {
                            if(document.getElementById(document.forms.id + ':' + elementId)) {
                            return document.getElementById(document.forms
                            .id + ':' + elementId);
                            }
                            }
                            return null;
                            }

                            same IE constraints apply - this code should work across browsers but hasnt been tested. The benefit of working in the financial industry - is EVERYbody uses ie. 6 or 7 :) Beats the days when I was devleloping for 1e 3.0, netscape 4.0.1 and LYNX - YUCH!

                            • 11. Re: show details when clicking on a table row?
                              baz

                              Thanks for the answer.
                              If you are using Seam it gets even easier:

                              <rich:dataTable
                               onRowMouseOver="onRowOver(this)"
                               onRowMouseOut="onRowOut(this)"
                               onRowClick="onRowClick(this)"
                               cellpadding="0" cellspacing="0"
                               width="700" border="0" value="#{ajaxhelper.requestList}" var="row"
                               <a4j:support event="onRowClick" action="#{ajaxhelper.rowSelected(row)}"/>
                               <rich:column>
                               <f:facet name="header">
                               <h:outputText value="Request ID"/>
                               </f:facet>
                               <h:outputText value="#{row.requestId}"/>
                              ........
                              </rich:dataTable>
                              

                              and ajaxhelper looks like:
                              public void rowSelected(TypeOfElem elem) {
                               System.out.println("@#@#@#@#@#@#@: ROW: "+elem.getRequestId()+" "+elem.getCreator()+" "+elem.getState()+" "+elem.getDescription());
                               }
                              

                              TypeOfElem is the Type of an element from requestlist.
                              Seam can use extended EL Expressions where you can pass parameters to action methods.

                              Ciao,
                              Carsten
                              BTW: Did you know that there is a method getRowData?
                              You can get the current row object with this.
                              public void rowSelected(ActionEvent event) {
                               Object obj = getTable().getRowData();
                               //cast obj to appropriate type.
                               System.out.println("@#@#@#@#@#@#@: ROW: "+currRow.getRequestId()+" "+currRow.getCreator()+" "+currRow.getState()+" "+currRow.getDescription());
                               }


                              • 12. Re: show details when clicking on a table row?
                                zenshai

                                 

                                "tbrown_01923" wrote:
                                The benefit of working in the financial industry - is EVERYbody uses ie. 6 or 7 :) Beats the days when I was devleloping for 1e 3.0, netscape 4.0.1 and LYNX - YUCH!


                                Yea, technically im developing for IE6 but since firebug is such a nice tool, I make things work in FF first and worry about IE later.

                                Also, baz yea I saw that method in the same post i mentioned earlier, I didnt use it because i know i will need that current index later. In fact im going to make index a property in my TableRow class, it will probably help with implementing sorting which is the next thing I need to do.



                                • 13. Re: show details when clicking on a table row?

                                  Could I ask a question?
                                  I don't use Seam. I'm using jsf 1.2, facelets, ajax4jsf, rich faces. There's this line in your code:

                                  <a4j:support event="onRowClick" action="#{ajaxhelper.rowSelected(row)}"/>

                                  Is it possible to call a method with parameters in the action property? I tried this example and there's an exception
                                  com.sun.facelets.tag.TagAttributeException: /admin/pieces/role/role-view.xhtml @32,83 action="#{roleView.roleSelected(role)}" Error Parsing: #{roleView.roleSelected(role)}
                                  ...
                                  com.sun.el.parser.ParseException: Encountered "(" at line 1, column 24.
                                  Was expecting one of:
                                   "}" ...
                                   "." ...
                                   "[" ...
                                   ">" ...
                                   "gt" ...
                                   "<" ...
                                   "lt" ...
                                   ">=" ...
                                   "ge" ...
                                   "<=" ...
                                   "le" ...
                                   "==" ...
                                   "eq" ...
                                   "!=" ...
                                   "ne" ...
                                   "&&" ...
                                   "and" ...
                                   "||" ...
                                   "or" ...
                                   "*" ...
                                   "+" ...
                                   "-" ...
                                   "?" ...
                                   "/" ...
                                   "div" ...
                                   "%" ...
                                   "mod" ...

                                  I don't have the onRowClick javascript function in my page (because I didn't see it here).
                                  "baz" wrote:
                                  Thanks for the answer.
                                  If you are using Seam it gets even easier:
                                  <rich:dataTable
                                   onRowMouseOver="onRowOver(this)"
                                   onRowMouseOut="onRowOut(this)"
                                   onRowClick="onRowClick(this)"
                                   cellpadding="0" cellspacing="0"
                                   width="700" border="0" value="#{ajaxhelper.requestList}" var="row"
                                   <a4j:support event="onRowClick" action="#{ajaxhelper.rowSelected(row)}"/>
                                   <rich:column>
                                   <f:facet name="header">
                                   <h:outputText value="Request ID"/>
                                   </f:facet>
                                   <h:outputText value="#{row.requestId}"/>
                                  ........
                                  </rich:dataTable>

                                  and ajaxhelper looks like:
                                  public void rowSelected(TypeOfElem elem) {
                                   System.out.println("@#@#@#@#@#@#@: ROW: "+elem.getRequestId()+" "+elem.getCreator()+" "+elem.getState()+" "+elem.getDescription());
                                   }

                                  TypeOfElem is the Type of an element from requestlist.
                                  Seam can use extended EL Expressions where you can pass parameters to action methods.

                                  Ciao,
                                  Carsten
                                  BTW: Did you know that there is a method getRowData?
                                  You can get the current row object with this.
                                  public void rowSelected(ActionEvent event) {
                                   Object obj = getTable().getRowData();
                                   //cast obj to appropriate type.
                                   System.out.println("@#@#@#@#@#@#@: ROW: "+currRow.getRequestId()+" "+currRow.getCreator()+" "+currRow.getState()+" "+currRow.getDescription());
                                   }


                                  • 14. Re: show details when clicking on a table row?

                                    Action method is a method that return String and has not parameters.
                                    So, both methods you show are not the action methods. The second one is qualified to be an action listener (and you need to use actionListener attribute in this case)

                                    The standard EL without Seam enhancements does not parameters. As soon as you do not use Seam yet, this option is not available for you.