Si simplemente quisiéramos navegar a un enlace interno sin ejecutar nada en el servidor podríamos hacerlo con un outputLink:
<h:outputLink value="pagina.jsf#ancla" ><h:outputText value="Ir a la página"/> </h:outputLink>
Sin embargo, puede que lo que necesitemos es ejecutar un método en el servidor y luego navegar hacia un ancla. Esto podemos hacerlo con un método actionListener al que enviaremos el nombre del ancla y que se encargará de redireccionar al usuario al ancla especificada tras hacer su trabajo.
En primer lugar veamos el código JSF que incluiría la llamada al actionListener:
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <f:view> <html lang='es'> <head> <title>Mi página</title> <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /> </head> <body> <div id='contenedor'> <h:form> <h:commandLink actionListener="#{bean.navegaEnlace}"> <h:outputText value="Ver resultados" /> <f:param name="ancla" value="resultado" /> </h:commandLink> </h:form> </div> <p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p> <div id='capaResultados'> <h1><a name='resultado'>Resultados</a></h1> <h:dataTable id="tablaResultados" value="#{bean.resultados}" var="resultado" style="width: 100%"> <h:column><h:outputText value="#{resultado}" /></h:column> </h:dataTable> </div> <p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p> </body> </html> </f:view>
Se han añadido los saltos de línea para comprobar mejor cómo se realiza la navegación al enlace interno. A continuación vemos el código de nuestro bean:
package org.ffbeltran.prueba; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.faces.context.FacesContext; import javax.faces.event.ActionEvent; public class BeanNavegacion { private List<String> resultados; public void navegaEnlace(ActionEvent actionEvent) { resultados = new ArrayList<String>(); for(int i=1;i<11;i ) resultados.add("Resultado " i); // Para recuperar el parámetro enviado por el JSP String ancla = FacesContext.getCurrentInstance().getExternalContext() .getRequestParameterMap().get("ancla"); try { FacesContext.getCurrentInstance().getExternalContext() .redirect("navegacion.jsf#"+ancla); } catch (IOException e) { e.printStackTrace(); } } public List<String> getResultados() { return resultados; } }
Como puede observarse, el método navegaEnlace del bean inicializa el array de resultados, recupera el valor del ancla y redirecciona a la misma página pero pasándole el enlace interno.
Este bean debería estar disponible para el contexto de JSF, por ejemplo mediante el siguiente código en el fichero faces-config.xml:
<?xml version="1.0"?> <faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"> <!-- managed beans of the simple hello world app --> <managed-bean> <managed-bean-name>bean</managed-bean-name> <managed-bean-class>org.ffbeltran.prueba.BeanNavegacion</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> </faces-config>
Esta es la única solución que he encontrado para hacer una navegación interna a un ancla (o anchor) tras ejecutar un método del servidor. El problema es que la redirección se salta el ciclo de JSF por lo que no tenemos las reglas de navegación y algunas cosas pueden no funcionar igual. Si conoces una solución mejor, por favor, coméntalo en el post.
0 comentarios:
Publicar un comentario