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

    How to enable already disabled a4j:commandLink?

    Sergey Tereshchenko Newbie

      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?
          Rocky S Master

          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>

           

          `

          • 3. Re: How to enable already disabled a4j:commandLink?
            Sergey Tereshchenko Newbie

            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 Master

              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.