Mr.J4mes
Mr.J4mes

Reputation: 9266

JSF 2.0: how can I dynamically generate Input component

In my application, I have the following Constants class

public class Constants {
    ...
    public static final int MAX_NUM_OF_PICTURES = 2
    ...
}

Earlier when I was using JSP, I managed to dynamically render input fields for uploading files based on this constant as following:

<%
    for (int i = 1; i < Constants.MAX_NUM_OF_PICTURES + 1; i++) {
%>
<tr>
    <td>Upload Picture <%= i %></td>
    <td><input name="<%= i%>" type="file" /></td>
</tr>
<tr>
    <td>Description <%= i %></td>
    <td><input type="text" name="<%= "description" + i%>" id="description" /></td>
</tr>
<%
    }
%>

Currently, I am trying to use JSF to achieve the above task. If these input fields are not dynamically generated, I can easily define the following properties in my backing bean:

@ManagedBean
@RequestScoped
public class MrBean {
   ...
   private UploadedFile picture1;
   private String       pictDescription1;
   ...
}

However, since these fields are now dynamically generated, I cannot know how many properties I would need to define in advance to capture these uploaded files.

I'd be very grateful if someone could give me an advice on how I should tackle this problem?

Best regards,

James Tran

Upvotes: 0

Views: 1735

Answers (1)

BalusC
BalusC

Reputation: 1109635

Put those properties in another javabean class and have a collection of those javabeans in your managed bean.

E.g.

public class Picture {

    private UploadedFile file;
    private String description;

    // ...
}

and

@ManagedBean
@ViewScoped
public class Profile {

    List<Picture> pictures;

    public Profile() {
        pictures = new ArrayList<Picture>();

        for (int i = 0; i < Constants.MAX_NUM_OF_PICTURES; i++) {
            pictures.add(new Picture());
        }
    }

    // ...
}

Then you can loop over it in for example <ui:repeat> (or maybe <h:dataTable>, but this isn't really suitable if you want two repeating rows instead of one).

<table>
    <ui:repeat value="#{profile.pictures}" var="picture" varStatus="loop">
        <tr>
            <td>Upload Picture #{loop.index + 1}</td>
            <td><t:inputFileUpload value="#{picture.file}" /></td>
        </tr>
        <tr>
            <td>Description #{loop.index + 1}</td>
            <td><h:inputText value="#{picture.description}" /></td>
        </tr>
    </ui:repeat>
</table>

I have no idea what component library you're using for uploading files, so I assumed it be just Tomahawk.

Upvotes: 2

Related Questions