2009-02-26 8 views
29

Me gustaría que los campos de formulario de edición sean tan fáciles de usar como sea posible. Por ejemplo, para valores numéricos, me gustaría que el campo se muestre con comas (como number_with_precision).¿Cómo puedo formatear el valor que se muestra en un campo de edición de Rails?

Esto es bastante fácil en el lado de la pantalla, pero ¿qué hay de la edición? ¿Existe una forma correcta de hacer esto?

Estoy usando Rails FormBuilder. Tras la investigación, descubrí que usa InstanceTag, que obtiene los valores para los campos usando <attribute>_value_before_type_cast, lo que significa que se reemplaza a <attribute> y no se llamará.

+0

que han comenzado una recompensa por esta pregunta porque me gustaría saber si hay una mejor respuesta que las articuladas por JDL y yo. ¡Tienen en él! –

Respuesta

37

El mejor que he encontrado hasta el momento es algo como esto:

<%= f.text_field :my_attribute, :value => number_with_precision(f.object.my_attribute) %> 

O my_attribute podría devolver el valor con formato, como este:

def my_attribute 
    ApplicationController.helpers.number_with_precision(read_attribute(:my_attribute)) 
end 

Pero todavía tiene que utilizar :value

<%= f.text_field :my_attribute, :value => f.object.my_attribute %> 

Esto parece mucho trabajo.

+0

Nota: Si usa la primera solución con un formato que agrega comas o símbolos de moneda, debe eliminarlos en los métodos de creación y actualización de su controlador. – LeBleu

+0

Evitaría usar la segunda solución, hacer referencia a 'ApplicationController' dentro de su modelo definitivamente no es algo bueno para acostumbrarse. –

+0

La última que funcionó mejor para mí, mis funciones aún podrían estar en mi modelo de datos y no afecta la presentación o edición. Buena solución! –

9

Prefiero su primera respuesta, con el formateo que se realiza en la vista. Sin embargo, si desea realizar el formateo en el modelo, puede usar métodos de envoltura para el captador y el colocador, y evitar tener que usar la opción: valor por completo.

Terminas con algo como esto.

def my_attribute_string 
    foo_formatter(myattribute) 
end 

def my_attribute_string=(s) 
    # Parse "s" or do whatever you need to with it, then set your real attribute. 
end 

<%= f.text_field :my_attribute_string %> 

Railscasts cubiertos Este con un objeto Tiempo en un text_field en episode #32. La parte realmente inteligente de esto es cómo manejan los errores de validación. Vale la pena ver el episodio solo por eso.

3

Si desea crear o mantener un formato durante la edición, deberá agregar Javascript para implementar "máscaras". Here is a demo.

Fue el primer golpe en these results.

+0

La demostración ya no está, aquí hay una nueva: https://igorescobar.github.io/jQuery-Mask-Plugin/ – fatfrog

1

He hecho algo similar. Formateamos tiempos y longitudes utilizando un generador de formularios personalizado. Se hace uso de la text_field existente, sino que lo envuelve por lo que el valor puede ser modificado para requisitos:

class SuperFormBuilder < ActionView::Helpers::FormBuilder 
    include ApplicationHelper 
    include FormHelper 
    include ActionView::Helpers::TagHelper 
    include ActionView::Helpers::FormTagHelper 

    def length_field(label,*args) 
    scale = 'medium' 
    args.each do |v| 
     if v.has_key?(:scale) 
     scale = v[:scale] 
     v.delete(:scale) 
     end 
    end 
    value = length_conversion(@object.send(label.to_sym),scale) 
    options = (args.length > 0) ? args.pop : {} 
    return has_error(label, text_field_tag(field_name(label),value,*args) + ' ' + length_unit(scale)) 
end 

private 
def field_name(label) 
    return @object_name + "[#{label}]" 
end 

def has_error(label, output) 
    return "<div class='fieldWithErrors'>#{output}</div>" if @object.errors[label] 
    return output 
end 

y se utiliza de esta manera:

<%= form_for(@section, {:action => 'save', :id => @section.id}, :builder => SuperFormBuilder) do |sf| %> 
    <%= sf.length_field :feed_size_min_w, :size => 3, :scale => 'small' %> 
<% end %> 

El resultado final es un valor en unidades apropiadas, basadas fuera de su elección en el sistema (Métrico, Imperial) y escala IE pequeño = pulgadas o milímetros.

B básicamente copié el método text_field del constructor de formulario existente, que usa el text_field_tag ​​mismo.

Hay dos errores: 1) Conocer el nombre del campo del objeto y cómo acceder al objeto para obtener el valor que desea formatear. 2) Obtener el nombre correcto para que cuando se envíe el formulario sea parte del hash de parámetros correcto.

Al generador de formularios se le asigna una variable de clase @object. Puede obtener el valor del campo usando el método .send.En mi caso, envío la etiqueta: feed_size_min_w al @object y recupero su longitud. Luego lo convierto al formato deseado y se lo paso al text_field_tag.

El nombre del campo es clave para que termine en hash de params, en mi caso params [: sections] one. Hice una pequeña función auxiliar llamada field_name que se encarga de esto.

Finalmente, has_error ajusta el campo en un error div si hay errores en esa etiqueta.

3

Puede usar el complemento number_format. Al especificar un number_format para un atributo numérico existente dentro de su modelo, el atributo ahora aparecerá como formateado en Rieles en todos los formularios y vistas. También se analizará desde ese formato (cuando se asigna a través de formularios) antes de la inserción en la base de datos. (El plugin también crea puramente numéricos unformatted_<attribute-name> descriptores de acceso que pueden seguir siendo utilizadas para la aritmética, o para la asignación numérica directa o recuperación por usted para una integración perfecta.)

class MyModel < ActiveRecord::Base 
    # this model has the balance attribute, which we 
    # want to display using formatting in views, 
    # although it is stored as a numeric in the database 
    number_format :balance, 
       :precision => 2, 
       :delimiter => ',', 
       :strip_trailing_zeros => false 

    def increment_balance 
    unformatted_balance += 10 
    end 

También se pueden combinar lo anterior con una solución Javascript, que puede obligar al usuario a mantener el punto decimal y miles de separadores en su lugar durante la edición, aunque esto realmente no es necesario.

+0

Buena idea. No estoy trabajando en Rails 3 como lo probé hoy. – Cheng

4

Esta es una vieja pregunta, pero en caso de que alguien se encuentre con esto, podría usar los helpers number_to_X. Tienen todos los atributos que usted podría desear para mostrar su valor de edición:

<%= f.text_field :my_number, :value => number_to_human(f.object.my_number, :separator => '', :unit => '', :delimiter => '', :precision => 0) %> 

Hay más atributos disponibles también: http://api.rubyonrails.org/classes/ActionView/Helpers/NumberHelper.html

Cuestiones relacionadas