2
votes

I've hit a wall. I know the a4j and rich tags pretty well (I use Seam 2.2.0 and Richfaces 3.3.1). However, I'm trying to do something quite simple, but in a rich:modalPanel.

It seems that rich:modalPanels do not allow Ajax events to be fired. Here's a simple breakdown: I have a h:selectOneMenu with some items in it and whose value is attached to a backing bean. Attached to that h:selectOneMenu is a a4j:support tag so that whenever the change event is fired, the backing bean should get updated. Truly simple stuff eh?

However, when this h:selectOneMenu is in a rich:modalPanel the onchange event doesn't update the backing bean until the rich:modalPanel closes.

I can confirm this because I'm running it in Eclipse debug mode and I have a breakpoint on the setter of the property that's hooked up to the h:selectOneMenu. This is driving me mad! This is vanilla stuff for Ajax, but rich:modalPanels don't seem to allow it.

So, the question is: can I do Ajax stuff within a rich:modalPanel? I'm basically trying to use the rich:modalPanel as a form (I've tried a4j:form and h:form to no avail) that reacts to changes to the drop down (e.g. when the user changes the drop down, a certain part of the form should get reRendered). Am I trying to do something that's not possible?

Here's a simplified version of the modalPanel:

<rich:modalPanel id="quickAddPanel">
    <div>
        <a4j:form id="quickAddPaymentForm" ajaxSubmit="true">
                <s:decorate id="paymentTypeDecorator">
                    <a4j:region>
                        <h:selectOneMenu
                            id="paymentType"
                            required="true"
                            value="#{backingBean.paymentType}"
                            tabindex="1">
                            <s:selectItems 
                                label="#{type.description}"
                                noSelectionLabel="Please select..."
                                value="#{incomingPaymentTypes}"
                                var="type"/>
                            <s:convertEnum/>
                            <a4j:support 
                                ajaxSingle="true" 
                                event="onchange"
                                eventsQueue="paymentQueue"
                                immediate="true"
                                limitToList="true"
                                reRender="paymentTypeDecorator, paymentDetailsOutputPanel, quickAddPaymentForm"/>
                        </h:selectOneMenu>
                    </a4j:region>
                </s:decorate>
            </fieldset>

            <fieldset class="standard-form">
                <div class="form-title">Payment details</div>
                <a4j:outputPanel id="paymentDetailsOutputPanel">
                    <h:outputText value="This should change whenever dropdown changes: #{backingBean.paymentType}"/>
                </a4j:outputPanel>
            </fieldset>
        </a4j:form>
    </div>
</rich:modalPanel>

Regards, Andy

4
is any action called by a4j:support onchange event? if yes then have you confirmed that action is called? - niksvp
No. It's a simple a4j:support event='onchange' binding that makes sure that when the drop down changes, the backing bean value it's bound to will get updated. And it does get updated, but only after the modal panel closes. If it wasn't in a modal panel, the update of the bean would happen each time the drop down value changed. - Andy Deighton
Modalpanel with a form (h or a4j) inside should work. Ah, and don't forget to reRender it. Edit and post your modal code, so we can help you better. - Renan
OK I've added a simplified version of the modalPanel. The thing that should happen, but isn't is the h:outputText value="This should change whenever...". - Andy Deighton

4 Answers

3
votes

use <h:form>

and remove following attributes from : ajaxSingle="true", immediate="true"

1
votes

It should work. Check with a4j:log that updated markup (which you re-render) is sent from the server. I don't believe it causes the problem, but you can change a few things in your code:

ajaxSubmit=true - you don't really need it as you use a4j:support ajaxSingle=true and a4j:region - is the same thing in your case limitToList=true - you don't need it as you don't update any other areas on the page.

0
votes

Try taking form outside of your modalPanel tag:

<a4j:form id="quickAddPaymentForm" ajaxSubmit="true">
    <rich:modalPanel id="quickAddPanel">
        <div>

also make sure your "quickAddPaymentForm" is not nested

0
votes

Check HTML options generated by f:selectItems or s:selectItems do not contain trailing spaces (view page source from browser):

<select>
  <option value="0    ">Select One    </option>
  <option value="id1    ">Choice 1    </option>
  <option value="id2    ">Choice 2    </option>
  <option value="id3    ">Choice 3    </option>
</select>

If so, remove the trailing white spaces in server side code,

<select>
  <option value="0">Select One</option>
  <option value="id1">Choice 1</option>
  <option value="id2">Choice 2</option>
  <option value="id3">Choice 3</option>
</select>

I found that the trailing spaces prevent Ajax event from firing when a4j:support and h:selectOneMenu working inside a rich:modalPanel, even though it works fine outside of rich:modalPanel. Here is a working sample code:

<h:form>
<rich:modalPanel id="myPanel" autosized="true" width="700" showWhenRendered="true">
  <table cellpadding="4" cellspacing="2" align="center" width="100%">
  <tr>
    <td align="left">
      <h:selectOneMenu styleClass="dropdown" id="dropdownList"
          value="#{backbean.currentChoice}"
          valueChangeListener="#{backbean.choiceChanged}" >
          <f:selectItems value="#{backbean.choiceItems}"></f:selectItems>
          <a4j:support event="onchange" reRender="whatPicked" ajaxSingle="true" />
          </h:selectOneMenu>
      </td>
    </tr>
    <tr>
      <td>
        <a4j:outputPanel id="whatPicked"> 
          <h:outputText value="#{backbean.currentChoice }"></h:outputText>
        </a4j:outputPanel>
      </td>
    </tr>
  </table>
</rich:modalPanel>
</h:form>