viernes, 30 de marzo de 2007

Manejo de fechas vacías con dynarch_calendar

En la aplicación en la que estoy trabajando necesito poder manejar fechas vacías con dynarch_calendar y no encuentro cómo hacerlo utilizando los métodos y parámetro existentes. He tenido que meter un par de cambios en el código del bundle que paso a enumerar:

- dynarch_calendar.rb

La última línea del método dynarch_date_select queda como

buffer << "<script>convert_date_container_to_dynarch_calendar('#{object_name}', '#{method_name}', #{index}, '#{object.send(method_name) ? initial_date : ''}', '#{object.send(method_name) ? initial_display : ''}', '#{image_url}')</script>\n"

de forma que si el campo fecha está vacío pase los parámetros initial_date e initial_display en vacío.

- convert_calendar_field.js

Cuando llega vacío y se utiliza en la línea 22

date = Date.parseDate(initial_date, ifFormat);

genera un objeto Date con la fecha del día. Por ello hay que trucar la asignación de los campos hidden en las líneas 28-30 de la siguiente manera:

dynarch_contents += "<input type='hidden' " + name_and_id('1i', 'year') + " value='" + (initial_date != '' ? date.getFullYear() : '') + "'>\n";
dynarch_contents += "<input type='hidden' " + name_and_id('2i', 'month') + " value='" + (initial_date != '' ? (date.getMonth() + 1) : '') + "'>\n";
dynarch_contents += "<input type='hidden' " + name_and_id('3i', 'day') + " value='" + (initial_date != '' ? date.getDate() : '') + "'>\n";


- Mi formulario

La línea que genera el calendario en mi formulario queda de la siguiente manera:

<%= dynarch_date_select 'vehicle', 'garage_out_date', {:date_format => "%d/%m/%Y", :use_month_names => spanish_month_names, :include_blank => true} %>

donde

def spanish_month_names
return ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre']
end

con lo que conseguimos que si no hay javascript habilitado, los combos que se generan se vean en castellano y con una opción en blanco para poder dejar la fecha vacía.

jueves, 22 de marzo de 2007

PDA y rails

He estado recientemente adaptando una aplicación hecha con ajaxscaffold para que pueda ser utilizada a través de una PDA con Intenet Explorer Mobile 5. Me he encontrado algunos inconvenientes lógicos y predecibles y otros no tanto.

En resumen:

- por alguna razón, los métodos de prototype.js sólo funcionan 'a veces'.
- lo mismo ocurre con las peticiones AJAX.
- el código generado con script/gnerate ajaxscaffold por sí mismo no funciona en PDA.
- en general, en una PDA no caben tantos datos como en una pantalla de portátil o sobremesa.
- el coste en tiempo de hacer que cierto código que funciona en portátil o sobremesa funcione también en PDA es, en general, mayor que el duplicar código.
- la conexión a través de PDA falla bastante y, en ocasiones, exige recargar páginas.

Por tanto, me he visto obligado a tomar las siguientes decisiones

- controlar en todos los controladores implicados si el dispositivo conectado es PDA.
- duplicar vistas en lugar de 'enmarañar' el código.
- eliminar AJAX de las vistas para PDA.
- reducir los formularios y los datos mostrados en las vistas para PDA.
- utilizar un layout propio para PDA que incluye hojas de estilo y ficheros de javascript reducidos.

Finalmente, para controlar el dispositivo he utilizado el siguiente método al que invoco before_filter.

def check_device
  @mobile_device = !request.env['HTTP_X_WAP_PROFILE'].blank?
  return true
end


Es muy posible que haya alguna manera mejor de controlarlo, pero revisando las cabeceras HTTP del request me pareció el parámetro más fiable de comprobar.

jueves, 15 de marzo de 2007

button_to_popup

En rails es muy sencillo hacer que un link abra una URL en un popup. Basta con utilizar link_to y utilizar el parámetro :popup.

Un ejemplo:

<%= link_to('Abrir ventana', {:action => 'my_action'}, :popup => ['ventana', 'height = 650, width = 750, top = 20, left = 100, scrollbars = 0, toolbar = 0, status = 0, menubar = 0, location = 0']) %>

Si queremos cambiar el link por un botón, no existe un método que por sí mismo te ofrezca la funcionalidad. Sin embargo, podemos darle una vuelta de tuerca al método button_to para que lo haga con una ayudita de javasctipt.

El ejemplo anterior quedaría de la siguiente manera:

<%= button_to('Abrir ventana', {:action => 'my_action'}, {:onclick => "this.form.target = 'ventana'; window.open('','ventana', 'height = 650, width = 750, top = 20, left = 100, scrollbars = 0, toolbar = 0, status = 0, menubar = 0, location = 0')"}) %>