You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Richard Wallace <rw...@thewallacepack.net> on 2005/06/13 20:17:53 UTC
Errant event firing
Hello,
I'm having another problem with my select list and the value changed
event listener. I have the following tag:
<h:selectManyListbox id="organizations"
value="#{contactHandler.selectedOrganizations}"
valueChangeListener="#{contactHandler.handleOrganizationChanged}"
onchange="submit()" immediate="true">
This is for an "Edit Contact" page so when the page is initially loaded
there is an organization selected. The problem that I'm having is that
when I click the update button to invoke the appropriate action handler
it is never called. The page just reloads. If I click the update
button a second time it does call the action handler.
I did a trace of the phases with a PhaseListener and found that it is
jumping from the apply request values phase to the render response
phase. So I added some logging in the places I call the
FacesContext.renderReponse() method and lo and behold the
handleOrganizationChanged() event handler is being called in spite of
nothing on the page having been changed. To investigate further I
logged the events old value and the new value and found that the old
value was empty when it shouldn't have been.
Is this a side effect of the event handling being declared as being
immediate? What can I do to fix this?
Thanks again for all the help,
Rich
Re: Errant event firing
Posted by Martin Marinschek <ma...@gmail.com>.
I was going to propose x:saveState, but x:inputHidden and forceId is
of course working as well!
Both are MyFaces extensions, by the way!
regards,
Martin
On 6/14/05, Richard Wallace <rw...@thewallacepack.net> wrote:
> Richard Wallace wrote:
>
> > Richard Wallace wrote:
> >
> >> Hello,
> >>
> >> I'm having another problem with my select list and the value changed
> >> event listener. I have the following tag:
> >>
> >> <h:selectManyListbox id="organizations"
> >> value="#{contactHandler.selectedOrganizations}"
> >> valueChangeListener="#{contactHandler.handleOrganizationChanged}"
> >> onchange="submit()" immediate="true">
> >>
> >> This is for an "Edit Contact" page so when the page is initially
> >> loaded there is an organization selected. The problem that I'm
> >> having is that when I click the update button to invoke the
> >> appropriate action handler it is never called. The page just
> >> reloads. If I click the update button a second time it does call the
> >> action handler.
> >>
> >> I did a trace of the phases with a PhaseListener and found that it is
> >> jumping from the apply request values phase to the render response
> >> phase. So I added some logging in the places I call the
> >> FacesContext.renderReponse() method and lo and behold the
> >> handleOrganizationChanged() event handler is being called in spite of
> >> nothing on the page having been changed. To investigate further I
> >> logged the events old value and the new value and found that the old
> >> value was empty when it shouldn't have been.
> >>
> >> Is this a side effect of the event handling being declared as being
> >> immediate? What can I do to fix this?
> >
> >
> > Ok, I found the problem and it's entirely my fault. But it brings up
> > another question. Basically all my page backing beans are request
> > scoped and this is an edit page so I need to pass in the id of the
> > contact to edit. I did this in the getContact() accessor method which
> > checks if the contact is null and if it is gets the contact id from
> > the external context parameter map. This is all well and good when I
> > initially go into the edit page with the url
> > http://localhost:8080/contact/edit.jsf?contactId=11.
> >
> > In the form I try and carry this through with a hidden form element
> > called contactId thinking that I should still be able to lookup the
> > external context parameter value for "contactId" and get the right
> > thing. That is, of course, wrong because the actual form element name
> > is like "_id1:contactId". So the reason it comes up with the empty
> > list of selected organizations is because it's using a newly
> > constructed object and not one loaded from the backend.
> >
> > So now my question is what is the best way to carry the id across page
> > reloads like this? I've seen the method where you would have the
> > currentContactId be a JSF managed bean property and then pass in
> > param.contactId. But that runs into the same kind of problem. The
> > other method I've seen for doing this sort of thing is to make the
> > actual link the user clicks on to get to the page a <h:commandLink>
> > element bound to an option that sets the current contact in a session
> > scoped backing bean and then does a redirect to the actual edit page.
> > I don't like this for a number of reasons, one being the session
> > scoped backing bean and the other being that users can't bookmark the
> > URL. I'll have to discuss this with some people here to see if the
> > latter really is an issue or not, but I'd like to get the feedback of
> > people on the mailing list that have done this before. So, what's the
> > most commonly accepted practice on how to handle this? The session
> > scoped backing bean which wraps the actual data model object? Or is
> > there a better way?
>
> Well I found a couple of solutions to this problem. I'm not sure either
> is the best solution but they both seem to work well enough.
>
> One solution was to add <x:saveState
> value="#{contactHandler.selectedOrganizations}"> element. After doing
> some testing it seems this causes the selectedOrganizations property to
> be set in the restore values phase before even any immediate events are
> handled. So it seems like it might be a good rule of thumb to use
> <x:saveState> on any values that you need in the event handler.
>
> In this case, however, the better solution was to use a a myfaces
> extension and use <x:inputHidden id="contactId" forceId="true"> to make
> sure the element has the name that the backing bean uses to load the
> actual data object.
>
> Rich
>
>
>
Re: Errant event firing
Posted by Richard Wallace <rw...@thewallacepack.net>.
Richard Wallace wrote:
> Richard Wallace wrote:
>
>> Hello,
>>
>> I'm having another problem with my select list and the value changed
>> event listener. I have the following tag:
>>
>> <h:selectManyListbox id="organizations"
>> value="#{contactHandler.selectedOrganizations}"
>> valueChangeListener="#{contactHandler.handleOrganizationChanged}"
>> onchange="submit()" immediate="true">
>>
>> This is for an "Edit Contact" page so when the page is initially
>> loaded there is an organization selected. The problem that I'm
>> having is that when I click the update button to invoke the
>> appropriate action handler it is never called. The page just
>> reloads. If I click the update button a second time it does call the
>> action handler.
>>
>> I did a trace of the phases with a PhaseListener and found that it is
>> jumping from the apply request values phase to the render response
>> phase. So I added some logging in the places I call the
>> FacesContext.renderReponse() method and lo and behold the
>> handleOrganizationChanged() event handler is being called in spite of
>> nothing on the page having been changed. To investigate further I
>> logged the events old value and the new value and found that the old
>> value was empty when it shouldn't have been.
>>
>> Is this a side effect of the event handling being declared as being
>> immediate? What can I do to fix this?
>
>
> Ok, I found the problem and it's entirely my fault. But it brings up
> another question. Basically all my page backing beans are request
> scoped and this is an edit page so I need to pass in the id of the
> contact to edit. I did this in the getContact() accessor method which
> checks if the contact is null and if it is gets the contact id from
> the external context parameter map. This is all well and good when I
> initially go into the edit page with the url
> http://localhost:8080/contact/edit.jsf?contactId=11.
>
> In the form I try and carry this through with a hidden form element
> called contactId thinking that I should still be able to lookup the
> external context parameter value for "contactId" and get the right
> thing. That is, of course, wrong because the actual form element name
> is like "_id1:contactId". So the reason it comes up with the empty
> list of selected organizations is because it's using a newly
> constructed object and not one loaded from the backend.
>
> So now my question is what is the best way to carry the id across page
> reloads like this? I've seen the method where you would have the
> currentContactId be a JSF managed bean property and then pass in
> param.contactId. But that runs into the same kind of problem. The
> other method I've seen for doing this sort of thing is to make the
> actual link the user clicks on to get to the page a <h:commandLink>
> element bound to an option that sets the current contact in a session
> scoped backing bean and then does a redirect to the actual edit page.
> I don't like this for a number of reasons, one being the session
> scoped backing bean and the other being that users can't bookmark the
> URL. I'll have to discuss this with some people here to see if the
> latter really is an issue or not, but I'd like to get the feedback of
> people on the mailing list that have done this before. So, what's the
> most commonly accepted practice on how to handle this? The session
> scoped backing bean which wraps the actual data model object? Or is
> there a better way?
Well I found a couple of solutions to this problem. I'm not sure either
is the best solution but they both seem to work well enough.
One solution was to add <x:saveState
value="#{contactHandler.selectedOrganizations}"> element. After doing
some testing it seems this causes the selectedOrganizations property to
be set in the restore values phase before even any immediate events are
handled. So it seems like it might be a good rule of thumb to use
<x:saveState> on any values that you need in the event handler.
In this case, however, the better solution was to use a a myfaces
extension and use <x:inputHidden id="contactId" forceId="true"> to make
sure the element has the name that the backing bean uses to load the
actual data object.
Rich
Re: Errant event firing
Posted by Richard Wallace <rw...@thewallacepack.net>.
Richard Wallace wrote:
> Hello,
>
> I'm having another problem with my select list and the value changed
> event listener. I have the following tag:
>
> <h:selectManyListbox id="organizations"
> value="#{contactHandler.selectedOrganizations}"
> valueChangeListener="#{contactHandler.handleOrganizationChanged}"
> onchange="submit()" immediate="true">
>
> This is for an "Edit Contact" page so when the page is initially
> loaded there is an organization selected. The problem that I'm having
> is that when I click the update button to invoke the appropriate
> action handler it is never called. The page just reloads. If I click
> the update button a second time it does call the action handler.
>
> I did a trace of the phases with a PhaseListener and found that it is
> jumping from the apply request values phase to the render response
> phase. So I added some logging in the places I call the
> FacesContext.renderReponse() method and lo and behold the
> handleOrganizationChanged() event handler is being called in spite of
> nothing on the page having been changed. To investigate further I
> logged the events old value and the new value and found that the old
> value was empty when it shouldn't have been.
>
> Is this a side effect of the event handling being declared as being
> immediate? What can I do to fix this?
Ok, I found the problem and it's entirely my fault. But it brings up
another question. Basically all my page backing beans are request
scoped and this is an edit page so I need to pass in the id of the
contact to edit. I did this in the getContact() accessor method which
checks if the contact is null and if it is gets the contact id from the
external context parameter map. This is all well and good when I
initially go into the edit page with the url
http://localhost:8080/contact/edit.jsf?contactId=11.
In the form I try and carry this through with a hidden form element
called contactId thinking that I should still be able to lookup the
external context parameter value for "contactId" and get the right
thing. That is, of course, wrong because the actual form element name
is like "_id1:contactId". So the reason it comes up with the empty list
of selected organizations is because it's using a newly constructed
object and not one loaded from the backend.
So now my question is what is the best way to carry the id across page
reloads like this? I've seen the method where you would have the
currentContactId be a JSF managed bean property and then pass in
param.contactId. But that runs into the same kind of problem. The
other method I've seen for doing this sort of thing is to make the
actual link the user clicks on to get to the page a <h:commandLink>
element bound to an option that sets the current contact in a session
scoped backing bean and then does a redirect to the actual edit page. I
don't like this for a number of reasons, one being the session scoped
backing bean and the other being that users can't bookmark the URL.
I'll have to discuss this with some people here to see if the latter
really is an issue or not, but I'd like to get the feedback of people on
the mailing list that have done this before. So, what's the most
commonly accepted practice on how to handle this? The session scoped
backing bean which wraps the actual data model object? Or is there a
better way?
Thanks
Rich