Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@previous The subexpression @previous doesn't exist, or it can't be resolved #944

Closed
MohaTikiTaka opened this issue May 25, 2018 · 8 comments
Assignees
Milestone

Comments

@MohaTikiTaka
Copy link

Hi BootsFaces team !

I recently discovered the existence of BootsFaces. I used PrimeFaces alone before. I combine both now. Thanks again.

I have a small error when I try to pass values (I think it comes from there) since I use BootsFaces.

Here is the error I have:

"Invalid search expression: @previous The subexpression @previous doesn't exist, or it can't be resolved. net.bootsfaces.component.message.Message j_idt7:j_idt18:j_idt25 Additional information: Invalid search expression - there's no predecessor to the @previous"

Here is my code:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
      xmlns:p="http://primefaces.org/ui"
      xmlns:b="http://bootsfaces.net/ui"
      template="WEB-INF/pageTemplate.xhtml">
    
    <ui:define name="title">
        <h:outputText value="Se connecter"/>
    </ui:define>
    
    <ui:define name="content">
        <h:form>
        <b:container fluid="true">
          <b:row>
            <b:column medium-screen="2">
              <h:outputText value="Username:"/>
            </b:column>
            <b:column medium-screen="4">
              <b:inputText id="email" required="true" value="#{loginManager.email}" />
            </b:column>
            <b:column medium-screen="6">
              <b:message/>
            </b:column>
          </b:row>
          <b:row>
            <b:column medium-screen="2">
              <h:outputText value="Password:" />
            </b:column>
            <b:column medium-screen="4">
              <b:inputSecret id="password" required="true" value="#{loginManager.password}" />
            </b:column>
            <b:column medium-screen="6">
              <b:message />
            </b:column>
          </b:row>
          <b:row>
            <b:column span="1" offset="2">
              <b:commandButton value="Connexion" update="login" action="#{loginManager.login()}" look="primary" style="width:100%" />
            </b:column>
          </b:row>
        </b:container>
        </h:form>
    </ui:define>
</ui:composition>

Thank you for your future help!

Regards.

@chongma
Copy link
Collaborator

chongma commented May 25, 2018

try putting h:form inside the b:container

@chongma
Copy link
Collaborator

chongma commented May 25, 2018

read the "basic usage" part at https://showcase.bootsfaces.net/layout/basic.jsf. also it might help if you can show contents of pageTemplate.xhtml and LoginManager bean

@MohaTikiTaka
Copy link
Author

MohaTikiTaka commented May 25, 2018

@chongma Hi
Works fine now ! Thank you 💯

Here is my pageTemplate.xhtml :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
      xmlns:p="http://primefaces.org/ui"
      xmlns:b="http://bootsfaces.net/ui">
    <h:head>
        <title><ui:insert name="title" /></title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    </h:head>
  
    <h:body>
        <h:form>
            <b:navBar brand="SupFile" brandHref="#" fluid="true">
             <b:navbarLinks>
               <b:navLink outcome="/index" value="Accueil"></b:navLink>
             </b:navbarLinks>
             <!-- Following line is needed for TBS 3.0.1 (panel content overflow issue) -->
           <b:navbarLinks pull="right"><b:navLink value="    " href="#"></b:navLink></b:navbarLinks>
             <b:navbarLinks pull="right" styleClass="hidden-xs">            
               <c:if test="#{loginManager.isUserLoggedIn()}">
                   <b:dropMenu value="Dropdown">               
                   <b:navLink value="Mon stockage" outcome="/user_space/home_page.xhtml"></b:navLink>
                   <b:navLink value="Mon compte" outcome="/user_space/myAccount.xhtml"></b:navLink>
                   <b:navLink action="#{loginManager.logout()}" value="Se déconnecter"/>
                   </b:dropMenu>
               </c:if>
               
               <c:if test="#{!loginManager.isUserLoggedIn()}">
                   <b:navLink value="S'enregistrer" outcome="/register"></b:navLink>
                   <b:navLink value="Se connecter" outcome="/login"></b:navLink>
               </c:if>
             </b:navbarLinks>
           </b:navBar>
        <main>
            <ui:insert name="content" />
        </main>
        
        <footer>
            Pied de page
        </footer>
        </h:form>
    </h:body>
</html>

And here my LoginManager :

package Beans;

import CRUD.UtilisateurFacadeLocal;
import Entities.Utilisateur;
import Util.SessionManager;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class LoginManager {
    
    
    @EJB
    UtilisateurFacadeLocal utilisateur;
    
    private Utilisateur loggedInUser;
    
    private String email;
    private String password;

    
/******************************************************************************/
    
    
    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
    
    public boolean isUserLoggedIn() {
        return SessionManager.isUserLoggedIn();
    }

    public Utilisateur getLoggedInUser() {
        //System.out.println(loggedInUser.getUsername());
        //System.out.println(loggedInUser.getFolder());
        return loggedInUser;
    }
    
    
    
    
/******************************************************************************/
    
    
    
    public String login(){
        
        try{
            loggedInUser = utilisateur.findByEmailAndPW(email, password);            
            if(!loggedInUser.equals(null)){//remplacer par try catch
                System.out.println(">>>>>>>>>>>>> userExist");
                SessionManager.getSession().setAttribute(SessionManager.ATTRIBUTE_USER, loggedInUser);
                return "/user_space/home_page?faces-redirect=true"; //home page
            }
        }catch(NullPointerException e){
            System.out.println("couple username password inconnu");
        }
        
        
        return "/login?faces-redirect=true"; //register_login
    }
    
    public String logout(){
        SessionManager.getSession().invalidate();
        return "/index?faces-redirect=true";
    }
    
    public String updateUser(){
        
        System.out.println("[" + password.length() + "]");
        
        if(password.length() >= 4){
            loggedInUser.setPassword(password);
        }
        
        utilisateur.edit(loggedInUser);
        
        return "/user_space/myAccount?faces-redirect=true";
    }
    

    
}

Thank you for your help.
Regards.

@chongma
Copy link
Collaborator

chongma commented May 25, 2018

i am glad it is working now. thank you for the extra info. out of interest which container are you using? tomcat, wildfly etc? you should consider changing to CDI instead of EJB if it is available

@MohaTikiTaka
Copy link
Author

Im using GlassFish. Why CDI instead of EJB ?

@ggam
Copy link
Collaborator

ggam commented May 25, 2018

Im using GlassFish. Why CDI instead of EJB ?

I think he refers to the use of @Inject instead of @EJB. Both annotations do the same, with the difference that @Inject works on every bean while @EJB only works for EJBs. EJBs are being left behind now with most of their functionality being moved to CDI to provide a more unified component model. At some point in time I expect EJBs to be deprecated.

But aside of that, what you should try to avoid is @ManagedBean. That's from and old JSF specific component model (created way before CDI) and it's already deprecated on JSF 2.3. In your case, @ManagedBean should be replaced with @Named, and javax.faces.bean.SessionScoped with javax.enterprise.context.SessionScoped. They work the basically the same but again, with CDI you may inject any bean, while the JSF managed bean facility is limited to specific JSF artifacts.

@stephanrauh
Copy link
Collaborator

Also see #256.

stephanrauh added a commit that referenced this issue May 29, 2018
…if the message and the input field is in a b:column
@stephanrauh
Copy link
Collaborator

stephanrauh commented May 29, 2018

@MohaTikiTaka I've got no idea how and why the hints of @chongma helped you to solve the bug...

I've improved the confusing error message and implemented the behavior you (and I) are intuitively expecting. <b:message> now finds it's input field even if both hide in a <b:column>.

I've uploaded a developer snapshot of BootsFaces to Maven Central. See #369 how to get it. Please test it and report back.

Thanks in advance,
Stephan

@stephanrauh stephanrauh self-assigned this May 29, 2018
@stephanrauh stephanrauh added this to the v1.5.0 milestone May 29, 2018
@stephanrauh stephanrauh modified the milestones: v1.5.0, v1.3.0 Oct 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants