Wednesday, December 4, 2013

Refresh af:OutputText value using JavaScript

Applicable to FMW 11.1.1.6.0

Y'day, I was trying to write a Java Script to change the Page header(af:outputText) based on link(af:goLink) clicked by user. I tried following approaches to achieve it.

Approach 1:
JSPX page source: 
<af:iterator>
  ...........................
   <af:goLink text="#{side_menu_item.title}" id="gk1"
              destination="#{side_menu_item.goLinkPrettyUrl}"
              targetFrame="#{side_menu_item.attributes['Target']}">
         <af:clientListener type="click" method="changeHeader"/>
         <af:clientAttribute name="Title" value="#{side_menu_item.title}"/>
         <af:serverListener type="setHeader" method="#{pageFlowScope.PortalBean.setNavHeader}"/>
   </af:goLink>
   ...........................
</af:iterator>

Note: No need to set clientComponent=true , if you are adding af:clientListener

   <af:outputText value="#{pageFlowScope.PortalBean.navHeader}" id="pt_ot2"
                  clientComponent="true"
                  binding="#{pageFlowScope.PortalBean.navHeaderText}"
                  noWrap="true">
   </af:outputText>

Java Script:
    function changeHeader(evt) {
       var goLink = evt.getSource();
       var title = goLink.getProperty("Title");
       AdfCustomEvent.queue(goLink,"setHeader",{param1:title},true);
    }

Managed Bean Method: (This server side method will be called using af:serverListener)
public void setNavHeader(ClientEvent ce) {
        String param = (String)ce.getParameters().get("param1");
        setNavHeader(param);
        AdfFacesContext.getCurrentInstance().addPartialTarget(getNavHeaderText());      
    }

    public void setNavHeader(String navHeader) {
        this.navHeader = navHeader;
    }

    public String getNavHeader() {
        return navHeader;
    }

Approach 2:
Later, I thought to set the <af:outputText> using only JavaScript instead of calling Server side bean.
function changeHeader(evt) {
       var goLink = evt.getSource();
       var title = goLink.getProperty("Title");
       var headerText = goLink.findComponent("pt_ot2");
       headerText.setValue(title);
    }

Note: In this case, the component can be find using its id.

Approach 3:
Again, I tried another approach to set the <af:outputText>.
function changeHeader(evt) {
       var goLink = evt.getSource();
       var title = goLink.getProperty("Title");
       document.getElementById('pt1:pt_ot2').value=title;
    }

Note: In this case, the component can be find using id generated on client side(browser). You can get the client side id by accessing page source.

When I run the page, it worked fine in IE 9, but not in Mozilla(17.0.11) & Chrome(31.0.1650.57 m) browsers. Then I made small change to javascript, which worked across all browsers.

function changeHeader(evt) {
       var goLink = evt.getSource();
       var title = goLink.getProperty("Title");
       document.getElementById('pt1:pt_ot2').innerHTML=title;
    }

Note: If you are using af:GoLink, it will refresh the complete global container. Hence the <af:outputText> value will be set to NULL. In this case, you can try to use browser sessionStorage to store values even after browser refresh.

    function storeValue(key, value) {
        if (window.sessionStorage) {
            sessionStorage.setItem(key, value);
        }
    }

    function getStoredValue(key) {
        if (window.sessionStorage) {
            return sessionStorage.getItem(key);
        }
    }

storeValue('header', title);
getStoredValue('header');

No comments:

Post a Comment

Provide your thoughts !