tags:

views:

364

answers:

4

I have this select option:

<f:verbatim>Pages: </f:verbatim>
<h:selectOneMenu id="selectPage" value="#{pageList.selectedPage}">
    <f:selectItems value="#{pageList.selectPages}" />
</h:selectOneMenu>

And the backing bean (called mybean2) for this is:

private int pages;

public void getPages(int Pages) 
{
 this.pages = Pages;
}

// getter methods
public List<SelectItem> getSelectPages() 
{
 selectPages = new ArrayList<SelectItem>();
        pages++;
        for (int i = 1; i > pages; i++) {
         selectPages.add(new SelectItem(Integer.toString(i), Integer.toString(i)));
        } 

     return selectPages;
}

public String getSelectedPage()
{
     return selectedPage;
}

// setter methods
public void setSelectPages(List<SelectItem> selectPages) {
        this.selectPages = selectPages;
}  

public void setSelectedPage(String selectedPage) {
     this.selectedPage = selectedPage;
}

The getPages method above gets the page count from mybean1.submit method. Thus, for example, when the submit method returns 30, how am I able to pass this value into the getSelectPages method so it can dynamically created the number of pages as in:

for (int i = 1; i > pages; i++) {

Also, I want mybean2 to be generic i.e. I don't want other beans to be referenced within mybean2 directly. For example, I don't want to reference like this within mybean2:

mybean1 mb1 = new mybean1();
pages = mb1.getPages();

Otherwise, I have to declare separate instances of other beans (about 12 others) that send pages count to mybean2 for it to action - this way would be way too messy...

Any hint or code example is much appreciated. Thanks.

+1  A: 

If you want that your mybean2 to be generic, you can put specific bean as session/request variable and in your mybean2 gets it from that scope.
Code for setting bean in session scope:

FacesContext context = FacesContext.getCurrentInstance();
Map sessionMap = context.getExternalContext().getSessionMap();
sessionMap.put("beanName", yourBean);

In your mybean2 you will get current bean by:

FacesContext context = FacesContext.getCurrentInstance();
Map applicationMap = context.getExternalContext().getApplicationMap();
GetPagesInterface yourBean = (GetPagesInterface)applicationMap.get("beanName");

For following code you can put this code in methods and create utility bean for that. Also method public void getPages(int Pages) should be as method in interface (GetPagesInterface) that all beans should implement.

Besides, in code that you pasted you have bad error, code:

pages++;
   for (int i = 1; i > pages; i++)

you should replace by:

for (int i = 1; i > pages+1; i++)

because metod getSelectPages might be called many times and that will be inrease your pages value.

cetnar
If I have configured my other beans in faces-config.xml, I gather this statement:Map applicationMap = context.getExternalContext().getApplicationMap();would allow me to the value of the managed-bean-name attribute?I've only started on JSF over 3 weeks ago (I'm still new to it) so I'm not really sure about writing the GetPagesInterface. Do you have an example of how to do this? Please help.Currently, I'm getting the pages count from the database via a method in mybean1. I don't know how to convert this method to the GetPagesInterface you mentioned.
icepax
@icepax. GetPagesInteface is your new interface that you should create and it's a temporary name coined by me. Using getApplicationMap() is not a good idea because it's whole application configuration (seams you have a very simple app). From what are you learnign JSF? Maybe you consider vistit free JavaPassion course (http://www.javapassion.com/j2ee/#JavaServer_Faces_JSF) a review your code after. I think that problem you want to solve is easy but you try to do it wrong way.
cetnar
A: 

As cetnar says, you can look up values directly using the FacesContext.

As an alternative, you may be able to inject the value via your faces-config.xml configuration. In this sample descriptor, an expensive-to-create bean is kept in the session and injected into a request-scope bean when as required:

  <managed-bean>
    <managed-bean-name>expensiveBean</managed-bean-name>
    <managed-bean-class>lifetime.ExpensiveBean</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
  </managed-bean>
  <managed-bean>
    <managed-bean-name>requestBean</managed-bean-name>
    <managed-bean-class>lifetime.RequestBean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
    <managed-property>
      <property-name>cachedAsset</property-name>
      <property-class>lifetime.ExpensiveBean</property-class>
      <value>#{expensiveBean}</value>
    </managed-property>
  </managed-bean>

The advantage of this approach is that you can keep your model free of JSF dependencies, making them easier to unit test. It isn't always possible to do this, of course. See the JSF spec for full details on the rules for property injection (you probably want the 1.2 spec).

McDowell
A: 

@McDowell. I've gone through this spec (I think this is what you meant) JavaServer™ Faces Specification Version 1.2 Final Draft by Ed Burns, Roger Kitain. There wasn't a good example in there that I could see relating to my JSF problem. It would have been nice if the authors have provided code examples so people can understand the spec a little bit better. I'll see if I can google any example regarding bean injection. Thanks.

icepax
A: 

Solved it. Just move the code to calculate the pages from mybean1 to mybean2.

@BalusC. Hi Baulke - pageList is mybean2. Sorry, I was trying to simplify it. Mybean1 is where I process the submit method to get the number of pages to pass to pageList (aka mybean2). Anyway, I already solved this problem.

It would be nice, however, to know how to do this with dependency injection (DI). I went through JSF 1.2 spec but there wasn't an example there about DI I could follow. I think my method work OK for me.

icepax