3

I have a hidden <p:fileUpload> which is opened via <h:outputLabel>.

<p:messages id="message" autoUpdate="true" />

<h:form id="form">

    <p:fileUpload id="file-input" auto="true"
        allowTypes="/(\.|\/)(gif|jpe?g|png)$/" sizeLimit="10"
        invalidSizeMessage="wrong size" fileUploadListener="#{bean.image}"
        update="@form message" style="display: none;"
        invalidFileMessage="wrong file" />

    <h:outputLabel for="file-input_input">
        <h:graphicImage name="images/dummy.jpg" />
     </h:outputLabel>

    <h:outputText value="#{bean.file.fileName}" />
    <br />
    <h:outputText value="#{bean.file.size}" />
</h:form>

Unfortunately, no messages are displayed after validation failed (e.g invalid size or invalid file). Those messages are displayed inside the <p:fileUpload> content box instead of in <p:messages>.

How can I display those messages inside <p:messages> instead of inside <p:fileUpload>?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
alexander
  • 1,191
  • 2
  • 20
  • 40
  • How do you upload file/s using an invisible ``? In other words, why is it set to `display: none`? If it is not to be used anywhere, why don't you simply remove it? – Tiny Aug 04 '15 at 08:13
  • The image is displayed instead of the component. I can click on the image and the dialog appears. I edited the question aswell, thanks. – alexander Aug 04 '15 at 08:13
  • 1
    @Tiny: http://stackoverflow.com/q/17544141 – BalusC Aug 04 '15 at 08:19
  • 1
    _"And yes, the is pointing to an other ID. This **is** necessary, otherwise it wont work! "_: Define 'won't work'... Way to vague. And why not fix this issue... And you talk about a dialog for uploading? Do you have 2 fileuploads then? – Kukeltje Aug 04 '15 at 08:30
  • 1
    @Kukeltje: OP edited it in to explain comments of Tiny, but those actually distract from the real question, so I removed it to reduce noise. – BalusC Aug 04 '15 at 08:33
  • Sorry for my english and explaining. I was trying to explain the whole thing, sometimes my questions are not clear enough. Hope it is clear cut, now? @BalusC did it for me, thank you. – alexander Aug 04 '15 at 08:35
  • 1
    @BalusC: I see the edits, but the code and text are still 'vague'. Messages of a fileUpload need to be shown but the fileUpload is hidden, so how is it used? From the original text, I got that there is **another** file upload was/is being used... And the label points to a generated HTML input inside the span that is the real file upload component. So that will never work (the 'for' could as well be left out I think, wondering why there is no error)). So that code still distracts (i.m.o.). And how **is** the fileupload done? Way to much vagueness, or I completely miss something – Kukeltje Aug 04 '15 at 08:44
  • @Kukeltje: label directly refers the ID of the hidden HTML input element generated by the component. The `file-input` is actually the ID of the div wrapping it, which isn't useful. You can also see it yourself when you copy'n'paste'n'run it. This is a quite good MCVE. – BalusC Aug 04 '15 at 08:52
  • 2
    :-) you changed the comment.. I did read the link, but failed to see the relation. And yes, the label points to the actual input, but I'd have expected it to point to the the component and the component make it point to the correct html input. So from my understanding, the OP used a kind of 'hack' to make the actual fileupload dialog (the native one, not a PF dialog with another upload) show up... Now I get it all... pheeeew... Talk about noise.. Think I created some to :-( – Kukeltje Aug 04 '15 at 08:59
  • @Kukeltje Don't be like this. It is perfectly fine in my opinion. We all learned here, I guess. My question was not clear enough, that was my bad, indeed. As pointed out, simple run this example, and you will get it perfectly. My exampled is used to upload an image to the user profile (I really do not want to have an extra button for this, which is displayed). – alexander Aug 04 '15 at 09:03
  • 1
    @Alexander: I perfectly understand the usecase and even like the solution very much. Upvote coming up. – Kukeltje Aug 04 '15 at 09:22

1 Answers1

5

The validation is performed fully client side without hitting the server. So you can't control this from server side on.

The message container of the <p:fileUpload> is available via messageContainer property of the widget variable. Simple let jQuery move it into the <p:messages> when clicking the label:

<p:messages id="messages" ... />

<h:form>
    <p:fileUpload id="file-input" widgetVar="file-input" ... 
        styleClass="ui-helper-hidden" />
    ...
    <h:outputLabel for="file-input_input" ...
        onclick="PF('file-input').messageContainer.appendTo($('#messages'));" />
</h:form>

(I only renamed <p:message id> to be more sensible, and used a PrimeFaces specific class to hide it instead of an inline style)

The onstart and oncomplete attributes of <p:fileUpload> weren't usable as they are only executed when the client side validation has passed and the file upload request is actually sent.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Is there a way to use `showIcon=false` or a different tag like `` or a newer one like BootsFaces `? – alexander Aug 04 '15 at 09:21
  • Just alter JS code accordingly based on HTML DOM tree. – BalusC Aug 04 '15 at 09:23
  • I simple don't get it, sorry. I bet, I need to change the message tag in the first instance. Also I'm not sure, how can I add those messages to a other component. I see, you are using PF, is there something similar in BootsFaces or even in plain JSF? I do not find any information about `messageContainer`. – alexander Aug 04 '15 at 10:04
  • The `messageContainer` is indeed not documented. I just looked in PF-generated JS source code in `fileupload.js`. As to `PF()` function, this is definitely documented, it's referring the `widgetVar` and returns you a JS object representing the component in client side, offering JS/jQuery access to HTML element's properties and functions. As to BootsFaces and plain JSF, just ask a new Question. This isn't covered by the Question in its current form. But it boils down to my answer and my previous comment: simply use JS to manipulate the HTML DOM tree. – BalusC Aug 04 '15 at 10:05
  • Thanks, I am always afraid of asking so many things. Thanks for pointing out! – alexander Aug 04 '15 at 10:14