Dynamically updating a4j:repeat using data from fo

2019-04-15 01:46发布

问题:

I have a page where the user can upload a file to the server. He can set which groups/users can read/write (to) the file.

This is done by selects. One select holds the names of the groups the user is currently in, and on the same row is a select with options Read and Write. On the second row is the corresponding stuff for selecting users.

When the user selects a group and either Read or Write for said group, he then presses a button. After pressing the button I would like to show the user a list of permissions below the select. The list would have a group name, access setting for said group and a button to remove the permission item.

My problem is, I'm not able to update the page and show the list of permissions. Server side the permissions are added to an ArrayList, but I can't get the contents to show in a4j:repeat. How can I get the repeat tag to update?

Here is what I've been trying to do so far:

        <h:form>
        <h:selectOneMenu value="#{assetUploadForm.currentGroupName}" valueChangeListener="#{assetUploadForm.groupNameChanged}">
            <f:selectItem itemValue="users" itemLabel="users" />
            <f:selectItem itemValue="foobar" itemLabel="Foobar" />
            <a4j:ajax event="valueChange" render="second" execute="@this" />
        </h:selectOneMenu>

        <h:selectOneMenu value="#{assetUploadForm.currentGroupRW}" valueChangeListener="#{assetUploadForm.groupRWChanged}">
            <f:selectItem itemValue="R" itemLabel="Read"/>
            <f:selectItem itemValue="W" itemLabel="Write"/>
            <a4j:ajax event="valueChange" render="second" execute="@this" />
         </h:selectOneMenu>

        <a4j:commandButton action="#{assetUploadForm.addGroupRights}" value="add group" render="groupList"/>
        <ul>
        <a4j:repeat value="#{assetUploadForm.groupPermissions}" var="permission" id="groupList">
            <li><h:outputText value="#{permission.permissionSetItemId}"/></li>
        </a4j:repeat> 
        </ul>
        </h:form>

So, the problem is a4j:repeat is never updated. If I replace the repeat with an outputtext, and set the commandbutton to render it, the page is updated "correctly".

回答1:

The <a4j:repeat> does not render any HTML to the response. The render attribute of <a4j:ajax> however expects a component with that ID being physically present in the HTML DOM tree (it is namely behind the scenes using JavaScript document.getElementById() stuff to get the element which needs to be updated after the ajax response has returned). This is thus not possible in combination with <a4j:repeat>. You would need to specify its parentmost JSF HTML component instead, or at least to wrap it in a new one.

E.g.

<a4j:commandButton action="#{assetUploadForm.addGroupRights}" value="add group" render="groupList"/>
<h:panelGroup id="groupList">
  <ul>
    <a4j:repeat value="#{assetUploadForm.groupPermissions}" var="permission">
      <li><h:outputText value="#{permission.permissionSetItemId}"/></li>
    </a4j:repeat> 
  </ul>
</h:panelGroup>

As a different alternative, you can also just use the <rich:list> component instead which renders the complete <ul><li> for you already. You're then basically updating the <ul> directly.

<a4j:commandButton action="#{assetUploadForm.addGroupRights}" value="add group" render="groupList"/>
<rich:list id="groupList">
  <h:outputText value="#{permission.permissionSetItemId}"/>
</rich:list>

To learn about which components all are available and how to use them, peek around in the showcase site and the component reference.



回答2:

I don't know why it does not work but as a work-around you could probably use h:dataTable for this. With some css tweaking that could be rendered with the same looks.

Or wrap a a4j:outputPanel around the a4j:repeat and try what happens if you render that.

MAG, Milo van der Zee