2
votes

I want to create a mobile form using Primefaces 5.2 where one selectOneMenu result updates a second selectOneMenu via Ajax, exactly like the showcase example here: http://www.primefaces.org/showcase/ui/ajax/dropdown.xhtml but then a mobile version.

My question is very similar to this one: Primefaces Mobile's Ajax does not update a <p:selectOneMenu> but there is no answer.

I have created a JSF page and backingbean exactly like the showcase example, and it works.

However when I add the mobile aspect using <f:view renderKitId="PRIMEFACES_MOBILE" /> the second selectOneMenu is rendered plain after the update, and a perpetual spinner is displayed.

...
<f:view renderKitId="PRIMEFACES_MOBILE" />
...
<h:body>
<h:form>
    <p:growl id="msgs" showDetail="true" />

    <p:panel header="Select a Location" style="margin-bottom:10px;">
        <h:panelGrid columns="2" cellpadding="5">
            <p:outputLabel for="country" value="Country: " />
            <p:selectOneMenu id="country" value="#{dropdownView.country}" style="width:150px">
                <p:ajax listener="#{dropdownView.onCountryChange}" update="city" />
                <f:selectItem itemLabel="Select Country" itemValue="" noSelectionOption="true" />
                <f:selectItems value="#{dropdownView.countries}" />
            </p:selectOneMenu>

            <p:outputLabel for="city" value="City: " />
            <p:selectOneMenu id="city" value="#{dropdownView.city}" style="width:150px">
                <f:selectItem itemLabel="Select City" itemValue="" noSelectionOption="true" />
                <f:selectItems value="#{dropdownView.cities}" />
            </p:selectOneMenu>

            <p:outputLabel for="debug" value="Debug: " />
            <p:inputText id="debug" value="#{dropdownView.debug}"/>
        </h:panelGrid>
...

The Ajax call works, when my update target is debug my inputText is updated, but when my update target is city the selectOneMenu is not.

Is this a bug? Am I misusing the Mobile aspect? Documentation seems scarce on this.

EDIT

The inputText was not included in the source, corrected.

1
You are not misusing anything in my opinion. What/where is 'debug' and where is 'textfield'? Did you run this in a normal browser to, to see if it works there? Might be (hope not) a limitation of the mobile browser. And does it make a difference which mobile browser you use? And did you try 5.3-SNAPSHOT?Kukeltje
Code is now corrected. I am testing this in desktop Chrome, Firefox, and iOS simulator. PF 5.3-SNAPSHOT is worth a try, thanks.mvreijn
Allright - where can I find 5.3-SNAPSHOT ? I cannot download it and I cannot add it as a maven dependency.mvreijn
You have to build it from source I'm afraid…Kukeltje
OK I took the time this weekend to build 5.3-SNAPSHOT from SVN, and it still behaves the same way. Can anyone help me on this?mvreijn

1 Answers

3
votes

This is a bug in the JavaScript associated with PrimeFaces mobile. It didn't take into account that the mobile renderer inserts additional JS to afterwards relocate the HTML representation of the dropdown elsewhere in the DOM (evidence can be found by checking the difference between raw HTML output ("View Source" in browser) and the actual HTML DOM tree ("Inspect Element" in browser).

The exact JavaScript error as shown in Chrome's console is as below:

Uncaught NotFoundError: Failed to execute 'replaceChild' on 'Node': The node to be replaced is not a child of this node.

(I hope you'll take it as a learning hint to always check the browser's console for clues)

Your best bet is to report this as bug to PrimeFaces guys.

In the meanwhile, the workaround is to wrap it in another (plain) element and update it instead.

<p:selectOneMenu ...>
    ...
    <p:ajax ... update="cityWrapper" />
</p:selectOneMenu>

<h:panelGroup id="cityWrapper">
    <p:selectOneMenu id="city" ...>
        ...
    </p:selectOneMenu>
</h:panelGroup>

Unrelated to the concrete problem: that noSelectionOption="true" has only effect when you add hideNoSelectionOption="true" to the component. See also a.o. Best way to add a "nothing selected" option to a selectOneMenu in JSF. Otherwise, just leave out it.