I have this very strange error with h:graphicImage
This code works fine :-
<h:graphicImage value="/Common/Images/#{item.templatePicName}"/>
And this one doesn't :-
<h:graphicImage alt="${app:getCommonImagePath(item.templatePicName)}" value="${app:getCommonImagePath(item.templatePicName)}" />
It only shows alt value /Common/Images/Sunset.jpg which is perfectly fine and works in 1st case. Then why doesn't it work in 2nd case? There are no problems with my images. They are present in right directory.
here getCommonImagePath is my custom EL function, whose definition is :
package Common;
public final class AppDeployment {
private AppDeployment(){ //hide constructor
}
private static String commonImageFolderPath = "/Common/Images/";
public static String getCommonImagePath(String picName){
return commonImageFolderPath + picName;
}
}
With JSF you should use #{..} rather than ${..}.
Then check the HTML that is generated to see what the src of the generated image is pointing to.
Then check whether your custom tag is mapped properly.
Its easier to solve if you have a property in your app class that concatenates what you want.
ie:
class App {
private String commonImagePath="/Common/Images/";
//getters and setters
}
Then you would write:
<h:graphicImage alt="#{app.commonImagePath}#{item.templatePicName}" value="#{app.commonImagePath}#{item.templatePicName}" />
Related
I have a backing bean and an XHTML that is tied to this backing bean. I have a private instance variable called testerString.
Here is an excerpt of the backingbean
public class LinkDataBackingBean {
Map<String, LinkInfo> linkMap = new HashMap<String, LinkInfo>();
List<LinkInfo> list = new ArrayList<LinkInfo>();
private String testerString = "http://www.google.com";
public String getTesterString() {
return testerString;
}
public LinkDataBackingBean() throws FileNotFoundException {
System.out.println("hello");
for(int i = 0; i < 10; i++){
list.add(new LinkInfo("hi", "www.google.com"));
//linkMap = getLinkData()
}
}
As you can see, I've manually populated the variable with http://www.google.com. There comes a time in my XHTML where I would like to have someone click on a link and then it will go to the URL described by testerString.
One way I tried this was this, as a passed variable.
<f:metadata>
<f:viewParam name="id" value="#{linkDataBackingBean.testerString}" />
</f:metadata>
And then:
TEST
This did not work, in the sense that "TEST" did not appear as a hyperlink at all (whereas if I manually put in "http://www.google.com" for the value of the former statement, it DOES appear as a hyperlink and works fine).
I've also tried the following, plugging the backing bean value directly (have to screw up formatting or SO won't show):
TEST
This yielded a similar result - TEST did not appear as an underlined hyperlink kind of thing.
I considered using outputLink, but faced similar woes, I do get the Text to be a hyperlink, but it does not link to the domain I specified:
<h:outputLink id="link1" value="#{ linkDataBackingBean.testerString}">
<h:outputText value="TEST" />
</h:outputLink>
This links to the base dir of my whole project - http://localhost:8080/name-of-my-proj/faces/
When I do the same as above, but populate value with "http://www.google.com", it properly goes there. It doesn't seem to get/understand my reference to the backingbean.
What sticking me is identifying what would be required to have TEST appear as a hyperlink and, when someone clicks on it, them being directed to the URL indicated by testerString? Surely there is some JSF "plumbing" I am missing.
I have this in my class and I am trying to access it on my web page.
public String carImageURL = "/resources/images/sample_car.jpg";
This is the code I use in my web page that does not work.
<h:graphicImage value="#{carClass.carImageURL}"></h:graphicImage >
When I run the page there is no picture of the car in it.
Change the carImageURL attribute to private scope and write a getter method for it. Also write a slash at the beginning of the image path:
private String carImageURL = "/resources/images/sample_car.jpg";
public String getCarImageURL() {
return carImageURL;
}
I am trying to use JSF 2.2 new to let the user upload a photografy to his profile. Anyway I need an Ajax behavior, which I achieved with the following snippet:
<h:form enctype="multipart/form-data">
<h:inputFile value="#{usuarioController.part}">
<f:ajax listener="#{usuarioController.uploadImage}"/>
</h:inputFile>
</h:form>
But at the moment my public void uploadImage() the javax.servlet.http.Part part still null..
This is the controller:
#Named(value="usuarioController")
#SessionScoped
public class UsuarioController extends GenericPersonificacaoCrudController<Usuario>{
private static final long serialVersionUID = 3233882970467365819L;
private Part part;
public void uploadImage(){
System.out.println(part);
}
public Part getPart() {
return part;
}
public void setPart(Part part) {
this.part = part;
}
}
I am using Mojarra 2.2.6 implementation of JSF with Tomcat + Weld CDI and Primefaces 5.1 which is unrelated to the question since I am using the native fileUpload component, but I am including just to let you know I also tried using it and it doesnt work with the mode="advanced" which use ajax, what make me wonder if it is some kind of incompatibility or conflict of the libraries I am using.
You're trying to access the file using the java representation of the <h:inputFile/> component; you should not be doing this. As you have it, file should be bound to an instance of javax.servlet.http.Part, from which you can get an InputStream. The rest is quite straightforward from that point. Your code would look something like this:
public Part file;
//getter and setter
public void uploadImagem(){
long fileSize = file.getSize();
byte[] fileStorage = new byte[fileSize];
BufferedInputStream bis = new BufferedInputStream(file.getInputStream);
bis.read(fileStorage);
//do whatever you want with the array.
}
Tip: You should also know that the Part also has a convenience method write() that allows you to write the file to a specified directory, directly
This question may be more of the type "conceptual" or "I don't understand JSF".
My scenario:
I have a JSF Page (index.xhtml) where I use a p:accordionPanel (but I don't think it matters what component it is). What I want to do is to set the activeIndexes of it.
<p:accordionPanel multiple="true" activeIndex="#{myController.getActiveIndexesForSections('whatever')}">
// bla bla...
</p:accordionPanel>
And the (simplified) method in the backing bean:
public String getActiveIndexesForSections(String holderName){
String activeSections = "";
for(Section s : sectionMap.get(holderName)){
if (s.isActive())
//add to the string
}
return activeSections;
}
Now this works just fine on a normal page load.
But if I click on a p:commandButton (with ajax=false) (or anything else which "sends" data back to the server I guess) - I get the following exception:
/WEB-INF/tags/normalTextSection.xhtml #8,112 activeIndex="#{myController.getActiveIndexesForSections(name)}": Illegal Syntax for Set Operation
// bla..
Caused by: javax.el.PropertyNotWritableException: Illegal Syntax for Set Operation
After some googling / reading the error message I found that I need a setter.
First of all: I don't want a setter - do I really need one or is there a way to tell JSF I don't want this "behavior".
Second I realized that it's not that "easy" to provide a setter, because my method has a parameter (so public void setActiveIndexesForSections(String name, String activeIndexes) or public void setActiveIndexesForSections(String name)won't work).
What I came up with in the end is:
Create a (generic) "Pseudo-Property-class":
// just a dummy class since the class is recreated at every request
public class Property<T> implements Serializable {
private T val;
public Property(T val) {
this.val= val;
}
public T getVal() {
return val;
}
//no need to do anyhting
public void setVal(T val) {
}
}
Change the bean method:
public Property<String> getActiveIndexesForSections(String holderName){
String activeSections = "";
for(Section s : sectionMap.get(holderName)){
if (s.isActive())
//add to the string
}
return new Property<String>(activeSections);
}
And call it from the index.xhtml:
<p:accordionPanel multiple="true" activeIndex="#{myController.getActiveIndexesForSections('whatever').val}">
// bla bla...
</p:accordionPanel>
This works but obviously is a ugly hack/workaround.
What is the proper way to handle a situation like this? Or is what I'm doing simply completely wrong?
The setter is needed to remember the active indexes as they were when the form is submitted. Basically, you need to bind it as a value expression (with a property), not as a method expression (like an action method), nor to an unmodifiable collection (like activeIndex="#{param.tab}"). Exactly like as with input values. Technically, you're indeed doing it "simply completely wrong" ;)
The requirement is however understood. Given that you're really not interested in the changed active indexes, and thus want to reset them to defaults on every form submit, then you can bypass it by storing the result as a request attribute with help of <c:set>. This way you will fool EL to set it in the request attribute map instead of the intented bean property.
<c:set var="activeIndex" value="#{myController.getActiveIndexesForSections('whatever')}" scope="request" />
<p:accordionPanel multiple="true" activeIndex="#{activeIndex}">
<!-- bla bla... -->
</p:accordionPanel>
Under the covers, it will basically do externalContext.getRequestMap().put("activeIndex", value) as setter operation, which will obviously just work.
Update: upon inspecting the source code of AccordionPanel component, I saw another workaround given the fact that the activeIndex won't be set when the rendered attribute evaluates false. So just alter the rendered attribute to behave exactly that: evaluate false during update model values phase (the 4th phase).
<p:accordionPanel multiple="true"
activeIndex="#{myController.getActiveIndexesForSections('whatever')}"
rendered="#{facesContext.currentPhaseId.ordinal ne 4}">
<!-- bla bla... -->
</p:accordionPanel>
I have an entity which i display and modify in an xhtml page. This entity has a getter returned a joined entity using a getter with a parameter (the language):
public JoinedEntity getJoinedEntity(Locale locale){
for(JoinedEntity je: joinedEntities)
if(je.getLocale().equals(locale)
return je;
}
my xhtml cointains the following code:
<h:inputText value="#{myBean.myEntity.getJoinedEntity(localeBean.locale).mytext}"/>
There is no problem if i only display this entity but when i try to save the modified JoinedEntity (using TextInputs), i receive an EL exception telling me that there is no getJoinedEntity argument in my Entity.
Is it a possibility to create such a setter:
public void setJoinedEntity(Locale locale, JoinedEntity je){
...
}
Is there another way to solve that?
I found the solution to my problem. I deleted my getter and used a map as follow:
<h:inputText value="#{myBean.joinedEntities[localeBean.locale].myText}">
public Map<Locale,JoinedEntity> getJoinedEntities(){
return joinedEntities;
}
public void setJoinedEntities(Map<Locale,JoinedEntity> joinedEntities){
this.joinedEntities = joinedEntities;
}
Updating the map works then fine.