14 Replies Latest reply on Dec 19, 2010 1:11 PM by Nick Belaevski

    How to stop a show component on a link

    Tanya Ruttenberg Expert

      I have a rich:contextMenu that gets shown via "onclick".  Within the area covered by the context menu there is an s:link.

      I do not want the contextMenu to display when I click the link.  I have found several promising articles that describe

      this scenario, but I cannot make it work.

       

      Here is the code

       

      <rich:contextMenu attached="false" submitMode="ajax" hideDelay="300"
              id="hwmenu">

        <rich:menuItem value="Number 1" />

        <rich:menuItem value="Number 2" />

        <rich:menuItem value="Number 3" />

      </rich:contextMenu>


      <rich:dataTable value="#{devicesList.resultSet" var="_device" >


      <rich:column>
         <f:facet name="header">Hostname</f:facet>
         <s:link id="sl2" includePageParams="false" view="/Device.xhtml" >View Detail </s:link>
      </rich:column>


      <rich:componentControl id="cc1" event="onRowClick" for="hwmenu"
        operation="show"  >
         <f:param name="name" value="#{_device}" />

      </rich:componentControl


      </rich:dataTable>

       

      How do I disable the contextMenu/componentControl when I click on the s:link?  I know it has to do with stopping an event, and I

      feel certain I can use the built-in client functions outlined here http://mkblog.exadel.com/2009/12/richfaces-built-in-client-functions/,

      but the specifics continue to elude me.

       

      Help?

       

      TDR

        • 1. Re: How to stop a show component on a link
          Nick Belaevski Master

          Hi Tanya,

           

          Unfortunately, stopping event will break navigation by h:link, so I recommend to create function using "name" attribute on rich:componentControl or using #{rich:component(...)}. Example:

           

          function rowClickHandler(event) {

              var element = Event.findElement(event, '.linkClass');

              if (element == document) {

                  #{rich:component('hwmenu')}.show(event);

              }

          }

           

          <s:link id="sl2" includePageParams="false" view="/Device.xhtml" styleClass="linkClass">View Detail </s:link>

          • 2. Re: How to stop a show component on a link
            Tanya Ruttenberg Expert

            Thanks Nick.  I can only get the rowClickHandler to fire if I explicitly state in the datatable definition

             

            onRowClick="rowClickHandler(event)"

             

            function rowClickHandler(event) {
                 var element = Event.findElement(event,'.slink');
                 alert(element);
            }

             


            I can't get it to return anything other "undefined".  I can see an advanced knowledge of javascript could come in really handy here.

            • 3. Re: How to stop a show component on a link
              Nick Belaevski Master

              Prototype.js script is required to be loaded:

               

              <a4j:loadScript src="resource:///org.ajax4jsf.javascript.PrototypeScript" />
              <h:form>
              <rich:dataTable value="#{forum5Bean.lotOfData}" var="item" onRowClick="rowClickHandler(event)">
              <rich:column>
              <h:outputLink value="http://google.com" styleClass="link">google</h:outputLink>
              </rich:column>
              </rich:dataTable>
              <script type="text/javascript">
              function rowClickHandler(event) {
                 var element = Event.findElement(event, '.link');
                 alert(element);
                 if (element == document) {
                 }
              }
              </script>
              </h:form>

              <a4j:loadScript src="resource:///org.ajax4jsf.javascript.PrototypeScript" />

              <h:form>

              <rich:dataTable value="#{forum5Bean.lotOfData}" var="item" onRowClick="rowClickHandler(event)">

              <rich:column>

              <h:outputLink value="http://google.com" styleClass="link">google</h:outputLink>

              </rich:column>

              </rich:dataTable>

               

              <script type="text/javascript">

              function rowClickHandler(event) {

                  var element = Event.findElement(event, '.link');

                  alert(element);

                  if (element == document) {

                                       //...

                  }

              }

              </script>

              </h:form>

               

              You can do the same check using jQuery: by using event.target & closest(...) function.

              • 4. Re: How to stop a show component on a link
                Tanya Ruttenberg Expert

                :-( I can't get it to work.

                 

                When I try to view the string returned by Event.findElement(event, '.link'); I just get "undefined"

                • 5. Re: How to stop a show component on a link
                  Nick Belaevski Master

                  Ok, please post page code.

                  • 6. Re: How to stop a show component on a link
                    Tanya Ruttenberg Expert

                    Thanks, Nick. Here it is

                     

                    <!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:h="http://java.sun.com/jsf/html"
                        xmlns:f="http://java.sun.com/jsf/core"
                        xmlns:rich="http://richfaces.org/rich"
                        xmlns:ui="http://java.sun.com/jsf/facelets"
                        xmlns:a4j="http://richfaces.org/a4j"
                        xmlns:s="http://jboss.com/products/seam/taglib"
                        xmlns:ond="http://ond.ba.ssa.gov/jsf">

                     

                    <ui:composition template="/layout/template.xhtml">

                     

                        <ui:define name="pageTitle">
                            <title>OND Hardware List</title>
                        </ui:define>
                        <ui:define name="head">
                            <script type="text/javascript">
                                function rowClickHandler(event) {
                                    var element = Event.findElement(event, '.slink');
                                    alert(element);
                                }
                            </script>
                        </ui:define>
                        <ui:define name="body">
                            <a4j:loadScript src="resource:///org.ajax4jsf.javascript.PrototypeScript" />
                            <a4j:form>
                                <a4j:jsFunction name="jsSetDeviceId" action="device" eventsQueue="q1">
                                    <a4j:actionparam name="param1" assignTo="#{devicesHome.devId}" />
                                </a4j:jsFunction>
                            </a4j:form>

                     

                            <h:form>

                     

                                <rich:contextMenu attached="false" submitMode="ajax" hideDelay="300"
                                    id="hwmenu">
                                    <rich:menuItem style="font-weight:bold; color: black" value="{name}"
                                        disabled="true" />
                                    <rich:menuSeparator />
                                    <rich:menuItem value="View details" onclick="jsSetDeviceId({devid})" />
                                </rich:contextMenu>

                     

                                <rich:panel id="p1">
                                    <f:facet name="header">Device HW Search Results</f:facet>

                     

                                    <div class="results" id="viewList"><rich:dataTable
                                        onRowClick="rowClickHandler(event)"
                                        value="#{hardwareList.resultList}" var="_inv" id="deviceTable"
                                        rowClasses="rvgRowOne, rvgRowTwo">

                     

                                        <rich:componentControl id="cc1" event="onRowClick" for="hwmenu"
                                            operation="show">
                                            <f:param name="name" value="#{_inv.devices.name}" />
                                            <f:param name="devid" value="#{_inv.devices.devId}" />
                                        </rich:componentControl>

                     

                                        <rich:column>
                                            <f:facet name="header">Hostname
                                            </f:facet>
                                            <s:link id="sl1" includePageParams="false" view="/Device.xhtml"
                                                styleClass="slink">
                                                <h:outputText value="#{_inv.devices.name}"/>
                                                <f:param name="devid" value="#{_inv.devices.devId}" />
                                                <f:param name="hostname" value="#{_inv.devices.name}" />
                                            </s:link>
                                        </rich:column>

                     

                                        <rich:column styleClass="justify-top" sortBy="#{_inv.udiDescr}">
                                            <f:facet name="header">#{messages['ond.label.hwdescription']}</f:facet>
                                            <h:outputText value="#{_inv.udiDescr}" />
                                        </rich:column>

                     

                                        <rich:column styleClass="justify-top" sortBy="#{_inv.udiPid}">
                                            <f:facet name="header">#{messages['ond.label.hwpid']}</f:facet>
                                            <h:outputText value="#{_inv.udiPid}" />
                                        </rich:column>

                     

                                    </rich:dataTable></div>

                     

                                </rich:panel>

                     

                            </h:form>

                     

                        </ui:define>
                    </ui:composition>

                     

                    </html>

                    • 7. Re: How to stop a show component on a link
                      Nick Belaevski Master

                      Tanya,

                       

                      Looks like Event.findElement(...) has changed its behavior since the version we use - sorry for the inconvenience. This should work:

                       

                                  function rowClickHandler(event) {
                                      var eventSrc = Event.element(event);
                                      var link = Selector.findElement([eventSrc], '.slink') || Element.up(eventSrc, '.slink');
                                      if (link) {
                                     alert(link);
                                      }
                                  }

                                  function rowClickHandler(event) {

                                      var eventSrc = Event.element(event);

                                      var link = Selector.findElement([eventSrc], '.slink') || Element.up(eventSrc, '.slink');

                                      if (link) {

                                      alert(link);

                                      }

                                  }

                      • 8. Re: How to stop a show component on a link
                        Tanya Ruttenberg Expert

                        Thank you!! that did work, specifically

                         

                        function rowClickHandler(event) {

                                        var eventSrc = Event.element(event);

                                        var link = Selector.findElement([eventSrc], '.slink') || Element.up(eventSrc, '.slink');

                                        if (!link) {

                                         //show context menu

                                        }

                                    }

                        1 of 1 people found this helpful
                        • 9. Re: How to stop a show component on a link
                          Tanya Ruttenberg Expert

                          Ack, another problem.  I don't want to just show the context menu, I want to pass several paramenters.  Simply invoking

                           

                          #{rich:component('hwmenu')}.show(event);

                           

                          does not replace

                           

                          <rich:componentControl event="onRowClick" for="devicemenu"
                                  operation="show"  >
                                  <f:param name="name" value="#{_device.name}" />
                                  <f:param name="devid" value="#{_device.devId}" />
                                  <f:param name="loopback" value="#{_device.ip}" />
                                  <f:param name="officeid" value="#{_office.officeId}" />
                              </rich:componentControl>

                           

                          because the parameters do not get passed. Is there any way to also pass the parameters in this case?

                          • 10. Re: How to stop a show component on a link
                            Nick Belaevski Master

                            The simplest possible solution:

                             

                            <rich:componentControl event="onRowClick" for="devicemenu" name="showMenu#{rowIndex}"
                                    operation="show"  >
                                    <f:param name="name" value="#{_device.name}" />
                                    <f:param name="devid" value="#{_device.devId}" />
                                    <f:param name="loopback" value="#{_device.ip}" />
                                    <f:param name="officeid" value="#{_office.officeId}" />
                                </rich:componentControl>

                             

                            and then declare showMenu#{rowIndex}(event) as event handler.

                            1 of 1 people found this helpful
                            • 11. Re: How to stop a show component on a link
                              Tanya Ruttenberg Expert

                              Nick,


                              I am dense. Can you please post the specific code?  I don't get how this works.  Even when I try a simple example I cannot seem to get the eventhandler to fire.

                               

                              Thanks again.

                              Tanya

                              • 12. Re: How to stop a show component on a link
                                Nick Belaevski Master

                                Tanya,

                                 

                                Here is the whole thing put together:

                                 

                                 

                                <script type="text/javascript">
                                            function rowClickHandler(event, callback) {
                                                var eventSrc = Event.element(event);
                                                var link = Selector.findElement([eventSrc], '.slink') || Element.up(eventSrc, '.slink');
                                                if (!link) {
                                               callback(event);
                                                }
                                            }
                                        </script>
                                 
                                 
                                <a4j:loadScript
                                src="resource:///org.ajax4jsf.javascript.PrototypeScript" />
                                 
                                 
                                <h:form>
                                 
                                 
                                 
                                <rich:contextMenu attached="false" submitMode="ajax" hideDelay="300"
                                id="hwmenu">
                                <rich:menuItem style="font-weight:bold; color: black" value="{name}"
                                disabled="true" />
                                <rich:menuSeparator />
                                <rich:menuItem value="View details" onclick="jsSetDeviceId({devid})" />
                                </rich:contextMenu>
                                <rich:dataTable onRowClick="rowClickHandler(event, showMenu#{idx})"
                                rowKeyVar="idx" value="#{forum5Bean.lotOfData}" var="_inv"
                                id="deviceTable" rowClasses="rvgRowOne, rvgRowTwo">
                                 
                                 
                                <rich:column>
                                <f:facet name="header">Hostname</f:facet>
                                 
                                <rich:componentControl id="cc1" for="hwmenu" operation="show"
                                name="showMenu#{idx}">
                                <f:param name="name" value="#{_inv}" />
                                <f:param name="devid" value="#{_inv}" />
                                </rich:componentControl>
                                 
                                <h:outputLink id="sl1" styleClass="slink">
                                <h:outputText value="#{_inv}" />
                                <f:param name="devid" value="#{_inv}" />
                                <f:param name="hostname" value="#{_inv}" />
                                </h:outputLink>
                                </rich:column>
                                 
                                <rich:column styleClass="justify-top">
                                <h:outputText value="#{_inv}" />
                                </rich:column>
                                </rich:dataTable>
                                 
                                 
                                 
                                </h:form>
                                 
                                          <script type="text/javascript">
                                            function rowClickHandler(event, callback) {
                                                var eventSrc = Event.element(event);
                                                var link = Selector.findElement([eventSrc], '.slink') || Element.up(eventSrc, '.slink');
                                                if (!link) {
                                                     callback(event);
                                                }
                                            }
                                        </script>
                                
                                
                                     <a4j:loadScript
                                          src="resource:///org.ajax4jsf.javascript.PrototypeScript" />
                                
                                
                                     <h:form>
                                
                                
                                
                                          <rich:contextMenu attached="false" submitMode="ajax" hideDelay="300"
                                               id="hwmenu">
                                               <rich:menuItem style="font-weight:bold; color: black" value="{name}"
                                                    disabled="true" />
                                               <rich:menuSeparator />
                                               <rich:menuItem value="View details" onclick="jsSetDeviceId({devid})" />
                                          </rich:contextMenu>
                                          <rich:dataTable onRowClick="rowClickHandler(event, showMenu#{idx})"
                                               rowKeyVar="idx" value="#{forum5Bean.lotOfData}" var="_inv"
                                               id="deviceTable" rowClasses="rvgRowOne, rvgRowTwo">
                                
                                
                                               <rich:column>
                                                    <f:facet name="header">Hostname</f:facet>
                                
                                                    <rich:componentControl id="cc1" for="hwmenu" operation="show"
                                                         name="showMenu#{idx}">
                                                         <f:param name="name" value="#{_inv}" />
                                                         <f:param name="devid" value="#{_inv}" />
                                                    </rich:componentControl>
                                
                                                    <h:outputLink id="sl1" styleClass="slink">
                                                         <h:outputText value="#{_inv}" />
                                                         <f:param name="devid" value="#{_inv}" />
                                                         <f:param name="hostname" value="#{_inv}" />
                                                    </h:outputLink>
                                               </rich:column>
                                
                                               <rich:column styleClass="justify-top">
                                                    <h:outputText value="#{_inv}" />
                                               </rich:column>
                                          </rich:dataTable>
                                
                                
                                
                                     </h:form>
                                
                                 
                                
                                • 13. Re: How to stop a show component on a link
                                  Tanya Ruttenberg Expert

                                  Nick,

                                   

                                  You're answer makes sense, but the code still does not work.

                                   

                                  The onRowClick on the row fires the rowClickHandler which, based on some condition or other fires the componentControl which displays the menu. I understand the order of events now, but that does not seem to be happening.

                                   

                                  Take out the condition in the rowClickHandler and clicking the row should result in the menu being displayed.  That is not happening.

                                   

                                  This code results in 2 alert boxes being displayed:

                                   

                                  <script type="text/javascript">

                                      function rowClickHandler(event, callback) {

                                          alert(event);

                                          alert(callback);

                                      }
                                  </script> 


                                  <rich:dataTable rowKeyVar="idx"

                                      onRowClick="rowClickHandler(event, 'showMenu#{idx}')"

                                      value="#{hardwareList.resultList}" var="_inv">


                                      <rich:componentControl id="cc1" for="hwmenu"
                                         operation="show" name="showMenu#{idx}">
                                          <f:param name="name" value="#{_inv.devices.name}" />
                                          <f:param name="devid" value="#{_inv.devices.devId}" />
                                      </rich:componentControl>


                                      <rich:column/>


                                      <rich:column/>

                                  </rich:dataTable>

                                   

                                  Same code except replace the alerts with the callback(event) and the results is nothing.

                                   

                                  <script type="text/javascript">

                                      function rowClickHandler(event, callback) {

                                          callback(event);

                                       }
                                  </script>

                                   

                                  I expected it to fire the showMenu#{idx}.

                                   

                                  The only thing that fires the componentControl is adding "event=onRowClick" attribute to the componentControl


                                  <rich:componentControl id="cc1" for="hwmenu" event="onRowClick"
                                     operation="show" name="showMenu#{idx}">
                                       <f:param name="name" value="#{_inv.devices.name}" />
                                       <f:param name="devid" value="#{_inv.devices.devId}" />
                                  </rich:componentControl>

                                   

                                  but then rowClickHandler(e,c) gets ignored.  I can't get showMenu#{idx} to fire via the javascript script at all.

                                   

                                  Did you actually get it to work?

                                  Thanks again,

                                  Tanya

                                  • 14. Re: How to stop a show component on a link
                                    Nick Belaevski Master

                                    Tanya,

                                     

                                    Yes, I've copied the code from working page.