0

I am stuck with a problem that doesnt make any sense to me. I have a listbox which fires selectionChange-Events with simple Ajax. The idea is that the edit-button isnt enabled until a item in the list is selected. So I created the following code.

<h:form>
    <h:selectManyListbox value="#{bean.selectedIds}">
        <f:selectItems value="#{bean.listOfItems}" />
        <f:ajax render="edit"
            listener="#{bean.selectionChanged}" />
    </h:selectManyListbox>
    <br />

    <h:commandButton id="add" value="#{msgs.add}"
        action="#{bean.addNew}" />

    <h:commandButton id="edit" value="#{msgs.edit}"
        disabled="#{bean.editButtonDisabled}"
        action="#{bean.edit}" />
</h:form>

The button is enabled and disabled as I wish but as it turns out, the edit-button isnt triggering any action (I added some sysout to the add- and edit-method in the bean and the edit-method is never called)...instead the html changes. The above code is nested in a simple div. When I click edit, the whole form is outside of that div.

When I add this ajax-behavior to the add-button, the same happens there and vice versa, when I remove the disabled-attribute from the edit-button everything works???

I already had a look at BalusC answer here but I couldnt find any mistake related to that list. No nested forms and so on...its just a simple page with a template.

I am using Mojarra 2.1.2 on JBoss 7.1.Final.

Any help is appreciated. Thanks

Community
  • 1
  • 1
lostiniceland
  • 3,729
  • 6
  • 38
  • 50
  • Don't you need to re-render the whole form since the commandButton action will be attached to the html form element? – Matt Handy Feb 22 '12 at 11:04
  • I tried that but it didn't help. Besides, why would I need to render the form? I expected that the JavaScript created by this would only change the button in the DOM-tree. – lostiniceland Feb 22 '12 at 12:19
  • This was just a guess. I am not quite sure how disabling/enabling is realized. Did you try the same with rendering, e.g. with two buttons conditionally rendered? – Matt Handy Feb 22 '12 at 12:31
  • No not yet. But when I remember right then when using 'rendered' I have to do a full page-reload and thats a little bit much. – lostiniceland Feb 22 '12 at 12:42

2 Answers2

2

This issue is covered by point 5 of the answer which you've linked.

The rendered attribute of the component and all of the parent components should not evaluate to false during the apply request values phase of the form submit request. JSF will namely recheck it then as part of safeguard against tampered/hacked requests. Putting the bean in the view scope and/or making sure that you're preinitializing the condition in (post)constructor of the bean should fix it. The same applies to the disabled attribute of the component, which should not evaluate to true during processing the form submit.

I suggest to change @RequestScoped on BikeManagementPanelBean to @ViewScoped.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Ups :-D I've read that ViewScoped is the best way to go but I am using CDI which doesnt have this scope :-/ When I follow the statement above (preinitializing the condition in postconstruct): wouldnt that mean that the attribute would always remain false (in my case since the button should be disabled if no selection occured)? – lostiniceland Feb 22 '12 at 13:19
  • 1
    Not if you preinitialize it properly based on some request parameter. The submitted dropdown value is available as request parameter. Yes, this is ugly, that's why the view scope exists so that you don't need to fiddle with request parameters while interacting with the same view. As to the view scope in CDI, your best bet is `@ConversationScoped`. – BalusC Feb 22 '12 at 13:21
  • Thanks again. I will try that. It should be possible with a ViewParameter. – lostiniceland Feb 22 '12 at 13:24
  • 1
    @lostiniceland: No, that's too late. It will set the value during update model values phase while you need it during apply request values phase. That's when JSF will determine the action which is to be invoked. You need `@ManagedProperty("#{param['clientId:of:menu']}")`. – BalusC Feb 22 '12 at 13:28
0

try something like this

<h:commandButton id="edit" value="#{msgs.edit}"
    disabled="#{bikeManagementPanelBean.editButtonDisabled eq false}"
    action="#{bean.edit}" />

try to wrap it again with the <h:panelGroup> and render the instead of the button...

Daniel
  • 36,833
  • 10
  • 119
  • 200
  • Thanks for the quick reply. Unfortunately wrapping doesnt solve this and rendering the form does neither (see second comment on the question) – lostiniceland Feb 22 '12 at 12:21
  • ALMOST :-D It is still not working but when the button is enabled when I open the page...the action is triggered. So it looks like that once the ajax-call happened it messes something up. I had a look at the html-source but nothing changed here. Is there another Add-On for Firefox that shows the actual DOM? – lostiniceland Feb 22 '12 at 12:40
  • 1
    You could use `ui:debug` to see the DOM – Matt Handy Feb 22 '12 at 12:48
  • try to wrap it again with the and render the instead of the button... – Daniel Feb 22 '12 at 13:03
  • How exactly does `eq false` change the expression? This makes no sense. – BalusC Feb 22 '12 at 13:05
  • Thanks...thats quite usefull. There seems to be a problem with my RequestScoped Bean. When I set it to SessionScoped it works. – lostiniceland Feb 22 '12 at 13:07
  • @BalusC the eq false didnt change the condition, acutally it just enabled the button when entering the page and I was able to see that it works before any Ajax-Thingy happens. Since I found quite some articles from you: do you have any idea about my previous comment (why a RequestScoped bean has a problem with Ajax) – lostiniceland Feb 22 '12 at 13:09
  • @lostiniceland: That comment was targeted to Daniel. Note that I've already posted an answer. – BalusC Feb 22 '12 at 13:09
  • @BalusC it was a guess, i saw something similar in some other Q' , apparently i was wrong... – Daniel Feb 22 '12 at 13:29