0

I'm trying to create a sing-in form with an Username(displayed), a Role(hidden) and its Password(hidden) using JSF.

First, the user types his/her Username then clicks on a ''Validate'' button. If the Username exists then the page has to display the Role's<h:SelectOneMenu> with the Username roles, the Password input and also hide the ''Validate'' button.

The Role and Password inputs are hidden by default via CSS:

<body>
  <div class="container">
    <h:form styleClass="form-signin">
      <h2 class="form-signin-heading">SISE<br><small>Inicio de Sesión</small></h2>
      <label for="inputEmail" class="sr-only">Nombre de Usuario</label>
      <input type="text" id="inputEmail" class="form-control" placeholder="Nombre de usuario" required autofocus>
      <br>
      <h:commandButton styleClass="btn btn-lg btn-primary btn-block" value="Validar" action="#{beanInicioSesion.buscarUsuarioDB}" />
      <h:selectOneMenu styleClass="form-control hide">
        <f:selectItem itemLabel="Something" itemValue="Something"></f:selectItem>
      </h:selectOneMenu>
      <label for="inputPassword" class="sr-only">Contraseña</label>
      <input type="password" id="inputPassword" class="form-control hide" placeholder="Contraseña" required>
      <br>
      <h:commandButton styleClass="btn btn-lg btn-primary btn-block hide" value="Iniciar sesión" />
    </h:form>
  </div>
</body>

Here is what I have in my managed user sing-in bean:

public String buscarUsuarioDB() throws SISE_Exceptions, SQLException {
  int usuarioValidado = 0; //validatedUser
  UsuarioDB usrDB = new UsuarioDB();

  try {
    usuarioValidado = usrDB.consultarUsuario(this.getNombreUsuario());
    if (usuarioValidado == 0) {
      setMensaje("Usuario Invalido");
    } else {
      setMensaje("Usuario Valido");
      //Valid user, then show/display the <h:selectOneMenu> and password input.
    }

  } catch (Exception e) {
    // TODO: Add catch code
    e.printStackTrace();
  }
  return "";

}

So the question is, how can I select HTML elements from my buscarUsuarioDB() method in order to set them displayed/hidden within the JSP?

2 Answers2

1

First of all you need to decide on whether you are going to use HTML5 with JSF or JSF full blown (i will suggest you use the latter).

On addressing your issue, you are using plain HTML input tags which JSF does not know about during its life cycle.

   .....
       <!-- NO   <label for="inputEmail" class="sr-only">Nombre de Usuario</label>-->           
       <!--YES--><h:outputLabel for="inputEmail" class="sr-only" value="Nombre de Usario"/>       
       <!--NO    <input type="text" id="inputEmail" class="form-control" placeholder="Nombre de usuario" required autofocus>-->
       <!--YES--><h:inputText id="inputEmail" class="form-control" required="true" value="#{backingBean.value}"/>
   .....

Lastly to answer your main question, to add such functionality you should enclose f:ajax in you h:commandButton component this way

<h:commandButton id="submit" value="Submit">
        <f:ajax event="click" render="selectOneMenu_id" listener="#{backingbean.doSomething}"/>
</h:commandButton>

and your selectOneMenu:

<h:selectOneMenu styleClass="form-control hide" id="selectOneMenu_id">
        <f:selectItem itemLabel="Something" itemValue="Something"/>
</h:selectOneMenu>

where your f:ajax listner points to a method that accepts an AjaxBehaviorEvent type as an argument.

The key here is the render attribute of f:ajax, as it points to an id or a space separated list of component ids that should be updated in the view when the Ajax call retruns.

Also note that JSF has a way of providing ids for components so be sure to specify yours or give this a read on how to find components by id .

Now providing a guide code sample:

your facelets :

      <h:inputLabel for="inputEmail" class="sr-only" value="Nombre de Usuario"/>
      <h:inputText  id="inputEmail" class="form-control" value="{renderBean.value}" reqired="true"/>

      <h:commandButton id="submit" value="Submit">
            <!--f:ajax does the magic here and the two attributes that tells JSF what to do during and after the Ajax call to the server is made-->
            <f:ajax event="click" render="selectOneMenu_id" listener="#{renderBean.doSomething}"/>
      </h:commandButton>


      <h:selectOneMenu id="selectOneMenu_id" styleClass="form-control hide" rendered="#{renderBean.rendered}">
        <f:selectItem itemLabel="Something" itemValue="Something"/>
      </h:selectOneMenu>

and your backing bean

@ManagedBean
@ViewScoped 
public class RenderBean{

   private boolean rendered = false;



    //the backing bean method to handle the Ajax call
    public void doSomething(AjaxBehaviorEvent event){
         //do a lot more with the event 
           rendered = true;
         }

    public boolean isRendered() {
        return rendered;
         }

    public void setRendered(boolean rendered) {
        this.rendered = rendered;
         }
}

Lastly i will point you to a rather good explanatory answer on how to use f:ajax. I hope this helped.

basamoahjnr
  • 145
  • 11
0

You need to use Ajax callback on form focus and blur. Use jquery. Using callback you can change class of the element to free or used. You need to use not template renderer, but instead json response wrapper.