views:

92

answers:

2

Hi,

I have a dropdown list of items a user can select from (the view is JSF). I would like for an image to appear on the same JSF page after a user selects an item from the dropdown list (i.e. A user select the word "Cat" from the dropdown list, and group of different cat images appear)

How would I code this in JSF?

Note* I'm using JSF 2.0 with facelets, not JSPs.

+1  A: 

Provide a list with image URL's in the dropdown and use h:graphicImage to display an image on the selected URL. Then, use f:ajax to re-render the image on change the dropdown.

Here's a kickoff example:

<h:form>
    <h:selectOneMenu value="#{bean.imageURL}">
        <f:selectItems value="#{bean.imageURLs}" />
        <f:ajax event="change" render="image" />
    </h:selectOneMenu>
    <h:graphicImage id="image" value="#{bean.imageURL}" /> 
</h:form>

Bean:

private List<String> imageURLs; // +getter
private String imageURL; // +getter +setter
BalusC
Thanks for the response. This seems logical. I have heard suggestions to use Ajax. I appreciate the feedback.-Calvin
Calvin Han
The only thing I'm not clear on is how the string would render on the page. From you code, would the user see a list of "http://..." strings as choices?
Calvin Han
The `<h:graphicImage>` renders a HTML `<img>` element. The `value` becomes its `src` attribute. So logically, you could just put those images in public webcontent, there where your JSF/XHTML file also is. Open the page in webbrowser, rightclick and choose *View Source*. All will become clear.
BalusC
Will this logic work with multiple images? (i.e. I select "Cat" from a dropdown list multiple images of cats are returned)?
Calvin Han
Truly, just put `<h:graphicImage>` in an `<ui:repeat>` or `<h:dataTable>` and re-render it on change. Use a `Map<String, List<String>>` instead to hold the images.
BalusC
Thanks for your patience BalusC. I think I have enough information now to figure this out.-C
Calvin Han
You're welcome. Don't forget to mark the answer which helped most in solving the actual problem to accepted.
BalusC
I'll be sure to do so BalusC. A combination of all different answers have been helping.-C
Calvin Han
A: 

BalusC's answer is (as always :) correct, but as you noticed there will be a list of URLs in the selectOneMenu. That is exactly why I asked you how do you store your images. The way I usually do it: (and from what I know that's the standard way of doing it, hopefully someone will correcty me if I'm wrong) you store the image somewhere on the server and in your DB you store its location. That's why I would suggest to make a MyImage class (which will be mapped to a DB table) where you would store the name of the image and a way to get its location on the server (for example you can do it using namespaces like cats will have a String namespace = "cats" and a String imageName and a method that will return the url like String getImageLocation() {return "http://something.com/images/"+namespace+"/"+imageName;} remember that it's important to make it look like a getter so the JSF can use it). Then all you have to do is to get the list of MyImages for a given namespace from your DB and render the images in a dataTable, something like this:

<h:dataTable value="#{myBeanWithAListOfImages.images}" var="img">
    <h:column>
        <h:graphicImage value="img.imageLocation"/>
    </h:column>
</h:dataTable>

Where images is a List<MyImage>. This should work and print the images in a single column.

Zenzen
This makes sense. I'll give it a shot. FYI, I'd would rather not have a dataTable rendered. I'm really picky on the UI, and I was looking more for a list of images returned, similar to Netflix's images for movies :), if you're familiar. (i.e. based on what generes of movies you're looking for, netflix returns rows of movie images and has a play button below each option)
Calvin Han
I know what you mean, probably (I think MacOS/iPhoneOS have a similar picture list), but unfortunately it won't be easy to code with JSF. You can use <ui:repeat> as BalusC said, but it will just show you a horizontal list instead (and I guess you want to see ~3 images and have a previous/next buttons or something like that?). Well I guess you can code it, but as I said I don't think there are already premade controls for that (I know I did something like that in Flex and it was easy, but Flex is easier in general when it comes down to coding "shiny" stuff).
Zenzen
Yeah, after spending a couple hours on my code today, I think a dataTable might be appropriate.I've been having trouble using a dataTable with f:ajax. Could you provide an example of this?-C
Calvin Han