[Lift] Forms validation formatter

2009-03-17 Thread Clemens Oertel

Hello everybody,

Still trying to learn how to use lift efficiently and effectively, I  
got a little bit confused about the toForm function in the model/ 
mappers. Admittedly, my web framework background may be limited, but  
this looked to me as if some view code snuck into the model space  
there (I must admit that I do like how RoR tries to keep the models  
fairly clean of both controller  code and of view code).

For my first little project, I was going to encapsulate the HTML field  
formatting into a separate class (similar to what RoR does, but making  
use of the type system).

This is a very quick brain dump, not running code.

// The different field types, at a higher level than HTML
abstract class InputType
case class TextField extends InputType
case class DateField extends InputType
case class DateTimeField extends InputType

// Rendering hints that an form field formatter may use, could also be  
called FormGenerator ...
abstract class RenderingHint
case class MinLength(l: Int) extends RenderingHint
case class MaxLength(l: Int) extends RenderingHint

// Input-type aware callback'ed formatter, from the model's perspective
trait InputTypeHandler {
   def handleTextField(fieldID: String, presetValue: String,  
renderingHints: RenderingHint*)

   def handleDateField(fieldID: String, presetValue: Date,  
renderingHints: RenderingHint*)
}

// A model class using the callback
class ModelClass {
   object aField extends MappedString(this, 128) {
 def inputTypeCallback(InputTypeHandler handler) {
   // A reasonable default should/could be pushed upwards in the  
type hierarchy
   handler.handleTextField(fieldID, this.is, MaxLength(this.length))
 }
   }
}

This InputTypeHandler could be a nice spot to deal with validation  
result formatting:

class AnInputFormatter(errors: List[FieldError]) extends  
InputTypeHandler {
   def handleTextField(fieldID: String, presetValue: String,  
renderingHints: RenderingHint*) {
 errors.filter(_._1 == fieldID).match {
   case Nil = /* format field normally */
   case xs = /* format as error, i.e. red background, error  
messages right of field  */
 }
   }

   ...
}

// A snippet
...
val inputFormatter = new AnInputFormatter(errorsFromValidation)
bind(form, html, aField - aModelClass.aField.  
inputTypeCallback(inputFormatter))
...

Maybe a partial function, potentially on case classes, is better? Many  
options ...

I'm looking forward to any feedback.

Best,
Clemens

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Forms validation formatter

2009-03-17 Thread Clemens

Hello everybody,

(I sent this post once already a few hours ago, but it has not shown
up yet, so I decided to send it again. I apologize should it show up
twice.)

Still trying to learn how to use lift efficiently and effectively, I
got a little bit confused about the toForm function in the model/
mappers. Admittedly, my web framework background may be limited, but
this looked to me as if some view code snuck into the model space
there (I must admit that I do like how RoR tries to keep the models
fairly clean of both controller  code and of view code).

For my first little project, I was going to encapsulate the HTML field
formatting into a separate class (similar to what RoR does, but making
use of the type system).

This is a very quick brain dump, not running code.

// The different field types, at a higher level than HTML
abstract class InputType
case class TextField extends InputType
case class DateField extends InputType
case class DateTimeField extends InputType

// Rendering hints that an form field formatter may use, could also be
called FormGenerator ...
abstract class RenderingHint
case class MinLength(l: Int) extends RenderingHint
case class MaxLength(l: Int) extends RenderingHint

// Input-type aware callback'ed formatter, from the model's
perspective
trait InputTypeHandler {
 def handleTextField(fieldID: String, presetValue: String,
renderingHints: RenderingHint*)

 def handleDateField(fieldID: String, presetValue: Date,
renderingHints: RenderingHint*)
}

// A model class using the callback
class ModelClass {
 object aField extends MappedString(this, 128) {
   def inputTypeCallback(InputTypeHandler handler) {
 // A reasonable default should/could be pushed upwards in the
type hierarchy
 handler.handleTextField(fieldID, this.is, MaxLength(this.length))
   }
 }
}

This InputTypeHandler could be a nice spot to deal with validation
result formatting:

class AnInputFormatter(errors: List[FieldError]) extends
InputTypeHandler {
 def handleTextField(fieldID: String, presetValue: String,
renderingHints: RenderingHint*) {
   errors.filter(_._1 == fieldID).match {
 case Nil = /* format field normally */
 case xs = /* format as error, i.e. red background, error
messages right of field  */
   }
 }

 ...
}

// A snippet
...
val inputFormatter = new AnInputFormatter(errorsFromValidation)
bind(form, html, aField - aModelClass.aField. inputTypeCallback
(inputFormatter))
...

Maybe a partial function, potentially on case classes, is better? Many
options ...

I'm looking forward to any feedback.

Best,
Clemens

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---