4 Replies Latest reply on Nov 30, 2010 6:45 AM by ilya_shaikovsky

    How to enable already disabled a4j:commandLink?

    pro4nist

      Hi. Please help me in this issue. I want to enable a4j:commandLink already disabled from backing bean (toDisableSaveLink = true).

       

               <a4j:commandLink id="${itemIndex}Save"
                      action="#{bean.save}"
                      ajaxSingle="false" limitToList="true"

                      disabled="${bean.toDisableSaveLink}"
                      styleClass="#{bean.toDisableSaveLink ? 'linkDisabled' : 'linkEnabled'}"
                      reRender="contentTabPanell"
                      rendered="${bean.toRenderSaveLink}">
                      <h:graphicImage value="/images/Save.gif"
                          styleClass="#{bean.toDisableSaveLink ? 'linkDisabled' : 'linkImageEnabled'}"></h:graphicImage>
                      <h:outputText value="#{globalizationBean.label['save']}"
                          styleClass="#{bean.toDisableSaveLink ? 'linkDisabled' : 'linkEnabled'}"></h:outputText>
                  </a4j:commandLink>

       


      I tried to do it per javascript function which change styleClasses for html components (<a> and childs: <img>, <span>) to EnabledClasses and change attribut onclick for the component <a> to the value which richfaces assigned when a4j:commandLink is enabled from backing bean.

       

      function enabledSaveLink(saveLinkId)
      {           
          var saveLink = document.getElementById(saveLinkId);
         
          var stringOnClick = "A4J.AJAX.Submit(\'contentTabPanel',event," +
                  "{\'similarityGroupingId\':\'" + saveLinkId + "\'," +
                  "\'parameters\':{\'" + saveLinkId + "\':" +
                  "\'" + saveLinkId + "\'} } );return false;";
         
          if(window.event)  //IE
          {               
              saveLink.onclick = new Function ('onclick', stringOnClick);
          }
          else  //FF
          {           
              for( var i = 0; i < saveLink.attributes.length; i++ )
              {
              if( saveLink.attributes[i].nodeName.toLowerCase() == 'onclick' )
              {
                  saveLink.attributes[i].value = stringOnClick;
                  break;
              }
              }
          }

                   
          saveLink.className = 'linkEnabled';
          var childArray = saveLink.children;

       

          for(var i=0; i<childArray.length; i++)
          {
              if(childArray[i].tagName.toLowerCase() == 'img')
              {
                  childArray[i].className = 'linkImageEnabled';
              }
              else
              {
                  childArray[i].className = 'linkEnabled';
              }
          }    

      }

       

      In this case works only simple submit (toDisableSaveLink get/set) but action="#{bean.save}" does not works.

      Please prompt, may be there is more simple way to do enable/disable a4j:commandLink on client?!

        • 1. Re: How to enable already disabled a4j:commandLink?
          boy18nj

          I don't see in your code when you are calling enabledSaveLink.

           

          There is another simpler way to achieve this without writing any javascript code for it. Write a method names as "toEnableSaveLink" under your backing bean which enables the link or flips your boolean value.

           

          So your code would like this, give it a shot if it works for you-

           

          `

          <a:commandLink id="${itemIndex}Save" action="#{bean.save}"

          <a:commandLink id="${itemIndex}Save" action="#{bean.save}"

          ajaxSingle="false" limitToList="true"

          disabled="${bean.toDisableSaveLink}"

          styleClass="#{bean.toDisableSaveLink ? 'linkDisabled' : 'linkEnabled'}"

          reRender="contentTabPanell" rendered="${bean.toRenderSaveLink}">

          <h:graphicImage value="/images/Save.gif"

          styleClass="#{bean.toDisableSaveLink ? 'linkDisabled' : 'linkImageEnabled'}"></h:graphicImage>

          <h:outputText value="#{globalizationBean.label['save']}"

          styleClass="#{bean.toDisableSaveLink ? 'linkDisabled' : 'linkEnabled'}"></h:outputText>

          <a:support event="onclick" action="#{bean.toEnableSaveLink}" reRender="${itemIndex}Save"></a:support>

          </a:commandLink>

          ajaxSingle="false" limitToList="true"
          disabled="${bean.toDisableSaveLink}"
          styleClass="#{bean.toDisableSaveLink ? 'linkDisabled' : 'linkEnabled'}"
          reRender="contentTabPanell" rendered="${bean.toRenderSaveLink}">
          <h:graphicImage value="/images/Save.gif"
          styleClass="#{bean.toDisableSaveLink ? 'linkDisabled' : 'linkImageEnabled'}"></h:graphicImage>
          <h:outputText value="#{globalizationBean.label['save']}"
          styleClass="#{bean.toDisableSaveLink ? 'linkDisabled' : 'linkEnabled'}"></h:outputText>
          <a:support event="onclick" action="#{bean.toEnableSaveLink}"></a:support>
          </a:commandLink>

           

          `

          • 2. Re: How to enable already disabled a4j:commandLink?
            ilya_shaikovsky
            • 3. Re: How to enable already disabled a4j:commandLink?
              pro4nist

              Thanks guys.

               

              Aman, I call enabledSaveLink after any first change on page. Your approach not works for me because of when I have any changes on page Save Link should already be enabled (all on client), and onclick I should call my method (action="#{bean.save}") not bean.toEnableSaveLink.

               

              Ilya, thanks a lot. Your approach is interesting, but structure of the application is such that I binded with js, I should made enabling procedure on client only.

               

              I found some workaround.

              When user made any changes on page immadiatly value of the hidden field (QuoteChangedHidden) on page becomes "true" and calls function enabledSaveLink:

              function enabledSaveLink(prefixID)
              {   
                  var saveButtonId;
                  var indexOfQuote = prefixID.indexOf("Quote");
                  saveButtonId = prefixID.substring(0, indexOfQuote) + "QuoteSave";
                     
                  var saveLink = document.getElementById(saveButtonId);
                  if(saveLink == null) return;
                               
                  saveLink.className = 'linkButton';
                  var childArray = saveLink.children;

               

                  for(var i=0; i<childArray.length; i++)
                  {
                      if(childArray[i].tagName.toLowerCase() == 'img')
                      {
                          childArray[i].className = 'linkImage';
                      }
                      else
                      {
                          childArray[i].className = 'linkButton';
                      }
                  }       
              }

               

              And my Link become enabled (only visual, not for functionality).

              Link looks liks this:

                   <h:panelGrid columns="2">

                       <a4j:commandLink id="${itemIndex}Save"
                              onmousedown = "fireClickIfChangesIs('contentTabPanel:${quoteId}', 'contentTabPanel:${quoteId}_forQuoteSaveAction');"

                              disabled="${bean.toDisableSaveLink}"
                              styleClass="#{bean.toDisableSaveLink ? 'linkDisabled' : 'linkEnabled'}"
                              reRender="contentTabPanell"
                              rendered="${bean.toRenderSaveLink}">
                              <h:graphicImage value="/images/Save.gif"
                                  styleClass="#{bean.toDisableSaveLink ? 'linkDisabled' : 'linkImageEnabled'}"></h:graphicImage>
                              <h:outputText value="#{globalizationBean.label['save']}"
                                  styleClass="#{bean.toDisableSaveLink ? 'linkDisabled' : 'linkEnabled'}"></h:outputText>
                          </a4j:commandLink>

               

                         <a4j:commandLink id="#{quoteId}_forSaveAction"
                              action = "#{bean.save}"

                             ajaxSingle="false" limitToList="true"

                             reRender="contentTabPanel">       
                            </a4j:commandLink>

                    </h:panelGrid>

               

              When user made click (onmousedown) on Link (onclick didnot works) then calls js function fireClickIfChangesIs

               

              function fireClickIfChangesIs(prefixIdIsChanged, idToClick)
              {  
                     var idIsChanged = prefixIdIsChanged + "QuoteChangedHidden";
                 
                  if(document.getElementById(idIsChanged).value == 'true')
                  {
                      if (document.createEvent)
                      {
                           var evObj = document.createEvent('MouseEvents');
                           evObj.initEvent( 'click', true, false )
                           document.getElementById(idToClick).dispatchEvent(evObj)
                       }
                       else if (document.createEventObject)
                       {
                           document.getElementById(idToClick).fireEvent('onclick')
                       }
                  }
              }

               

              This approach works for me, may be usefull for somebody.

              But have some problem when form submitted throught js .onclick. For some reason one of my widgets which contain rich:calendar and several h:selectOneMenu has some conflict during whole page submiting throught js. Problem resolved partialy via changing immadiate to "false" in calendar and onmouseup to onmousedown in Link. I don't know why so, but become works better.

              May be someone found better way or knows why actions are conficted?

              • 4. Re: How to enable already disabled a4j:commandLink?
                ilya_shaikovsky

                my goal was to show you not only working sample but description also. there is explanation why controls enabled bia js will still not fire Action events.