La web 2.0:
Retos y tecnologías para la Internet de nueva generación
Taller: "Programa una aplicación web 2.0 Ajax"
Parte 4. Modificando nuestro blog
Aplicación del taller.
1. Parte 1. Introducción
2. Enfrentándonos a Ajax sin ayudas
-
El objeto XmlHttpRequest
-
Controlarlo todo desde Javascript
-
Ejemplo de uso: autocompletar
3. Parte 2: Primeros pasos con Prototype
-
Qué es prototype
-
Algunos aspectos básicos
-
Despreocuparnos de la comunicación asíncrona: Ajax.Updater
-
Ejemplo de uso: autocompletar con prototype
4. Parte 3: Primeros pasos con Script.aculo.us
-
Qué es script.aculo.us
-
Posibilidades que ofrece
-
Ejemplo de uso: tienda de libros
5. Parte 4. Modificando nuestro blog
- Borrado de comentarios arrastrando con script.aculo.us
- Ordenación de comentarios
6. Parte 5. Modificando nuestro blog (II)
-
Prototype en Ruby on Rails
-
Mostrar un formulario sobre el listado de categorías
-
Actualizar el listado de posts desde el formulario
7. Parte 6. La guinda final
-
Efectos de animación con Script.aculo.us
-
Formularios animados
-
Menús animados
5. Parte 4. Modificando nuestro blog
Vamos a utilizar las librerías de Prototype y script.aculo.us desde nuestro Blog hecho en Ruby on Rails. Para ello debemos cargar las librerías javascript en la cabecera de las páginas. Antes de nada, editamos la página
/app/views/layouts/_cabecera.html.erb y añadimos la línea:
<%= stylesheet_link_tag 'style_blue' %> <%= javascript_include_tag :defaults %> Esta línea se encarga de cargar todas las librerías javascript que incorpora por defecto RoR.
Borrado de comentarios arrastrando con script.aculo.us
Vamos a aplicar lo que hemos visto en la parte anterior sobre nuestro blog. En primer lugar, vamos a permitir borrar comentarios mediante la técnica de drag & drop. Para ello, vamos a cambiar la estructura HTML en que se muestran los comentarios (página
/app/views/posts/_post.html.erb). Añadimos en el listado de comentarios el texto que tenemos en negrita:
<% unless @post.comentarios.empty? %> <h3 class="comentario">Comentarios</h3> <div id="listacoments">
<% @post.comentarios.each do |comentario| %> <div id="listacoment_<%= h comentario.id%>" class="producto">
<h4 class="comentario"><%= h comentario.autor %> </h4> <p class="comentario"><%= h comentario.contenido %></p> </div>
<% end %> </div>
<% end %>Lo que hemos hecho ha sido encerrar cada comentario en un
div, y todos los comentarios en otro
div general con un id. Ahora, añadimos el icono de la papelera (que ya utilizamos en el apartado anterior), debajo de la lista de comentarios
<% unless @post.comentarios.empty? %> <h3 class="comentario">Comentarios</h3>
<div id="listacoments">
<% @post.comentarios.each do |comentario| %>
<div id="listacoment_<%= h comentario.id%>" class="producto">
<h4 class="comentario"><%= h comentario.autor %> </h4> <p class="comentario"><%= h comentario.contenido %></p>
</div>
<% end %>
</div>
<% end %>
<p id="papelera">
<img src="/images/trash.png" alt="Papelera" width="50" height="50" />
</p>
<div id="result_borrado">
</div>
Y después añadimos al final del código un bloque script que gestione el arrastre de comentarios a la papelera:
<% if modo_listado == 'false' %>
<script type="text/javascript"> document.observe('dom:loaded', function() { $$('.producto').each(function(comentario) { new Draggable(comentario, {revert:true}); }); Droppables.add('papelera', { containment: 'listacoments', onDrop:function(borrado) { borrado.remove(); } }); });</script>
<% end %>
Con esto ya borramos los comentarios visualmente de la web, aunque no de la base de datos. Para ello tendríamos que utilizar un Ajax.Updater, y llamar a una acción que lo borre.
Droppables.add('papelera', {
containment: 'listacoments', onDrop:function(borrado) {
borrado.remove();
new Ajax.Updater('result_borrado', '/comentarios/delcoment',
{method:"get", parameters:"post_id=" + <%= @post.id %> +
"&id="+borrado.id.replace('listacoment_','')});
}
});
en el lado del servidor, definimos la acción:
# GET /comentarios/delcoment
def delcoment
@comentario = @post.comentarios.find(params[:id])
if @comentario.destroy
render :text => "Comentario eliminado satisfactoriamente"
else
render :text => "Error borrando comentario"
end
end
Ordenando con script.aculo.us
Otra funcionalidad muy útil que podemos tomar de script.aculo.us es la de ordenar elementos de una página de forma interactiva y sencilla. Por ejemplo, supongamos que queremos reordenar los comentarios de los posts. Bastaría, tal y como está ya construido del ejercicio anterior, con añadir otro bloque script al final del código:
<script type="text/javascript">
document.observe('dom:loaded', function() {
Sortable.create('listacoments', {tag:'div'});
});
</script>
<% end %>
Ya está, así de sencillo. Simplemente hemos usado la clase Sortable, con su método create. Esto define que los elementos del id listacoments sean ordenables. El atributo tag sirve para indicar que lo que queremos ordenar son los divs internos al div con id listacoments.
Podemos probar a arrastrar los comentarios hacia arriba y abajo y ver cómo se reordenan automáticamente. En el caso de que quisiéramos guardar el orden en la base de datos, existe un evento cuando se actualiza el orden en la página, que podemos usar para disparar algún Updater contra el servidor. En nuestro caso no lo vamos a hacer, porque la base de datos no está preparada para almacenar un orden distinto, pero vamos a capturar el evento de actualización del orden, y sacar entonces un mensaje por pantalla para que veamos la información que se guarda. Para ello modificamos el código anterior por este otro:
document.observe('dom:loaded', function() {
Sortable.create('listacoments', {tag:'div', onUpdate: function(item) {
var lista = Sortable.options(item).element;
alert(Sortable.serialize(lista));
}});
});
El evento en cuestión es onUpdate, cuando se dispare (cuando soltemos el elemento que estamos arrastrando para reordenar), se ejecutará la función que definimos. Lo que hacemos entonces es serializar los elementos con el nuevo orden y sacarlos por pantalla. Podemos ver qué cadena se muestra, y así saber cómo procesarla para enviarle al servidor los datos necesarios para ordenar.
listacoments[]=1&listacoments[]=2&listacoments[]=3
Observad que, a pesar de que los ids de cada div en el código fuente son listacoment_X, realmente Sortable se queda con el X concreto, desechando el prefijo. Si no ponemos ese prefijo, Sortable no es capaz de obtener los ids correctos.