Últimas entradas

Mi pequeño paso por python: RSS, HTML, Jquery

Hace no menos de un mes terminé un proyecto que consistía en mostrar noticias de diarios argentinos de manera offline. Para ser implementado en muy poco espacio de disco, por lo que utilizar algun framework sería un poco pesado.
El sistema ya se encontraba implementado con mod-python, la idea era seguir trabajando con eso y crear los scripts correspondientes en python.
Desde un principio la idea era que un script traiga los feeds de noticias cada cierto tiempo (utilizando tareas cron) y generar un html el cual se podía ver de forma offline.
Para ello en python existe una librería llamada feedparser, que nos trae en forma de diccionario todo lo que el servicio nos da.

import feedparser
import urllib2 #lo utilizamos mas adelante
import re #lo utilizamos mas adelante
parse = feedparser.parse(url_de_rss)

Si tenemos conexión a internet, esas líneas nos deberían bajar el feed completo que nos ofrece la página con la que queremos trabajar. Solo queda sacar lo que nos importa, en este caso el título, la noticia y las fotos si las hubiera. Como trabajamos offline no tendrín que haber links de ningun tipo

noticias = '<ol>\n'
for i in range(0,10):
    titulo = parse.entries[i].title
    resumen =  re.sub('((<a){1}(.)+(</a>)?)|((<img){1}(.)+(/img>)?)|((<table){1}(.)+(</table>)?)', '',parse.entries[i].summary_detail.value)
    try:
        img_url = urllib2.urlopen(parse.entries[i].enclosures[0].href).read()
        f = open("images/imagen_%s.jpg"%i,"w")
        f.write(img_url)
        imagen = '<img src="images/imagen_%s.jpg" alt=""/>'%i
    except:
        imagen = ''
    noticias += '<li>%s<br/>%s<br/>%s</li>\n'%(titulo,resumen,imagen)
 
noticias += '</ol>'
archivo_noticias = open("templates/_noticias.html","w")
archivo_noticias.write(noticias)

En la línea 1 simplemente inicializamos la variable que luego pondremos en el html correspondiente, vamos a utilizar una lista ordenada.
En la línea 2 empezamos nuestro bucle diciendo que sólo vamos a querer 10 noticias. Con un simple for podemos hacerlo, debido a que vamos a trabajar con la clave entries del diccionario, esta clave contiene un array, donde cada elemento es otro diccionario con sus propias claves. Las que vamos a utilizar en esta ocasión son:
title: Trae el título de la noticia.
summary_detail: Es donde está el resúmen de la noticia, este tiene como valor otro diccionario, de donde utilizaremos la clave value, donde está el resúmen propiamente dicho.
enclosures: es donde se guardan los adjuntos de la noticia, en este caso nos interesan las imágenes, pero como trabajamos offlines tenemos que descargarlas para ello utilizamos urllib2 asi la guardamos en nuestro sistema de archivos. A modo de ejemplo puse que la imagen tenga como nombre el indice de la noticia. Si sólo trabajamos con un diario no sería inconveniente, para más de un diario puede haber problemas porque los archivos se sobreescribirían y no se mostrariacutean las correctas. Esta parte pongo dentro de un try, porque no siempre traen imágenes y el parse nos tira una excepción, en caso de que pase cargamos la variable con nada, sino creamos el tag html de imágenes.
En la línea 3 creamos una variable donde se guarda el título de nuestra noticia
En la línea 4 guardamos el resúmen en una variable, puede parecer un poco complejo el código, pero es bastante fácil. Utilizamos la librería re para poder trabajar con expreciones regulares y con el método sub eliminamos del string las cosas que no queremos. A mi no me interesaba ningún
link:

 ((<a){1}(.)+(</a>)?)

imágen:

((<img){1}(.)+(/img>)?)

tabla:

((<table){1}(.)+(</table>)?

que haya en el resúmen, entonces cuando encuentre algo de eso que simplemente lo reemplace por nada.
Finalmente cerramos nuestra lista fuera del for y tendríamos un resultado parecido a este:

<ol>
<li>Titulo1<br/>Resumen1<br/><img src="images/imagen_1.jpg" alt=""/></li>
<li>Titulo2<br/>Resumen2<br/><img src="images/imagen_2.jpg" alt=""/></li>
<li>Titulo3<br/>Resumen3<br/><img src="images/imagen_3.jpg" alt=""/></li>
<li>Titulo4<br/>Resumen4<br/><img src="images/imagen_4.jpg" alt=""/></li>
<li>Titulo5<br/>Resumen5<br/><img src="images/imagen_5.jpg" alt=""/></li>
<li>Titulo6<br/>Resumen6<br/><img src="images/imagen_6.jpg" alt=""/></li>
<li>Titulo7<br/>Resumen7<br/></li>
<li>Titulo8<br/>Resumen8<br/><img src="images/imagen_8.jpg" alt=""/></li>
<li>Titulo9<br/>Resumen9<br/></li>
<li>Titulo10<br/>Resumen10<br/></li>
</ol>

Para poder guardarlo en el archivo _noticias.html
Ya tenemos toda una lista de noticias lista para ser leída offline, sólo queda cargarlo en nuestro index y problema resulto, para eso podemos hacer uso de jquery (se puede hacer directamente con javascript, pero una página web tiene bastante código javascript hoy en día y jquery es un framework muy copadito
para escribir poco :) ).

En el index.html tendríamos:

<div id="#noticias"></div>
 
<script type="text/javascript">
    $("#noticias").load('_noticias.html');
</script>

Este fue mi pequeño paso por python, la verdad una experiencia muy linda, es un muy buen lenguaje. En realidad si querés hacer un script de manera muy rápida es una buena opción.
Les dejo los links de feedparser y mod-python
Feedparser: http://code.google.com/p/feedparser/
Mod-Python: http://www.modpython.org/
Bueno espero que les haya gustado y hasta la próxima :)

Conferencias de Actualización en el marco de la Industria del Software del Nordeste

Semana 1. Fecha: 7 Octubre de 2011.

Tema: Desarrollo y Administración de Proyectos de Software
Disertantes: Ing. Fabián B. Bobadilla Godoy – - Aliare S.R.L.

;  Mario Alejandro Acevedo – 3Trex S.R.L.

Semana 2. Fecha: 14 Octubre de 2011.

Tema: Framework de aplicaciones web de código abierto
Disertante: Lic. Carlos Enrique Barbiero – Firma: IPCorp S.R.L.

Semana 3. Fecha: 21 Octubre de 2011.

Tema: Gestión de Proyectos
Disertantes: Ing. José Fernández , Ing. Diego Morales – Firma: DesarrollosNea S.R.L.

Semana 4. Fecha: 28 Octubre de 2011.

Tema: Exportaciones y mercados regionales
Disertante: Ing. Darío Almeida - Coninfo.net S.A.;  Lic. José Tagliarini - SP  S.A.

Semana 5. Fecha: 04 de Noviembre de 2011.

Tema: Accesibilidad en la Web. Aspectos técnicos y legales.
Disertante: Lic. Sonia Mariño FACENA ; Lic. Juan José Acevedo

Cocinando la Receta RGM (Ruby-GTK-MongDB) en FACENA

En el marco de las Jornadas de Presentación de Trabajos de Investigación y Desarrollo de Alumnos y Graduados L.S.I de FACENA, el día 24 de septiembre a las 11hs, Leandro Rodriguez y Carlos Mathiasen presentarán Cocinando la Receta RGM (Ruby-GTK-MongDB).

El objetivo de la charla es compartir la experiencia de utilizar la tecnología de:

Los esperamos en el edificio de la FACENA ubicado por calle 9 de Julio.

Aplicaciones de Escritorio: Ruby y Gtk+

Hola a todos. Debido a que dentro de un par de días doy una charla sobre el tema: JORNADA DE INTEGRACIÓN, EXTENSIÓN Y ACTUALIZACIÓN DE ESTUDIANTES DE INFORMÁTICA (JOINEA), me gustó la idea de compartir con ustedes una pequeña aplicación que muestra un poco el manejo de widgets gtk2, espero les guste.
Primero,
¿Qué es GTK?
GTK+ o The GIMP Toolkit es un conjunto de bibliotecas multiplataforma para desarrollar interfaces gráficas de usuario (GUI), desarrollada en C y utilizando en paradigma orientado a objetos.

¿Qué es Ruby-Gnome2?
Ruby-GNOME2 es un conjunto de librerías Ruby para el entorno de desarrollo Gnome2. Ésta es la siguiente generación del proyecto Ruby-GNOME.

Sabiendo esto podemos empezar a hacer nuestro programa de ejemplo.
El programa es muy sencillo, tiene un menú con dos opciones: Archivo y Editar y en cada opción se despliega un menú. Después tenemos un combo con nombres de “Artistas” del software libre :) y un botón. Cuando damos click al botón se abre un diálogo diciendo qué hizo ese artista.
Manos a la obra.

 
#!/usr/bin/ruby
#requerimos la librería gtk2
#depende de ruby1.8+ - ruby-gnome2 - ruby-gnome-dev
require 'gtk2'
 
#tiene que heredar de Gtk::Window
class RubyApp < Gtk::Window
 
   #constructor de la clase
   def initialize
        super
	#atributos de clase
	@fixed= Gtk::Fixed.new #crea un contenedor de tipo fixed vacío
	@combo= Gtk::ComboBox.new #crea un combobox vacío
	@menu= Gtk::MenuBar.new #crea una barra de menu vacía
	@boton= Gtk::Button.new "¿Qué hizo?" #crea un botón y le da valor al label
        set_windows
    end
 
    #setea los valores de la ventana
   def set_windows
	set_title  "Ipcorp Ruby y GTK+" #nombre de la ventana
	set_default_size 250, 200 #tamaño de la ventana
	set_window_position Gtk::Window::POS_CENTER #posicion de la ventana
	add fixed_main([combo_box, menu_bar, boton]) #llama a fixed_main para crear un contenedor
	show_all #muestra todo
	signal_connect "destroy" do 
	    Gtk.main_quit #cuando se le da click al boton cerrar se cierra el programa
	end
   end
    #agrega widgets al contenedor @fixed
    def fixed_main(widgets)
      widgets.each do | widget|
	  @fixed.put widget[0], widget[1], widget[2]
      end
      @fixed
    end
 
    #agrega valores al atributo @combo
    def combo_box
      contenido = ["Matz", "Stallman", "Linus", 'Mattis']
      contenido.each do |item|
        @combo.append_text item
      end
      [@combo,10,60]
    end
 
    #crea un menu y lo agrega al atributo @menu
    def menu_bar
      menues = {"Archivo" => ["Nuevo","Salir"],
                "Ayuda" => "Acerca de..."}
      menues.each do |menu_key, item_value|
	    menu = Gtk::Menu.new
	    submenu = Gtk::MenuItem.new menu_key
	    if item_value.class == Array
	        item_value.each do |item_v|
	            item_menu = Gtk::MenuItem.new item_v
	            menu.append item_menu
	            widget_activo(item_menu,1) if item_v == "Salir"
		    widget_activo(item_menu,2) if item_v == "Acerca de..."
	        end
	    else
	        item_menu = Gtk::MenuItem.new item_value
	        menu.append item_menu
	        salir(item_menu,1) if item_value == "Salir"
		widget_activo(item_menu,2) if item_value == "Acerca de..."
	    end
	    submenu.set_submenu menu
	    @menu.append submenu
      end
      [@menu,0,0]
    end
 
    #cuando se activa un item del menu ejecuta el codigo
    def widget_activo(widget,tipo)
      widget.signal_connect "activate" do
	tipo == 1 ? Gtk.main_quit : about_dialogo #si el tipo es 1 cierra la aplicacion, caso contrario abre el about
      end
    end
 
    #setea el tooltip del @boton y agrega un metodo en caso que se haga un click
    def boton
      @boton.set_tooltip_text "Button widget"
      @boton.signal_connect "clicked" do |w,e|
	mensaje_dialogo(@combo.active_iter.to_s)
      end
      [@boton,150,60]
    end
 
    #muestra un diálogo según el valor pasado
    def mensaje_dialogo(index)
      mensaje = case index
		  when "0" 
		    "Creador del lenguaje ruby..."
		  when "1" 
		    "Creador del Proyecto GNU... Se presentará en Posadas el 05/09/2011"
		  when "2" 
		    "Creador del kernel Linux..."
		  when "3" 
		    "Creador del proyecto GTK+..."  
		  else 
		    "No elegiste nada"
		end
      md = Gtk::MessageDialog.new(self,
	  Gtk::Dialog::DESTROY_WITH_PARENT, Gtk::MessageDialog::INFO, 
	  Gtk::MessageDialog::BUTTONS_CLOSE, mensaje)
      md.run
      md.destroy
    end
 
    #crea un diálogo about.
    def about_dialogo
        about = Gtk::AboutDialog.new
        about.set_program_name "Prueba GTK Ipcorp 2011"
        about.set_version "0.1"
        about.set_copyright "(cc) Carlos Mathiasen"
        about.set_comments "Una simple muestra de lo que se puede hacer con gtk y ruby"
        about.set_logo Gdk::Pixbuf.new "ipcorp.png"
        about.run
        about.destroy
    end
 
end
 
#Ejecuta la aplicación
Gtk.init # con esta linea inicializamos la librería de gtk2
    window = RubyApp.new
Gtk.main

El código está comentado en casi todas sus líneas explicando lo que hace. Espero les resulte útil y cualquier cosa no duden en preguntar.

Jornada de Integración, Extensión y Actualización de estudiantes de informática (JoInEA)

La Jornada de Integración, Extensión y Actualización de estudiantes de informática (JoInEA) es organizada por una comisión de alumnos de las carreras de informática de la Facultad de Ciencias Exactas, Químicas y Naturales de la Universidad Nacional de Misiones. El objetivo de la misma es efectivizar la logística de la actualización mediante la integración y extensión, generando un espacio para los aportes, avances y reflexiones de estudiantes y profesionales del medio; así como también la promoción e inserción del personal y las herramientas informáticas en nuestra sociedad.
La misma fué declarada de interés provincial el pasado 9 de agosto.

Estaré presentando la charla “Interfaces de Usuario Con Ruby y GTK” el viernes 02 de septiembre de 2011 a las 14:30 hs.

Si querés saber un poco más visitá: JOINEA

Los espero

Richard Stallman en Posadas (Misiones). “El software libre y tu libertad”

Misiones Software Libre – MiSoL- e IPCorp SRL  los invita a la Conferencia Magistral de Richard Matthew Stallman “El software Libre y tu Libertad” que se realizará en las instalaciones del  Centro del Conocimiento – sala 1 del Centro de Convenciones de la Ciudad de Posadas Misiones el próximo 5 de Septiembre a las 17hs.

Noticia en sitio de MiSol : http://www.misol.org.ar/2011/07/richard-m-stallman-en-septiembre-dara-una-conferencia-en-posadas/

Richard Matthew Stallman (rms) es conocido por establecer y desarrollar el Proyecto GNU que es el marco legal, filosófico y ético-moral para los movimientos de Software Libre, también es creador del concepto de copyleft, un método para licenciar software de tal forma que su uso y modificación permanezcan siempre libres y queden en la comunidad.

Este evento también está coorganizado junto a la Universidad Nacional de Misiones, Polo Audiovisual Tecnológico NEA, Centro del Conocimiento – Gob. de la Pcia de Misiones – ,  y se encuentra enmarcado dentro de la agenda de la Conferencia Internacional de Software Libre – CISL – que se realizará el 8 y 9 de Septiembre  en la ciudad de Buenos Aires.

Script para recorrer archivos html y encontrar las clases

Me vinieron con un problema bastante bueno ayer: “Necesito que elimines las clases que no se usan en el archivo .css”, la verdad parece no complicarse mucho, el problema se agrava un poco cuando tenés unos cuantos archivos html. Por curiosidad se me ocurrió contar los archivos:

  find /proyectos/app/ -name *.erb -exec ls -l {} \; | wc -l
  #busco todos los que terminan en .erb, porque es un proyecto en Rails

Me dió la módica suma de 444 archivos. Ahora si se complicaba demasiado hacerlo a mano.
Me puse a incursionar un poco en bash y salió esto:

a=$(find $1 -name "*.erb"); #busco los archivos y guardo los paths en una lista
for i in $a; do #recorro la lista
   cat $i | egrep 'class="' | awk -F 'class=' '{print $2}' | awk -F '"' '{print $2}' | awk -F ' ' '{for (j=1; j<=NF; j++)  print $j; print "\n"}' >> clases.txt
done  
 
sort clases.txt >> clases2.txt #ordeno el archivo y lo guardo en otro
rm clases.txt #elimino el primer archivo
uniq -u clases2.txt >> clases.txt #borro las l&iacute;neas duplicadas (ya que las clases no son &uacute;nicas)
rm clases2.txt #elimino el archivo auxiliar

La tercer linea del script la explico aca abajo, sino no se iba a entender nada

cat $i: muestra el contenido del path que le estamos pasando.
egrep ‘class=”‘: Me muestra solo las líneas que contienen ‘class=”‘, que es como definimos una clase en html.
awk -F ‘class=’ ‘{print $2}’:Hago como un split a un string separando por ‘class=’ y mostrando solo el segundo valor, es decir todas las clases que tenga ese tag.
awk -F ‘ ‘ ‘{for (j=1; j<=NF; j++) print $j; print "\n"}': Como ya tenemos en una sola línea todas las clases de un tag, y sabemos que las clases se separan con un espacio, hacemos nuestro split por espacios y recorremos todas las variables y las vamos imprimiendo con un salto de linea al final. Esto nos haría una lista con todas las clases que existan en los archivos html.
Después habriendo el archivo clases.txt, vemos las clases ordenadas y únicas :)

Quizá se pueda costumizar más, no usar 2 archivos sino solo uno. También se podria recorrer el archivo .css y compararlo con nuestro archivo, eliminando las líneas que necesitamos. Pero para salir del apuro anda perfecto. Y si queremos encontrar los id, es cuestión de reemplazar la búsqueda nomá, aunque me tira algunos datos sucios, ya que también se usa en javascript y en ruby, entonces por ahi se complicaba un poco más, pero les dejo como tarea para la casa jeje
Bueno espero les pueda servir y cualquier consulta no duden en comentar.

FullCalendar de JQUERY Y RAILS

Les queria mostrar un calendario con el cual me entusiasme mucho cuando lo puse en práctica, claro que adaptándolo a mi aplicación.
FullCalendar es un plugin JQuery para implementar un calendario con una interfaz muy sencilla de implementar y muy personalizable por medio de CSS.

Para configurarlo, este recurso brinda un conjunto de parámetros, objetos y eventos como:
*Opciones para definir meses, años, si el elemento es arrastrable, la transparencia del elemento arrastrado, titulo, etc.
*Eventos para proveer los datos.
*Eventos que se disparan al hacer clic en un día, al cargar, al arrastrar, al soltar, etc.
*Objetos del calendarios como título, fecha, hora, etc.
*Ademas es de código abierto

De acuerdo a mis necesidades y a mi lenguaje utilizado, lo implemente de la siguiente manera:
Se descarga el archivo ZIP de la biblioteca JQuery, el plugin y demos funcionales y los incluís a tu archivo que contienen tus scripts.

Inicialmente en tu formulario donde vas a presentarlo, lo llamas con un simple identificador

Luego en la parte del codigo javascript, incluís el conjunto de parámetros que te sea mas útil.

A modo de ejemplo les muestro algunos que utilice:

<table>
  <tr>
  <a><%= link_to 'Nuevo Evento', turno_tarea_turnos_path %></a>
 
// Este link_to nos llevara a los distintos eventos que serán mostrados en el calendario (en el caso de mi aplicación)
 
 </tr>
</table>
 
<table>  
<div id='calendar'></div>  
 
Acá comenzamos a configurar el calendario
<script type="text/javascript">
  $(document).ready(function(){
$('#calendar').fullCalendar({   
          editable: true,
          header: {
              left: 'prev,next',
              center: 'title'
              /*right: 'month,agendaWeek,agendaDay'*/
          },
          defaultView: 'agendaWeek',      
          height: 600,
          slotMinutes: 30,
          minTime : 8,
          maxTime : 21,
          firstDay : 1,
          allDaySlot : false,
          columnFormat:'ddd d/M',       
           titleFormat : "MMM d[ yyyy]{ '&#8212;'[MMM] dd 'del' yyyy}",
          weekends: false,
          defaultEventMinutes : 30,        
          buttonText: {prev: '&nbsp;&#9668;&nbsp;',
		next: '&nbsp;&#9658;&nbsp;',
		prevYear: '&nbsp;&lt;&lt;&nbsp;',
		nextYear: '&nbsp;&gt;&gt;&nbsp;',
                today : 'Hoy'},
 
          unselectAuto: false,
          weekMode : false,
          monthNamesShort : ['Enero' , 'Febrero' , 'Marzo' , 'Abril' , 'Mayo' , 'Junio' , 'Julio' ,
                        'Agosto' , 'Septiembre' , 'Octubre' , 'Noviembre' , 'Diciembre' ],
          dayNamesShort : ['Domingo', 'Lunes', 'Martes', 'Miercoles', 'Jueves', 'Viernes', 'Sabado'],
 
 
  // Este pequeño array nos va a permitir visualizar los eventos
          events:[
 
            <% for turno in @turnos = Turno.all   -%>
              {
               id : 'turno: <%= turno.id.to_s %>',
               title  : 'Profesional: <%= turno.profesional.nombre %> Duracion: <%= turno.duracion %>minutos Paciente: <%= turno.paciente.nombre  %> ' ,
               start : 'Fecha: <%= turno.fecha_hora.iso8601 %>',
               end : 'Duracion: <%= (turno.fecha_hora + (60 * turno.duracion)) %>',
               allDay : false,
               url: '<%= eliminar_turno_path(turno) %>'
 
              },
 
            <% end %>           
 
              ],
 
          timeFormat: 'h:mm t{ - h:mm t} ',
          dragOpacity: "0.5",
 
 
 
          eventDrop: function(event, dayDelta, minuteDelta, allDay, revertFunc){
              if (confirm("Are you sure about this change?")) {
                  moveEvent(event, dayDelta, minuteDelta, allDay);
              }
              else {
                revertFunc();
              }
          },
 
          eventResize: function(event, dayDelta, minuteDelta, revertFunc){
              if (confirm("Are you sure about this change?")) {
                  resizeEvent(event, dayDelta, minuteDelta);
              }
              else {
                 revertFunc();
              }
          },        
 
 
// En este caso, al hacer click sobre el evento, me llevara a la url especificada para ese evento (se muestra mas arriba)
 
 eventClick: function(event, jsEvent){
             if (event.url) {
              if (confirm('Esta seguro de eliminar? Esta accion no se podra deshacer')){
                event.url;
              //return false;
              }else{
                return false;
              }
 
        }
          }
}
 
</script>

Espero que les guste y lo implementen.

Para descargar los archivos js: http://arshaw.com/fullcalendar/
Otro ejemplo que me sirvió lo podes ver en http://fullcalendar.vinsol.com/

IPCorp en el 4to Festival Misionero de Software Libre.

La comunidad MiSol invita a todos al 4to Festival Misionero de Software Libre los días 20 y 21 de Mayo de 2011 próximos en la Fac. de ingeniería de la UNaM (Universidad Nacional de Misiones) en la ciudad de Oberá, Misiones, Argentina.

IPCorp S.R.L estara presente en el mismo presentando  la charla  sobre “Desarrollo con RubyOnRails y PostgreSQL”  la misma sera disertada por Carlos Mathiasen y Alfredo Ramirez el sabado 21 de mayo de 2011 a las 15:00 hs.

Este evento tiene como objetivo fomentar las ventajas técnicas, sociales, políticas y filosóficas relacionadas a la utilización del software libre. En particular este año abordaremos 2 temáticas: “Hackers”“Cultura Libre” para que podamos divertirnos entre todos de la diversidad de temas en nuestra comunidad.

Este año nuevamente contaremos con la presencia de:

Mozilla Foundation que llevan adelante un modelo de negocio basado en software libre y conocimiento libre.
SoLAr (Software Libre Argentina) – Asociación civil sin fines de lucro dedicada a la promoción del Soft. libre en nuestro país.

El evento constará de:
Viernes 20: Charlas y ponencias en el auditorium de la Facultad de Ingeniería – Juan Manuel de Rosas 325. Acreditación 8:00 hs – Inicio 9:15hs
Sábado 21: Charlas en las aulas “Hackers” y “Cultura Libre” (Facultad de Ingeniería). INICIO 9:00 hs
Entrada Libre y Gratuita – CERTIFICADO IMPRESO $25

Jquery Validation y formulario ajax en rails

Hola a todos. Hoy vengo con un pequeño tip que me hizo doler la cabeza por un rato.
El problema era el siguiente, tenía un formulario ajax y necesitaba hacer una validación del lado del cliente. Para realizar la validación utilizaba el plugin de jquery validation, y para el formulario ajax usaba lo siguiente

<% form_remote_for @personas, :url => crear_titulares_personas_path, :method => 'POST' , :update => 'creado' do |f| %>
<%= f.text_field :nombre, :class => 'required'%>
<%= f.submit "Guardar" %>
<% end %>
 
<script type="text/javascript">
  $(document).ready(function(){
   $('#new_factor_variante').validate();
  });
</script>

Normalmente, al presionar el botón Guardar, el plugin me dice que ingrese un nombre (debido a que el campo es requerido) y no va al método del controller hasta que lo ingrese. Sin embargo me mostraba el error, pero igual se iba hasta el controller, es decir, la acción se ejecutaba igual.
Para resolver esto, después de una ardua búsqueda en google, decidí consultar la api de rails 2.3.5(es la versión que estoy usando) y encontre que podes agregar una condición en el form, para que se ejecute o no la acción y en esta condición puedo meter código javascript.
Lo que hice fue preguntar si el formulario era válido y el código me quedó así:

<% form_remote_for @persona, :url => crear_titulares_personas_path, :method => 'POST' , :condition => '$(this).valid()',  :update => 'creado' do |f| %>
<%= f.text_field :nombre, :class => 'required'%>
<%= f.submit "Guardar" %>
<% end %>
<script type="text/javascript">
  $(document).ready(function(){
   $('#new_factor_variante').validate();
  });

.valid() es un método del jquery validation que me devuelve un valor booleano según el estado del formulario.
Con esto ya pueden tener validación del lado del cliente con un formulario ajax en rails.
Espero les sirva, cualquier cosa pregunten nomás

Next Page »