0
votes

I am creating an image gallery with JSF and PrimeFaces. I am using ui:repeat with p:graphicImage inside to display a list of images retrieved from db. Every image has an on click p:dialog (with its respective id) defined also inside ui:repeat. In the p:dialog I am showing again the clicked image and there is also a h:form that has inside a p:inputText and a p:commandbutton to save the text of p:inputText to a String property of a bean. The problem is that only last image of the list showed by ui:repeat "sees" the bean and set the property. If in the dialog of last image showed by ui:repeat I write a comment and click the commandbutton it sets the String text of the bean, if I do the same for the other images the String text is null. Maybe it's a problem of bean visibility. I tried to use different scopes for the bean but it doesn't work anyway.

This is the JSF code:

    <ui:repeat value="#{imageShowController.images}" var="img">
    <h:outputLink value="javascript:void(0)"
        onclick="PF('picDialog-#{img.id}').show();">
        <p:graphicImage value="#{imageShowController.streamedContent}"
            width="250" height="250" cache="false">
            <f:param name="id" value="#{img.id}" />
        </p:graphicImage>
    </h:outputLink>
    <p:dialog id="picDialog-#{img.id}" widgetVar="picDialog-#{img.id}"
        width="500" height="500">
        <p:graphicImage value="#{imageShowController.streamedContent}">
            <f:param name="id" value="#{img.id}" />
        </p:graphicImage>
        <h:form>
            <h:panelGrid columns="2" cellpadding="5">
                <p:inputText value="#{imageShowController.txt}" />
                <p:commandButton value="Submit comment"
                    action="#{imageShowController.saveComment()}">
                    <f:param name="id" value="#{img.id}" />
                </p:commandButton>
            </h:panelGrid>
        </h:form>
    </p:dialog>
</ui:repeat>

This is the bean (Java):

@ManagedBean
@RequestScoped
public class ImageShowController {
    @Inject
    private UserSessionBean userSession;
    @Inject
    private ImageDaoService imagedao;
    @Inject
    private CommentDaoService commentdao;

    private List<Image> images;
    private String text;
    private String id;

    @PostConstruct
    public void init() throws SQLException {
        images = new ArrayList<>();
        images = imagedao.findImagesByUserId( userSession.getUserId() );
    }

    public void saveComment(){
        FacesContext context = FacesContext.getCurrentInstance();
        String id = 
        context.getExternalContext().getRequestParameterMap().get("id");

        Comment comment = new Comment();
        comment.setText(text);
        comment.setDate(new Date());
        comment.setImage(imagedao.findById(Long.valueOf(id)).get(0));
        commentdao.addComment(comment);     
    }

    public StreamedContent getStreamedContent() throws IOException {
        FacesContext context = FacesContext.getCurrentInstance();

        if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
            return new DefaultStreamedContent();
        }
        else {
            id = 
            context.getExternalContext().getRequestParameterMap().get("id");
            System.out.println("INDEX: "+id);

            byte [] b = null;
            for (int i = 0; i < images.size(); i++) {
                if(images.get(i).getId() == Long.valueOf(id)){
                    b = images.get(i).getPicture();
                    break;
                }
            }
            return new DefaultStreamedContent(new ByteArrayInputStream(b));
        }
    }
}
1
You shouldn't be creating a dialog for each iteration. Put it outside and have variables in your be controlling it. The problem i see here, although not shown in your code, is you probably have a form surrounding the ui:repeat and you have your dialog also inside it with a form, you can't have a form inside another one.Jorge Campos
Thanks for the answer. The ui:repeat is not inside a form, there is only the form inside the dialog. I already tried to put the dialog outside ui:repeat but the problem was that I need to pass to the dialog the id of the respective image and it was not possible if the dialog was outside. How can I do it?Euleo
Try removing the throws SQLException from your PostConstruct annotated method init. See what happens.Jorge Campos
I removed throws SQLException but nothing changes. @Kukeltje I don't think that my question it's a duplicate of that because I am asking how to set a bean property from jsf and in the other question it's asked how to get and display a property from bean to jsf. This works for me. My problem is that the set works only for last element of the ui:repeatEuleo

1 Answers

0
votes

I solved using tag c:forEach of JSTL instead of ui:repeat. It works!!