Looks to me that you should use x:saveState to extend the lifetime of
the request scoped bean and/or to save the specific properties of the
bean - unless there is some specific reason why you are avoiding the use
of x:saveState?

Kalle 

> -----Original Message-----
> From: Richard Wallace [mailto:[EMAIL PROTECTED] 
> Sent: Sunday, June 12, 2005 12:33 PM
> To: MyFaces Discussion
> Subject: Re: Filling in select lists
> 
> Martin Marinschek wrote:
> 
> >have you tried to set the "immediate" attribute on the 
> ui-input component?
> >
> >  
> >
> Yes.  I have immediate="true" set for the <h:selectOneMenu> 
> elements and in the event handler I have it updating the 
> selected value and then jumping to the renderResponse() phase 
> to bypass validation.  The problem is that the backing bean 
> is request scoped and the previously set value for the first 
> <h:selectOneMenu> does not get set again in the backing bean. 
>  So the only way I can think to get that value is to use the 
> getExternalContext().getRequestParameterMap().  Here's the 
> JSF tags so you can get a better idea of what is going on 
> cause I don't think I'm getting my thoughts across very clearly.
> 
>                 <h:panelGroup>
>                     <h:outputLabel for="organization" 
> value="Organization" />
>                     <h:selectOneMenu id="organization" 
> value="#{courseHandler.selectedOrganization}" 
> valueChangeListener="#{courseHandler.handleOrganizationChanged}" 
> onchange="submit()" immediate="true">
>                         <f:selectItem itemValue="" />
>                         <f:selectItems
> value="#{organizationHandler.organizationChoices}" />
>                     </h:selectOneMenu>
>                 </h:panelGroup>
>                 <br />
>                 <h:panelGroup>
>                     <h:outputLabel for="department" 
> value="Department" />
>                     <h:selectOneMenu id="department" 
> value="#{courseHandler.selectedDepartment}" 
> valueChangeListener="#{courseHandler.handleDepartmentChanged}" 
> onchange="submit()" immediate="true">
>                         <f:selectItem itemValue="" />
>                         <f:selectItems
> value="#{courseHandler.departmentChoices}" />
>                     </h:selectOneMenu>
>                 </h:panelGroup>
>                 <br />
>                 <h:panelGroup>
>                     <h:outputLabel for="instructors" 
> value="Instructors" />
>                     <h:selectManyListbox id="instructors" 
> value="#{courseHandler.selectedInstructors}">
>                         <f:selectItems
> value="#{courseHandler.contactChoices}" />
>                     </h:selectManyListbox>
>                 </h:panelGroup>
> 
> Now the selectItems for the department depend on the selected 
> value of the organization and the selectItems for the 
> instructors list depends on the selected value for the 
> departments.  What's happening is that when a user selects 
> the organization the department list gets populated just 
> fine.  When they select the department, the instructors list 
> gets populated fine, but the departments list comes up empty 
> because the value for the organization is never set in the 
> backing bean because the update model phase is also bypassed. 
>  The only ways I can think to fix this is to make the backing 
> bean session scoped so that the selected organization is 
> persisted across requests.  But that makes me nervous cause 
> it seems error prone.  The only other way to do it is to use the
> getExternalContext().getRequestParameterMap() and lookup the 
> value for the selected organization in the 
> handleDepartmentChanged() event handler.  But that seems like 
> a bad idea because it means I have to know the id of the 
> element ahead of time, which I think is just sloppy design.
> 
> I'll probably wind up switching to a session scoped backing 
> bean if I have to.  But that raises all sort of other 
> problems in other areas that I'm not entirely sure how to 
> work around.  I guess I could move stuff that needs to be 
> request based like the dynamic choice elements to be request 
> scoped and keep the current working object session scoped or 
> something like that.
> 
> Does that sound like a decent approach or is there a better way?
> 
> Thanks again,
> Rich
> 
> >regards,
> >
> >Martin
> >
> >On 6/12/05, Richard Wallace <[EMAIL PROTECTED]> wrote:
> >  
> >
> >>I understand all that you've said and am using some 
> application scoped 
> >>beans for global select items that don't change.  The 
> problem is that 
> >>the list of items that I'm working with now are database backed and 
> >>are likely to change often.  I can maybe cache the top level select 
> >>list items, the organizations and update it when an organization is 
> >>added or updated.  But the others, the list items for 
> departments and 
> >>personnel are dependent on the selected organization so 
> there's no way 
> >>to cache them.
> >>
> >>What about my other questions?  When the second select list, the 
> >>department, selected value changes and the page is submitted for 
> >>immediate event handling, it seems the only way to avoid validation 
> >>_and_ have the selected organization set in the backing bean is to 
> >>lookup the value myself using the 
> >>FacesContext.getExternalContext().getParameterMap().  Is there a 
> >>better way to accomplish this?
> >>
> >>Thanks for the feedback,
> >>Rich
> >>Craig McClanahan wrote:
> >>
> >>    
> >>
> >>>One thing to remember is that you are *not* limited to 
> referencing a 
> >>>single backing bean.  Using a request scope backing bean 
> >>>corresponding to the page is fine ... but quite often, the 
> lists of 
> >>>select items are fairly constant, and you'd *really* like to build 
> >>>them only once, right?
> >>>
> >>>In the Shale <http://struts.apache.org/shale> "use cases" example 
> >>>application, there is an illustration of the technique I 
> prefer for 
> >>>this ... bind select lists to a property on an application scoped 
> >>>managed bean (if they are common to all users) or on a 
> session scoped 
> >>>managed bean (if they are specific to a user).  The 
> example includes 
> >>>"select locale" use case, which includes a dropdown like this:
> >>>
> >>>   <h:selectOneListbox id="locale"
> >>>       value="#{locale$select.locale}">
> >>>           <h:selectItems value="#{domains.supportedLocales}"/>
> >>>   </h:selectOneListbox>
> >>>
> >>>where "locale$select" is my request scoped managed bean for this 
> >>>page, and "domains" is an application scoped managed bean that 
> >>>includes this
> >>>method:
> >>>
> >>>   public SelectItem[] getSupportedLocales();
> >>>
> >>>Inside this method, you have a number of alternative strategies 
> >>>available ... and you can change your choice without 
> callers having a 
> >>>clue :-).  Consider among other options:
> >>>
> >>>* Lazily instantiating the list the first time someone 
> calls this method.
> >>>
> >>>* Using a ServletContextListener to load up the appropriate data 
> >>>before  the first request is received.
> >>>
> >>>* Either of the above two techniques, plus a timer thread to erase 
> >>>the  cached value after a given amount of time (to pick up the 
> >>>changes that  occasionally occur, without having to 
> restart the app).
> >>>
> >>>* Either of the above two techniques, plus embedded logic 
> that does a  
> >>>relatively cheap database access to determine whether the 
> data has  
> >>>changed, and refreshes the list first.
> >>>
> >>>Doing this sort of logic on every request is quite likely 
> a waste of 
> >>>resources.  Strive to minimize the number of times you do 
> things like 
> >>>"create a SelectItems array containing the 50 state 
> abbreviations and 
> >>>names" :-).  That's the sort of thing I would want to do just once 
> >>>:-).
> >>>
> >>>Craig McClanahan
> >>>
> >>>
> >>>On 6/11/05, Richard Wallace <[EMAIL PROTECTED]> wrote:
> >>>
> >>>
> >>>      
> >>>
> >>>>I just thought that I should also mention that my backing 
> bean is a 
> >>>>request scoped object.  So another solution is to switch 
> this to a 
> >>>>session based backing bean, but my backing bean is where 
> the select 
> >>>>items for organizations, departments and contacts for the 
> list boxes 
> >>>>and drop-down menus are generated.  I would like to be 
> able to cache 
> >>>>those for the life of the request but they shouldn't be cached 
> >>>>across requests since they could change at any time.
> >>>>
> >>>>What's the best practice for these backing beans?  My design is 
> >>>>pretty much following the design ideas in a couple of 
> articles I've 
> >>>>read where the backing bean contains the current selected 
> object and 
> >>>>the JSF pages bind with 
> >>>>value="#{contactHandler.currentContact.firstName}" for 
> example.  Is 
> >>>>it better to have this backing bean be session scoped or 
> request scoped?
> >>>>
> >>>>Richard Wallace wrote:
> >>>>
> >>>>
> >>>>
> >>>>        
> >>>>
> >>>>>Richard Wallace wrote:
> >>>>>
> >>>>>
> >>>>>
> >>>>>          
> >>>>>
> >>>>>>So what do I need to do to fix this?  One idea is to 
> try and find 
> >>>>>>the value that JSF will use in the form and use that if 
> there is 
> >>>>>>one and then otherwise use the backing beans value when I'm 
> >>>>>>generating the department choices.  Seems kind of hacky since 
> >>>>>>that's one of the things that JSF is supposed to do for you is 
> >>>>>>provide the form values.  I'm also not certain how to get the 
> >>>>>>values that JSF is going to use in the forms without 
> having it update the model values.
> >>>>>>
> >>>>>>
> >>>>>>            
> >>>>>>
> >>>>>Well, I figured this part out at least.  I can use the 
> >>>>>FacesContext.getExternalContext ().getRequestParameterMap(), but 
> >>>>>then I'd need to know the key of the form and form element to be 
> >>>>>able to lookup the value.  Obviously, not an ideal solution.
> >>>>>
> >>>>>
> >>>>>
> >>>>>          
> >>>>>
> >>>>>>Another idea is if I can somehow avoid doing the 
> validation some 
> >>>>>>other way.  That's really the only reason I need to do 
> the event 
> >>>>>>processing right away and then skip to the rendering 
> phase.  But 
> >>>>>>I've looked and there doesn't seem to be another way of 
> bypassing validation.
> >>>>>>
> >>>>>>
> >>>>>>            
> >>>>>>
> >>>>>Well, I've looked around and this doesn't seem possible. 
>  Unless I 
> >>>>>can do something with PhaseListeners, but I don't see how.
> >>>>>
> >>>>>Please help!
> >>>>>
> >>>>>Thanks,
> >>>>>Rich
> >>>>>
> >>>>>
> >>>>>          
> >>>>>
> >>>>
> >>>>        
> >>>>
> >>    
> >>
> 

Reply via email to