6 Replies Latest reply on Oct 30, 2009 1:53 PM by mark lewis

    AJAX SelectOneMenu use

    mark lewis Newbie

      hi
      i've got a rich:toolbar:

      <rich:toolBar>
       <rich:toolBarGroup location="left">
       <h:outputText style="text-align: center" value="Select node " />
       <h:selectOneMenu id="nodes" value="#{Welcome.chosenNode}">
       <f:selectItems value="#{Welcome.nodes}" />
       <a4j:commandButton value="Retrieve" reRender="nodeConfig" />
       </h:selectOneMenu>
       </rich:toolBarGroup>
      </rich:toolBar>
      
      <h:panelGroup id="nodeConfig"
       rendered="#{not empty Welcome.chosenNode}">
       <rich:tabPanel switchType="client">
       <!-- has to be client - i want all data there -->
       <rich:tab style="font-weight: bold;"
       label="#{Welcome.chosenNode} Global Settings">
       Here is tab #1
       </rich:tab>
       <rich:tab style="font-weight: bold;" label="File-Message Settings">
       Here is tab #2
       </rich:tab>
       </rich:tabPanel>
      </h:panelGroup>
      


      and in my backing bean, public class Welcome {

      <snip>
      
      private ApexConnect acon = new ApexConnect();
      
      <snip>
      
       public List<SelectItem> getNodes() {
       nodes = acon.readColumn();
       return nodes;
       }
      
       public void setNodes(List n)
       {
       nodes = n;
       }
      
       public String getChosenNode() {
       return chosenNode;
       }
      
       public void setChosenNode(String n) {
       this.chosenNode = n;
       System.out.println(n);
       }
      


      The class ApexConnect makes a connection to an oracle db.

      When the page loads, my dropdown menu of nodes is shown, correctly output from the db. But when I select a node and hit 'Retrieve', the app crashes.

      From the log, a second OracleDataSource() object is being instantiated. When it gets to the fairly standard

      pstmt = conn.prepareStatement("SELECT * FROM " + dbTable);

      line that's where it dies:

      java.lang.NullPointerException
      myPkg.ApexConnect.readColumn(Unknown Source)
      myPkg.Welcome.getNodes(Unknown Source)

      is the error.

      As it's tiered, my app will need to read the db table once per HTTP client connection to the app (ie so a refresh gets new nodes added to the db) but I only want one DB connection.

      How can I maintain this first connection to the database so manipulating the SelectOneMenu doesn't cause problems and selecting a item in the dropdown list allows me to act on it? The app thinks the oracle data source member is null when the commandButton is hit.

      Thanks IA
      M

        • 1. Re: AJAX SelectOneMenu use
          mark lewis Newbie

          Ok, in faces-config.xml my managed bean scope was set to request. Now set to session, the app doesn't crash, but

          1. every change to the SelectOneMenu is still causing a new connection to the db
          2. the index.jsp 'reRender="nodeConfig"' in the commandButton is not causing a rerender of the panelGroup with id nodeConfig. I'll be looking at this..

          • 2. Re: AJAX SelectOneMenu use
            mark lewis Newbie

            Sorry - on point 1, it isn't setting up a new datasource. I guess that makes that problem solved. Just got to work out why my ajax form isn't working...

            • 3. Re: AJAX SelectOneMenu use
              Nick Belaevski Master

              Hi,

              Advice for resolving point 2 - try adding a4j:log and check it for warning/error messages.

              • 4. Re: AJAX SelectOneMenu use
                mark lewis Newbie

                Hi

                OK I've got a4j:log in and it's outting nicely, except there is a lot of output...

                the line earlier in this post

                <a4j:commandButton value="Retrieve" reRender="nodeConfig" />
                


                doesn't seem to want to reRender the node with id="nodeConfig".

                the tags are thus:
                <a4j:form>
                 <rich:toolBar>
                
                 <rich:toolBarGroup location="left">
                 <h:outputText style="text-align: center" value="Select node " />
                 <h:selectOneMenu id="nodes" value="#{Welcome.chosenNode}">
                 <f:selectItems value="#{Welcome.nodes}" />
                 </h:selectOneMenu>
                 <a4j:commandButton value="Retrieve" reRender="nodeConfig" />
                 </rich:toolBarGroup>
                 </rich:toolBar>
                </a4j:form>
                
                <h:form id="nodeConfig" rendered="#{not empty Welcome.chosenNode}">
                 <rich:tabPanel switchType="client">
                 <!-- has to be client - i want all data there -->
                 <rich:tab style="font-weight: bold;"
                 label="#{Welcome.chosenNode} Global Settings">
                 Here is tab #1
                 </rich:tab>
                 </rich:tabPanel>
                </h:form>
                


                and the a4j log does produce a warning:

                debug[16:01:39,456]: Update page part from call parameter for ID nodeConfig
                debug[16:01:39,457]: call getElementById for id= nodeConfig
                warn[16:01:39,457]: Node for replace by response with id nodeConfig not found in document
                


                so it appears that the node for the getElementById cannot see the node with that id in it's tree, but we know it's there.

                if i select an option from the menu and (nothing happens) then refresh the page, the tabPanel appears. I know that chosenNode is being called ok, so this seems like a richfaces bag, but i can't seem to find out how to get the page to see the elem so it can replace it (and thus reveal the tab to the user).

                any comments would be blinding. especially as it's Friday.

                m

                • 5. Re: AJAX SelectOneMenu use
                  mark lewis Newbie

                  Incidentally, if i put an item with that id in with the command button, it works ok:

                  <rich:toolBarGroup location="left">
                   <h:outputText style="text-align: center" value="Select node " />
                   <h:selectOneMenu id="nodes" value="#{Welcome.chosenNode}">
                   <f:selectItems value="#{Welcome.nodes}" />
                   </h:selectOneMenu>
                   <a4j:commandButton value="Retrieve" reRender="nodeConfig" />
                   <h:panelGroup id="nodeConfig">
                   <h:outputText value="Hello "
                   rendered="#{not empty Welcome.chosenNode}" />
                   <h:outputText value="#{Welcome.chosenNode}" styleClass="outhello" />
                   <h:outputText value="!" rendered="#{not empty Welcome.chosenNode}" />
                   </h:panelGroup>
                  </rich:toolBarGroup>
                  



                  debug[16:29:27,276]: call getElementById for id= org.ajax4jsf.oncomplete
                  debug[16:29:27,276]: Processing updates finished, no oncomplete function to call
                  debug[16:29:27,276]: Update part of page for Id: j_id_jsp_920730595_29:nodeConfig successful
                  debug[16:29:27,277]: call getElementById for id= ajax-view-state
                  


                  Which suggests again it's because the code is in a rich:toolBar so it's not able to reach outside it - except that i'm going to have a whole tabset which i need to pop up underneath the SelectOneMenu rich:toolBar so i have to have them separate.

                  i thought it was cos the tabs were outside the a4j:form element, but moving it doesn't help.


                  • 6. Re: AJAX SelectOneMenu use
                    mark lewis Newbie

                    Ok, I've fixed this one myself too, and it is a scoping issue:

                    <a4j:form>
                     <rich:toolBar>
                    
                     <rich:toolBarGroup location="left">
                     <h:outputText style="text-align: center" value="Select node " />
                     <h:selectOneMenu id="nodes" value="#{Welcome.chosenNode}">
                     <f:selectItems value="#{Welcome.nodes}" />
                     </h:selectOneMenu>
                     <a4j:commandButton value="Retrieve" reRender="nodeConfig" />
                     </rich:toolBarGroup>
                     </rich:toolBar>
                    
                     <h:panelGroup id="nodeConfig">
                     <h:form id="nodConfig" rendered="#{not empty Welcome.chosenNode}">
                     <rich:tabPanel switchType="client">
                     <!-- has to be client - i want all data there -->
                     <rich:tab style="font-weight: bold;" label="Global Settings">
                     <h:outputText value="#{Welcome.chosenNode}: Global Settings" style="font-weight:bold" />
                     </rich:tab>
                     </rich:tabPanel>
                     </h:form>
                    
                    <!--
                     <h:outputText value="Hello " rendered="#{not empty Welcome.chosenNode}" />
                     <h:outputText value="#{Welcome.chosenNode}" styleClass="outhello" />
                     <h:outputText value="!" rendered="#{not empty Welcome.chosenNode}" />
                     -->
                    
                     </h:panelGroup>
                    
                    </a4j:form>