FAQ
Hello,

I'm working on writing my first webapp with JavaServer Faces and I'm
using a compiled libraries that I checked out earlier today. I'm having
a problem with filling in a bunch of select menu and select boxes
dynamically.

Here's the situation. I have a <h:selectOneMenu> element for a person
to select a company. When they change the selected company the form is
submitted and the next <h:selectOneMenu> is populated with the
departments in the company. When the department selected is changed a
<h:selectManyListbox> is supposed to be populated with the personnel in
that department.

Optimally, in the future, I'll change this to be an ajax interface. But
for now, because time is limited, I'm doing it all with regular old page
requests (I know, yuck, but you gotta do what you gotta do).

The problem is when the department selection changes, it seems as tho
the value for the selected organization is not being carried tho to the
backing bean. The proper organization is still selected in the form,
but because the department select items are populated with a method in
the backing bean that tries to use the beans value for the selected
organization the department menu shows up empty but the personnel list
box is populated.

The company and department <h:selectOneMenu> elements both use the
immediate="true" attribute to bypass any validations and then the event
handler doesn't do anything other than take the new value and call
setSelectedCompany/setSelectedDepartment and then jump to the rendering
phase with FacesContext.getCurrentInstance ().renderResponse (). I'm
guessing this completely bypasses setting any of the backing beans
values and just carries the form across as is cause all the other form
values are also maintained.

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. 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.

Any other ideas? Suggestions?

Thanks,
Rich

P.S. Is there anyway I can get you guys to start pushing SNAPSHOT builds
to the maven repos? I've been getting bitten by the null pointer
exception bug when forms with list boxes are submitted but nothing in
them is selected. I saw it was fixed in svn so checked out, built and
tested that and it worked beautifully. But it would be much easier for
me if there was a SNAPSHOT build in the maven repos. Thanks.

Search Discussions

  • Richard Wallace at Jun 11, 2005 at 7:02 pm

    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
  • Richard Wallace at Jun 11, 2005 at 7:30 pm
    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
  • Craig McClanahan at Jun 12, 2005 at 3:51 am
    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 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
  • Muhammad Ikram at Jun 12, 2005 at 11:52 am
    So you are suggesting that the list of states should be application scoped then? That would ensure it gets instantiated only once. right?

    K.
    ----- Original Message -----
    From: Craig McClanahan
    To: MyFaces Discussion
    Sent: Saturday, June 11, 2005 11:51 PM
    Subject: Re: Filling in select lists


    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<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 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
    >
    >
    >
  • Martin Marinschek at Jun 12, 2005 at 12:17 pm
    It depends, I would say.

    application scoped is great if you have one list for all users as
    Craig mentions, if you need to have a different list for each user,
    you would do it session scoped.

    Often you will need to change the output depending on the language
    setting of the user, so you might end up with a session scoped list
    created for the current user with his language setting, just copied
    from an application scope map which contains the state lists in all
    languages.

    regards,

    Martin

    On 6/12/05, Muhammad Ikram wrote:


    So you are suggesting that the list of states should be application scoped
    then? That would ensure it gets instantiated only once. right?

    K.


    ----- Original Message -----
    From: Craig McClanahan
    To: MyFaces Discussion
    Sent: Saturday, June 11, 2005 11:51 PM
    Subject: Re: Filling in select lists

    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 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
  • Richard Wallace at Jun 12, 2005 at 4:09 pm
    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 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
  • Martin Marinschek at Jun 12, 2005 at 7:00 pm
    have you tried to set the "immediate" attribute on the ui-input component?

    regards,

    Martin
    On 6/12/05, Richard Wallace 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 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
  • Richard Wallace at Jun 12, 2005 at 7:33 pm

    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 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 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


  • Korhonen, Kalle at Jun 13, 2005 at 4:35 am
    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
    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 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 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


  • Richard Wallace at Jun 13, 2005 at 3:34 pm

    Korhonen, Kalle wrote:
    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?

    I didn't know it existed. I've looked at some of the examples on its
    use and I'm still not sure exactly what it does. It's not very well
    documented from what I've been able to find. Care to fill me in on the
    details of how to use it and what it does?

    Thanks
    Rich
    Kalle


    -----Original Message-----
    From: Richard Wallace
    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 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 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






  • Korhonen, Kalle at Jun 13, 2005 at 5:14 pm

    -----Original Message-----
    From: Richard Wallace
    Subject: Re: Filling in select lists
    Korhonen, Kalle wrote:
    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?
    I didn't know it existed. I've looked at some of the
    examples on its use and I'm still not sure exactly what it
    does. It's not very well documented from what I've been able
    to find. Care to fill me in on the details of how to use it
    and what it does?
    With x:saveState you can store a value an object/property and restore it
    using the same id, i.e. on "edit user" page you have x:saveState
    id="editedUser" value="currentUser" (if currentUser is the name of your
    user bean). Then on "confirm user changes" page you use the same tag to
    restore the changed bean. The same goes for saving bean properties. Play
    with it and see how it works.

    Kalle
    -----Original Message-----
    From: Richard Wallace
    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 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 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






  • Richard Wallace at Jun 13, 2005 at 5:33 pm

    Korhonen, Kalle wrote:

    -----Original Message-----
    From: Richard Wallace
    Subject: Re: Filling in select lists
    Korhonen, Kalle wrote:

    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?
    I didn't know it existed. I've looked at some of the
    examples on its use and I'm still not sure exactly what it
    does. It's not very well documented from what I've been able
    to find. Care to fill me in on the details of how to use it
    and what it does?
    With x:saveState you can store a value an object/property and restore it
    using the same id, i.e. on "edit user" page you have x:saveState
    id="editedUser" value="currentUser" (if currentUser is the name of your
    user bean). Then on "confirm user changes" page you use the same tag to
    restore the changed bean. The same goes for saving bean properties. Play
    with it and see how it works.

    Kalle

    That worked perfectly! It was exactly the right magic I needed. Thanks
    a ton!
    Rich
    -----Original Message-----
    From: Richard Wallace
    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 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 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












Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupusers @
categoriesmyfaces
postedJun 10, '05 at 9:53p
activeJun 13, '05 at 5:33p
posts13
users5
websitemyfaces.apache.org

People

Translate

site design / logo © 2019 Grokbase