4 Replies Latest reply on Jan 24, 2012 12:27 PM by tomjohn

    Setting a bean property on page load (for Breadcrumbs!)

    facemakersc

      Good Morning!

       

      I'm trying to build a simple breadcrumbing system and I'm having a little trouble.  I decided that I want the jsf pages to contain the breadcrumb info, and I want a breadcrumbs class (that uses a breadcrumb class) to contain the breadcrumbs information.  So when the page loads I want to send the new breadcrumbs information to the Breadcrumbs managed bean, and that bean will decide what to do with the existing breadcrumb trail (if there is one), and contain the information needed to print  the breadcrumb trail on the page.  The problem that I'm having is sending the breadcrumb information to the Breadcrumbs bean when the page loads.  I know Richfaces uses jquery so in the jsf page I have this:

       

                <h:form>

                  <a4j:jsFunction name="registerCrumb" render="breadcrumbs" action='#{breadcrumbs.addCrumb}' >

                      <a4j:param name="name" value="Departments" assignTo="#{breadcrumbs.setNewName}"/>

                      <a4j:param name="link" value="dept" assignTo="#{breadcrumbs.setNewLink}" />

                      <a4j:param name="level" value="1" assignTo="#{breadcrumbs.setNewLevel}" />

                  </a4j:jsFunction>           

              </h:form>

              <script type="text/javascript">

                  $(document).ready(function(){

                      registerCrumb();

                  })

              </script>

       

      The Breadcrumbs bean just has basic getters and setters and the addCrumb method takes care of the breadcrumb trail management.  I guess I'm using a4j:jsFunction wrong...but how can I do this on the page startup?  Thanks for any help!

        • 1. Re: Setting a bean property on page load
          facemakersc

          Got it!  This is how it's done guys....

          To display the form....and then to register the form, use these two snippets on the same page!

          //////////////////////////////////////////////////////////////////////////////////////////////

                    <a4j:outputPanel id="breadcrumbs">

                          <h:form>

                              <h:link outcome="home">

                                  <h:outputText value="Auto Attendant#{breadcrumbs.crumbSeparator}" />

                              </h:link>

                              <a4j:repeat value="#{breadcrumbs.crumbs}" var="crumb">

                                  <h:link outcome="#{crumb.link}">

                                      <h:outputText value="#{crumb.name}#{breadcrumbs.crumbSeparator}" />

                                  </h:link>

                              </a4j:repeat>

                              <h:outputText value="#{breadcrumbs.thisCrumb.name}" />

                          </h:form>

                      </a4j:outputPanel>

                 

          ...............then........

           

            <h:form>

                      <a4j:jsFunction name="registerCrumb" render="breadcrumbs"  >

                          <f:setPropertyActionListener value="Directory" target="#{breadcrumbs.newName}"/>

                          <f:setPropertyActionListener value="directory" target="#{breadcrumbs.newLink}"/>

                          <f:setPropertyActionListener value="1" target="#{breadcrumbs.newLevel}"/>

                      </a4j:jsFunction>           

                  </h:form>

                  <script type="text/javaScript">

                      $(document).ready(function(){

                          registerCrumb();

                      });

                  </script>

          ////////////////////////////////////////////////////////////////////////////////////////////////

          For everyone that might someday be really happy I posted the backing breadcrumb interface, here ya go:

          Breadcrumbs.java (managed bean):::

          ////////////////////////////////////////////////////////////////////////////////////////////////

          import java.util.ArrayList;

          import {path.to}.Breadcrumb;

           

          public class Breadcrumbs {

              private ArrayList<Breadcrumb> crumbs = new ArrayList<Breadcrumb>();

              private Breadcrumb thisCrumb = null;

           

              private String crumbSeparator = "::";

           

              private String newName = null;

              private String newLink = null;

              private int newLevel = 0;

           

           

           

              public void addCrumb(){

                  if(thisCrumb!=null){

                      if(getThisCrumb().getLevel()<getNewLevel()){//we went further into the application

                          //check if we came from homepage....add crumb to crumbs if not

                          if(getThisCrumb().getLevel()!=0){

                              crumbs.add(getThisCrumb());

                          }

                      }

                      if(getNewLevel()-getThisCrumb().getLevel()==1){//we stayed at the same level of hierarchy in the application

                          setThisCrumb(new Breadcrumb(getNewName(), getNewLink(), getNewLevel()));

                      }else{//we came further out of the application

                          if(crumbs.size()!=0){

                              for(int i=crumbs.size()-1; i >= 0; i--){

                                  if(crumbs.get(i).getLevel()>=getNewLevel()){

                                      crumbs.remove(crumbs.size()-1);

                                  }

                              }

                          }

                          setThisCrumb(new Breadcrumb(getNewName(), getNewLink(), getNewLevel()));

                      }

                  }else{

                      setThisCrumb(new Breadcrumb(getNewName(), getNewLink(), getNewLevel()));

                  }

           

              }

           

              public void setThisCrumb(Breadcrumb thisCrumb) {

                  this.thisCrumb = thisCrumb;

              }

              public Breadcrumb getThisCrumb() {

                  return thisCrumb;

              }

              public ArrayList<Breadcrumb> getCrumbs(){

                  return this.crumbs;

              }

              public void setCrumbs(ArrayList<Breadcrumb> crumbs){

                  this.crumbs = crumbs;

              }

              public void setNewName(String newName) {

                  this.newName = newName;

              }

              public String getNewName() {

                  return newName;

              }

              public void setNewLink(String newLink) {

                  this.newLink = newLink;

              }

              public String getNewLink() {

                  return newLink;

              }

              public void setNewLevel(int newLevel) {

                  this.newLevel = newLevel;

                  addCrumb();

              }

              public int getNewLevel() {

                  return newLevel;

              }

              public void setCrumbSeparator(String crumbSeparator) {

                  this.crumbSeparator = crumbSeparator;

              }

              public String getCrumbSeparator() {

                  return crumbSeparator;

              }

          }

          ////////////////////////////////////////////////////////////////////////////////////////////////

           

          Breadcrumb.java:

          ///////////////////////////

           

          public class Breadcrumb {

              private String link;

              private String name;

              private int level;

           

              public Breadcrumb(String name, String link, int level){

                  this.link = link;

                  this.name = name;

                  this.level = level;

              }

           

              public void setLink(String link) {

                  this.link = link;

              }

              public String getLink() {

                  return link;

              }

              public void setName(String name) {

                  this.name = name;

              }

              public String getName() {

                  return name;

              }

           

              public void setLevel(int level) {

                  this.level = level;

              }

           

              public int getLevel() {

                  return level;

              }

          }

          /////////////////////////////////////////////////////////////////////

           

          Simple, but surely effective for some applications!  Enjoy!

          • 2. Re: Setting a bean property on page load
            tomjohn

            Thank you very much for this post. It is very useful. Have you found or tried another solution - I mean without javascript? I happy now .-))

            • 3. Re: Setting a bean property on page load
              swampdev

              Sure!  Good to see someone use it.  I would make some updates to some of my code above, though, in light of a few important aspects of a4j and Richfaces that I feel like I've figured out since....

               

              1) You should only have one form element to a page, and correct me if I'm wrong someone, but the only exception to this when you're using richfaces popup panels. In that case you just put  the popups outside the root form element and place another form inside it.  So in my example, my outputPanels shouldn't be outside of the form tag.

                   -An important thing that goes along with this 'one form per page' idea is that you use as many a4j:region as you're application needs, along with execute='regionId1 regionId2' to submit a post request.  Then, you use a4j:outputPanel to determine which parts of the page need to be updated.   In this way you have complete sectional control over what portions of your page get submitted and updated, not through the use of forms anymore. 

               

              2) Also, I have changed my application to use a4j:param's to submit the page properties onload.  This is only because it allows me to supply input arguments in the javascript.  I just personally find it more convenient.  I haven't come across any onload events any other place than javascript.   And it's only 3 lines. Oh, one thing to remember when using a4j:param is that you MUST set the name attribute to a UNIQUE value(relative to the page).  I think that got me a couple times in the beginning.

              • 4. Re: Setting a bean property on page load
                tomjohn

                Oh, this is very useful! I'm just a beginner with jsf and richfaces - experimenting. Once more, thank you very much!