0

I have a page where a SelectOneMenu is rendered whether there is some info on DB or not. My form looks like this:

...
<h:form id="wrapperUpload" enctype="multipart/form-data" >
<h:outputLabel for="option" value="Tipo de carga: "
                            rendered="#{uploadFile.check(userVerifier.dependencia)}" />
<h:selectOneMenu id="option"
                 value="#{uploadFile.optionSelected}"
                 rendered="#{uploadFile.check(userVerifier.dependencia)}"  >
    <f:selectItems value="#{uploadFile.options}" />
</h:selectOneMenu>
<h:outputLabel for="upfile" value="Archivo: " />
<t:inputFileUpload id="upfile" required="true" 
                   value="#{uploadFile.upFile}" />
<h:commandButton value="Validar #{userVerifier.dependencia}"
                 action="#{uploadFile.upload}"
                 onclick="return confirmation()" >
    <f:param name="dependencia" value="#{userVerifier.dependencia}" />
</h:commandButton>
</h:form>
...

And my Beans is

private UploadedFile upFile;
private boolean showOptions = false;
private final String[] options = {
    "Seleccione una opción.",
    "Cargar toda la información.",
    "Cargar solo información errónea."
};
private String optionSelected;
private Database db = new Database();

public UploadedFile getUpFile() {
    return upFile;
}

public void setUpFile(UploadedFile upFile) {
    this.upFile = upFile;
}

public String[] getOptions() {
    return options;
}

public void setOptionSelected(String optionSelected) {
    this.optionSelected = optionSelected;
}

public String getOptionSelected() {
    return optionSelected;
}

public boolean check(String dependencia) {
    String hasInfo;
    hasInfo = db.checkForInfo(dependencia);
    if (hasInfo.equals("T")) {
        showOptions = true;
    } else {
        showOptions = false;
    }
    return showOptions;
}

public String upload() {
    byte[] buffer = null;
    int count = 0;
    File serverFile = null;
    InputStream input = null;
    OutputStream output = null;

    Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
    String dependencia = params.get("dependencia");
    String extension = FilenameUtils.getExtension(upFile.getName());

    System.out.println("__depend:   " + dependencia);
    System.out.println("__option:   " + optionSelected);  //null
...
...

Finally when I hit the button the value of SelectOneMenu (or selectedOption in my bean) is always null... How to fix this? Am I missing something?

Forgot to mention that, if I delete the render part everything works fine...

BRabbit27
  • 6,333
  • 17
  • 90
  • 161
  • This is not real code. You don't have an `isCheck()` method, nor are you using `rendered="#{uploadFile.check('somestring')}"`. It would already throw an EL exception while displaying the form. Please show the real code. – BalusC Nov 03 '11 at 17:48
  • Sorry to tell you but yes it is real code, I omitted the rest of the code but basically that's what I have... But I'll post all the code so maybe you can help. – BRabbit27 Nov 03 '11 at 18:00
  • The `rendered="#{uploadFile.check}"` expects a `public boolean isCheck()` method, not a `public boolean check(String dependencies)` method. It should have thrown an EL exception. What container are you using? – BalusC Nov 03 '11 at 18:04
  • There it is, hope that helps better. Sorry if I post incomplete code. Oh I see what you mean... I'll try to correct that... but it doesn't send any EL exception, but to be in good practice I'll change it. – BRabbit27 Nov 03 '11 at 18:17
  • Now since you changed it to `rendered="#{uploadFile.check(userVerifier.dependencia)}"`, it looks better. Initially you had `rendered="#{uploadFile.check}"` which is invalid in combination with the given method. – BalusC Nov 03 '11 at 18:36

1 Answers1

0

Forgot to mention that, if I delete the render part everything works fine

That can only mean that the bean is request scoped and that the rendered attribute depends on a request based variable which was present in initial request while displaying the form, but is absent in subsequent request while processing the form submit.

Putting the bean in the view scope or ensuring that the request based variable is preserved in subsequent request should fix your problem.

As you haven't posted real code, it's not possible to post code of how to fix it properly.

See also:


Update: as per your update and the comments, you should make UserVerifier a managed property of the UploadFile bean and do the preinitialization in (post)constructor. Something like:

@ManagedBean
@ViewScoped
public class UploadFile {

    @ManagedProperty("#{userVerifier}")
    private UserVerifier userVerifier; // +setter

    private boolean showOptions;

    @PostConstruct
    public void init() {
        showOptions = "T".equals(db.checkForInfo(userVerifier.getDependencia()));
    }

    public boolean isShowOptions() {
        return showOptions;
    }

    // ...
}

with

rendered="#{uploadFile.showOptions}"

and get rid of <f:param>.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • How can I preserve that variable? I put it on View Scope but that generated a new problem, the `` and `` tags aren't keeping the value anymore. I put it on a `` to see if they have a value and they do. – BRabbit27 Nov 04 '11 at 14:58
  • Initialize the property on bean's (post)construction and just don't use f:param. The view scoped bean lives as long as you're interacting with the same view. The property will just have the same value on the subsequent postbacks. You don't need to pass it forth and back through HTTP requests. – BalusC Nov 04 '11 at 17:39
  • I don't get it... I'm a newbie in JSF so if you could explain me with detail. Should I initialize the userVerifier bean? The idea is: after login (after checking that user pass are right) in this page I will check on the DB to see if the user has data already, if it has, render the *selectOneMenu*. Then after selecting the file and hitting the button it should check if the user selected a valid option from the *selectOneMenu* and perform the uploading. – BRabbit27 Nov 04 '11 at 21:08
  • Anyone there? Can you explain me in detail? – BRabbit27 Nov 07 '11 at 16:07
  • THanks ! I'll check it right away and post the results ! BTW where can I learn all that? Is that some kind of advance JSF stuff? – BRabbit27 Nov 07 '11 at 18:25
  • I'm back... I'll try it out and the next exception was thrown `javax.servlet.ServletException: No se puede crear el bean administrado uploadFile. Se han encontrado los problemas siguientes: - El ámbito del objeto al que hace referencia la expresión #{userVerifier}, request, es más corto que el ámbito de view del bean administrado de referencia (uploadFile)` the **UserVerifier** bean has RequestScoped but for what the exception says, I think it should be also ViewScoped? – BRabbit27 Nov 08 '11 at 00:13
  • I understood that `UserVerifier` represents the currently logged-in/active user and I'd expect it to be in the session scope. What exactly does that bean represent and why exactly is it in the request scope? – BalusC Nov 08 '11 at 00:15
  • Well I put it on SessionScoped and it works fine this part, but after I upload the file, I have a third (and last) page where I wanted to display the name of the file uploaded. Since the **UploadFile** is now ViewScoped (correct me if I'm wrong) when I go to this next page the bean is lost. What I have in mind is do something similar as what we did with **UserVerifier** is that a good idea? BTW, is there a "best" way to pass info from one page to another in JSF? as in my project, page1:getsUser -> page2:uses that User to check on DB and uploadFile -> page3:uses the uploadFile name . THANKS ! – BRabbit27 Nov 08 '11 at 00:36
  • A view scoped bean lives as long as you're interacting with the **same** view. I have no idea why you want to have this bean in the next page, is it to display the results? Why don't you just do it in the same view? As to the bean scopes and all other things about communication in JSF, you may find this articule helpful: http://balusc.blogspot.com/2011/09/communication-in-jsf-20.html – BalusC Nov 08 '11 at 00:40
  • Yes, after uploading the file, in next page there will be just a message like "We've received the file: Blabla.txt" This is what the client wants, but if your advise and what best practices tell is that it would be better to have it on the same page (view) I'll change it. I'll read the article and keep going into this interesting (and somewhat rare for me haha) technology. Thanks again. – BRabbit27 Nov 08 '11 at 00:53