0

I am trying simple example to enable and disable button based upon submit of form. If some one can also point me to concept of jsf:id as I am mixing plain html5 with jsf.

Below are relevant code:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
     xmlns:jsf="http://java.sun.com/jsf" 
     xmlns:f="http://java.sun.com/jsf/core">
    <head jsf:id="head">
        <title>Putting it all together </title>
        <!-- script jsf:target="body" jsf:name="js.js"/>
        <link jsf:name="css.css" rel="stylesheet" type="text/css" /-->
    </head>
    <body jsf:id="body">
        <form jsf:id="form" jsf:prependId="false">
            <label jsf:for="name">Name </label>
            <input jsf:id="name" type="text" jsf:value="#{complex.name}">
                <f:ajax execute="@this" render="progress"/>
            </input>
            <label jsf:for="tel">Tel </label>
            <input jsf:id="tel" type="tel" jsf:value="#{complex.tel}">
                <f:ajax execute="@this" render="progress"/>
            </input>

            <label jsf:for="email">Email </label>
            <input jsf:id="email" type="email" jsf:value="#{complex.email}">
                <f:ajax execute="@this" render="progress"/>
            </input>

            <label for="progress">Progress </label>
            <progress jsf:id="progress" max="3">#{complex.progress} of 3 </progress>


            <input jsf:id="submit" type="submit" value="submit">
                <f:ajax execute="@this" render="login" event="click" listener="#{complex.process}" />
            </input>

            <!-- label jsf:id="status"></label-->
            <button jsf:id="login" disabled="#{complex.status}">Login</button>

        </form>
    </body>
</html>

The managed bean is:

package mypackage.bean;
import java.io.Serializable;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.AjaxBehaviorEvent;

@ManagedBean
@SessionScoped
public class Complex implements Serializable {
    public Complex() {}

    private String name;
    private String tel;
    private String email;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getTel() {
        return tel;
    }
    public void setTel(String tel) {
        this.tel = tel;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    private boolean status;

    public void process(AjaxBehaviorEvent event) {
        status = !status;
    }


    public boolean isStatus() {
        return status;
    }

    public boolean getStatus() {
        return status;
    }

    public void setStatus(boolean status) {
        this.status = status;
    }

    public String getProgress() {
        int progress = 0;
        if(name != null) {
            progress++;
        }
        if(tel != null) {
            progress++;
        }
        if(email != null) {
            progress++;
        }
        return progress + "";
    }


}

Here is error printed to web page:

HTTP Status 500 - java.lang.Boolean cannot be cast to java.lang.String

type Exception report

message java.lang.Boolean cannot be cast to java.lang.String

description The server encountered an internal error that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: java.lang.Boolean cannot be cast to java.lang.String
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)

root cause

java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.String
    com.sun.faces.renderkit.html_basic.HtmlResponseWriter.getAttributeValue(HtmlResponseWriter.java:1210)
    com.sun.faces.renderkit.html_basic.HtmlResponseWriter.flushAttributes(HtmlResponseWriter.java:1170)
    com.sun.faces.renderkit.html_basic.HtmlResponseWriter.closeStartIfNecessary(HtmlResponseWriter.java:1112)
    com.sun.faces.renderkit.html_basic.HtmlResponseWriter.writeText(HtmlResponseWriter.java:935)
    com.sun.faces.facelets.compiler.LiteralTextInstruction.write(LiteralTextInstruction.java:76)
    com.sun.faces.facelets.compiler.UIInstructions.encodeBegin(UIInstructions.java:82)
    com.sun.faces.facelets.compiler.UILeaf.encodeAll(UILeaf.java:183)
    javax.faces.render.Renderer.encodeChildren(Renderer.java:176)
    javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:900)
    javax.faces.component.UIComponent.encodeAll(UIComponent.java:1847)
    javax.faces.render.Renderer.encodeChildren(Renderer.java:176)
    javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:900)
    javax.faces.component.UIComponent.encodeAll(UIComponent.java:1847)
    javax.faces.component.UIComponent.encodeAll(UIComponent.java:1850)
    javax.faces.component.UIComponent.encodeAll(UIComponent.java:1850)
    com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:443)
    com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
    com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
    com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:202)
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)

note The full stack trace of the root cause is available in the Apache Tomcat/7.0.35 logs.
Apache Tomcat/7.0.35
Miten
  • 356
  • 7
  • 23
  • I can't pin it down since I don't work with JSF, but it has to do with ``. Something about `complex.status` being a boolean is throwing it off. – Makoto Mar 04 '13 at 05:57
  • May you should use View Scoped – Jaider Mar 23 '13 at 04:38
  • @Jaider The response has valid attribute value but still its not reflecting on UI. I guess using command button will more likely fix it. – Miten Mar 24 '13 at 13:59

1 Answers1

5

The critical part of your code is

<button jsf:id="login" disabled="#{complex.status}">Login</button>

and then this exception

java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.String

Now It mean for <button> tag, the value of disabled attribute is not boolean but a String.
So the value of this attribute is disabled="disabled".
Please see this question as well for handling the disabled attribute for HTML5
You need to set the String value from your managed bean and declare status property as a String rather than boolean.

Community
  • 1
  • 1
Freak
  • 6,786
  • 5
  • 36
  • 54
  • I changed to String the status attribute and now error is gone but then how to enable the button. Basically on submit I try to process toggle behavior to learn how to control it. If I return empty string login button still stays disabled. - Miten. – Miten Mar 04 '13 at 06:45
  • for this purpose , you need to post a new thread.Please accept this answer if it helped you out and start a new thread for your next problem.By the way it should not be continue its disabled behaviour when you return empty String.Keep in mind, to enable, don't return a null String but return a initialized String by empty String. like the value of status should be `status=""` – Freak Mar 04 '13 at 06:47
  • public void process(AjaxBehaviorEvent event) { System.out.println("listener process called"); status = (status == "disabled" ? "" : "disabled"); } so I do return status = ""; as you mentioned but button still is disabled. – Miten Mar 04 '13 at 06:57
  • are you sure that your Ajax method named `process` is being invoked? – Freak Mar 04 '13 at 07:09
  • INFO: Unable to discern ProjectStage for value ${webapp.projectStage}. START PHASE RESTORE_VIEW 1 END PHASE RESTORE_VIEW 1 START PHASE RENDER_RESPONSE 6 END PHASE RENDER_RESPONSE 6 START PHASE RESTORE_VIEW 1 END PHASE RESTORE_VIEW 1 START PHASE APPLY_REQUEST_VALUES 2 END PHASE APPLY_REQUEST_VALUES 2 START PHASE PROCESS_VALIDATIONS 3 END PHASE PROCESS_VALIDATIONS 3 START PHASE UPDATE_MODEL_VALUES 4 END PHASE UPDATE_MODEL_VALUES 4 START PHASE INVOKE_APPLICATION 5 `listener process called` END PHASE INVOKE_APPLICATION 5 START PHASE RENDER_RESPONSE 6 END PHASE RENDER_RESPONSE 6 – Miten Mar 04 '13 at 07:19
  • start a new thread with your this issue and post fresh code there.Before doing this , first clean your poject and restart your server and IDE – Freak Mar 04 '13 at 07:27
  • It's weird that we can use HTML's attributes with CDI's properties like that... I think you should use preappend `jsf` tag, like: `jsf:disabled=...` – Jaider Mar 25 '13 at 14:36