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