martes, 18 de agosto de 2009

Volver a la página correcta (y a la ordenación, también)

Este es un tema recurrente. La situación típica es la siguiente:

Nos encontramos en la típica vista index que muestra un listado paginado de registros (posts, usuarios, lo que sea). Supongamos que estamos en la página 17 de 25, con los registros ordenados por algún criterio y que pulsamos el enlace para ver o editar alguno.

Al volver de la edición, nos llevamos el gran palo: otra vez en la primera página y ordenados por id.

¿Cómo hacemos para volver a la misma página y a ser posible a las mismas condiciones de ordenación?

Hay varias técnicas, la última que estoy probando la encontré en este enlace. La explico:

Para obtener la URL a la que queremos redirigir recurriremos al método referer() del controlador, que nos devuelve la URL de la que venimos. Este método nos conserva los parámetros del URL relacionados con la paginación.

Si estábamos en /app/posts/index/page:17 y consultamos referer() en admin_edit(), por ejemplo, nos devolverá ese valor.

Sin embargo, recuerda que las acciones como admin_edit son llamadas dos veces consecutivas. La primera es explícita, cuando hacemos clic en el enlace que nos lleva a ella. En esa situación, referer() nos devolverá la URL de la acción de procedencia. Por tanto, esa es la URL que deberíamos usar para redirigir después de guardar los cambios.

Pero la segunda vez es implícita, cuando pulsamos el botón de envío del formulario, volvemos a admin_edit, con lo cual referer() tendrá la propia URL de la acción. Es en esta pasada cuando se realiza habitualmente la redirección a la acción de index.

Dicho de otro modo: la primera vez que llegamos a la acción editora tenemos que obtener referer() y guardarlo de algún modo para recuperarlo en la segunda pasada.

Una forma es pasar el valor de referer() a la vista en la primera pasada.

$this->set('returnTo', $this->referer());


Así podremos recuperarlo para varios usos:

* Para crear enlaces de cancelación o regreso.

link(__('Return to Admin Index', true), $returnTo);?>

* Para añadir un campo oculto al formulario en el que anotar ese valor y poder retomarlo en la segunda pasada.

input('App.returnTo', array('type' => 'hidden', 'value' => $returnTo)); ?>


Esta última opción, nos permite recuperar la URL correcta, con todos los parámetros de paginación que tuviese, y redirigir la acción correctamente. El valor estará en el array $this->data, bajo las claves con las que hayas puesto el nombre del campo en el formulario.

if (isset($this->data['App']['returnTo'])) {
$this->redirect($this->data['App']['returnTo']);
}

Otro caso

Otra situación es la que ocurre en acciones que redirigen al index sin mostrar ninguna vista, como podría ser un enlace para borrar registros.

En ese caso, podemos redirigir al referer().

$this->redirect($this->referer()

Siempre puede ser conveniente tener un plan B, es decir, en caso de que referer() nos devuelva un valor no válido, tratar de redirigir a la acción básica, aunque perdamos la información de paginado.

No hay comentarios: