RE: [Lift] Multipage wizards

2009-12-14 Thread Naftoli Gugenheim
Found this sitting in my drafts... :)
I agree. It should be possible for library users to have the same meaning with 
the bytes experience while factoring out Mapper so that the presentation 
aspect lives in a trait that can be used without Mapper.

-Original Message-
From: Jeppe Nejsum Madsen je...@ingolfs.dk
Sent: Wednesday, November 25, 2009 3:30 AM
To: liftweb@googlegroups.com
Subject: Re: [Lift] Multipage wizards

David Pollak feeder.of.the.be...@gmail.com writes:

 Folks,

 I've completed the first pass at multi-page input Wizards in Lift.  You can
 see an example at: http://demo.liftweb.net/wiz

Great news!

[...]

 The building of HTML forms from the given field type is based on the type
 (currently, there's support for String and Int, but more to come) and it's
 based on plugable functions, so you can build date pickers that are
 localized, etc.

 What needs to be done:

- The naming (including the names that the various parts of the wizard
bind to) need a good going-over
- Support for many different input types (not just Int and String)
- Feedback

I've been thinking about this for a while and haven't really reached
anything concrete yet, but it overlaps enough with the wizard stuff that
I might just throw it out here now:

I think that form handling in Lift is too cumbersome. I.e. all the
building blocks are there to create great forms, but it takes too much
boilerplate code to achieve a nice result. 

I know forms are not sexy in the ways Comet  Ajax support is, but for
many applications (ours included :-) it's where the major interactions
with the user happens, so a good UX is essential. 

Here's my (ultimate) list of things that should be easy (for the
developer) to do without too much fuzz:

- Provide field level validations - including client side if possible
- Provide form level validations - including client side
- If the form contains Mapper fields, you should not have to respecify
  the validations
- Render fields with proper markup (ie required fields should be indicated)
- When a form is in error, retain values entered by the user
- When a field is in error render it differently (ie red) with field
  specific error
- Provide field level help (inline, popup etc)
- Provide form level help
- All fields and text should support i18n (ie both labels, text and for numeric 
and e.g
  date entries)

I haven't looked closely at the wizard code yet, but it seems like it
does provide some of these benefits. Some possible ideas:

- Could be nice if the wizard code could be extended to generic
  forms. Wizards would just be a special case, with a sequence of forms
  and prev/next buttons etc.
- I would very much like to see validations lifted to a higher level so
  that the same validation rule can be used for Mapper (and Record),
  forms  wizards.
- Fields should be able to emit client side validations and code
- Maybe we could introduce generic form fields (ie Number, Date etc) and
  they could be reused by the Mapper/Record fields. In this way, they
  would all share the same presentation logic (ie i18n formatting for
  display/editing, datepickers, more advanced dialogs etc)
- Much more

Thoughts?

We'll soon be needing much of this in our app, so I'm willing to
participate in this if there's any interest.

/Jeppe

--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@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.



--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@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.




Re: [Lift] Multipage wizards

2009-11-30 Thread David Pollak
On Wed, Nov 25, 2009 at 12:30 AM, Jeppe Nejsum Madsen je...@ingolfs.dkwrote:

 David Pollak feeder.of.the.be...@gmail.com writes:

  Folks,
 
  I've completed the first pass at multi-page input Wizards in Lift.  You
 can
  see an example at: http://demo.liftweb.net/wiz

 Great news!

 [...]

  The building of HTML forms from the given field type is based on the type
  (currently, there's support for String and Int, but more to come) and
 it's
  based on plugable functions, so you can build date pickers that are
  localized, etc.
 
  What needs to be done:
 
 - The naming (including the names that the various parts of the wizard
 bind to) need a good going-over
 - Support for many different input types (not just Int and String)
 - Feedback

 I've been thinking about this for a while and haven't really reached
 anything concrete yet, but it overlaps enough with the wizard stuff that
 I might just throw it out here now:

 I think that form handling in Lift is too cumbersome. I.e. all the
 building blocks are there to create great forms, but it takes too much
 boilerplate code to achieve a nice result.

 I know forms are not sexy in the ways Comet  Ajax support is, but for
 many applications (ours included :-) it's where the major interactions
 with the user happens, so a good UX is essential.

 Here's my (ultimate) list of things that should be easy (for the
 developer) to do without too much fuzz:

 - Provide field level validations - including client side if possible
 - Provide form level validations - including client side
 - If the form contains Mapper fields, you should not have to respecify
  the validations
 - Render fields with proper markup (ie required fields should be indicated)
 - When a form is in error, retain values entered by the user
 - When a field is in error render it differently (ie red) with field
  specific error
 - Provide field level help (inline, popup etc)
 - Provide form level help
 - All fields and text should support i18n (ie both labels, text and for
 numeric and e.g
  date entries)

 I haven't looked closely at the wizard code yet, but it seems like it
 does provide some of these benefits. Some possible ideas:

 - Could be nice if the wizard code could be extended to generic
  forms. Wizards would just be a special case, with a sequence of forms
  and prev/next buttons etc.
 - I would very much like to see validations lifted to a higher level so
  that the same validation rule can be used for Mapper (and Record),
  forms  wizards.
 - Fields should be able to emit client side validations and code
 - Maybe we could introduce generic form fields (ie Number, Date etc) and
  they could be reused by the Mapper/Record fields. In this way, they
  would all share the same presentation logic (ie i18n formatting for
  display/editing, datepickers, more advanced dialogs etc)
 - Much more

 Thoughts?


Yeah this all sounds good.

I'm trying to unify most of the pieces of single form inputs, validation,
mapper, record and wizard.  It's generally slow going.



 We'll soon be needing much of this in our app, so I'm willing to
 participate in this if there's any interest.

 /Jeppe

 --

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





-- 
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Surf the harmonics

--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@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.




Re: [Lift] Multipage wizards

2009-11-30 Thread Jeppe Nejsum Madsen
David Pollak feeder.of.the.be...@gmail.com writes:


[...]

 Thoughts?


 Yeah this all sounds good.

 I'm trying to unify most of the pieces of single form inputs, validation,
 mapper, record and wizard.  It's generally slow going.

Good news (about the unification :-) Let me know if there's anything I
can do to speed up the process

/Jeppe

--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@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.




Re: [Lift] Multipage wizards

2009-11-25 Thread Jeppe Nejsum Madsen
David Pollak feeder.of.the.be...@gmail.com writes:

 Folks,

 I've completed the first pass at multi-page input Wizards in Lift.  You can
 see an example at: http://demo.liftweb.net/wiz

Great news!

[...]

 The building of HTML forms from the given field type is based on the type
 (currently, there's support for String and Int, but more to come) and it's
 based on plugable functions, so you can build date pickers that are
 localized, etc.

 What needs to be done:

- The naming (including the names that the various parts of the wizard
bind to) need a good going-over
- Support for many different input types (not just Int and String)
- Feedback

I've been thinking about this for a while and haven't really reached
anything concrete yet, but it overlaps enough with the wizard stuff that
I might just throw it out here now:

I think that form handling in Lift is too cumbersome. I.e. all the
building blocks are there to create great forms, but it takes too much
boilerplate code to achieve a nice result. 

I know forms are not sexy in the ways Comet  Ajax support is, but for
many applications (ours included :-) it's where the major interactions
with the user happens, so a good UX is essential. 

Here's my (ultimate) list of things that should be easy (for the
developer) to do without too much fuzz:

- Provide field level validations - including client side if possible
- Provide form level validations - including client side
- If the form contains Mapper fields, you should not have to respecify
  the validations
- Render fields with proper markup (ie required fields should be indicated)
- When a form is in error, retain values entered by the user
- When a field is in error render it differently (ie red) with field
  specific error
- Provide field level help (inline, popup etc)
- Provide form level help
- All fields and text should support i18n (ie both labels, text and for numeric 
and e.g
  date entries)

I haven't looked closely at the wizard code yet, but it seems like it
does provide some of these benefits. Some possible ideas:

- Could be nice if the wizard code could be extended to generic
  forms. Wizards would just be a special case, with a sequence of forms
  and prev/next buttons etc.
- I would very much like to see validations lifted to a higher level so
  that the same validation rule can be used for Mapper (and Record),
  forms  wizards.
- Fields should be able to emit client side validations and code
- Maybe we could introduce generic form fields (ie Number, Date etc) and
  they could be reused by the Mapper/Record fields. In this way, they
  would all share the same presentation logic (ie i18n formatting for
  display/editing, datepickers, more advanced dialogs etc)
- Much more

Thoughts?

We'll soon be needing much of this in our app, so I'm willing to
participate in this if there's any interest.

/Jeppe

--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@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] Multipage wizards

2009-11-24 Thread David Pollak
Folks,

I've completed the first pass at multi-page input Wizards in Lift.  You can
see an example at: http://demo.liftweb.net/wiz

Wizards are declarative, type-safe mechanisms for describing multi-page
workflows.  They are stateful, isolated (you can run multiple copies of the
same wizard in the same browser at the same time), and testable independent
of a user interface.

Here's a 3 page wizard that chooses the flow based on the age entered on the
first screen:

/**
 * An example of a wizard in Lift
 */
object MyWizard extends Wizard {
  object completeInfo extends WizardVar(false)

  // define the first screen
  val nameAndAge = new Screen {

// it has a name field
val name = new Field with StringField {
  def title = S ?? First Name

  override def validation = minLen(2, S ?? Name Too Short) ::
  maxLen(40, S ?? Name Too Long) :: super.validation
}

// and an age field
val age = new Field with IntField {
  def title = S ?? Age

  override def validation = minVal(5, S ?? Too young) ::
  maxVal(120, S ?? You should be dead) :: super.validation
}

// choose the next screen based on the age
override def nextScreen = if (age.is  18) parentName else favoritePet
  }

  // We ask the parent's name if the person is under 18
  val parentName = new Screen {
val parentName = new Field with StringField {
  def title = S ?? Mom or Dad's name

  override def validation = minLen(2, S ?? Name Too Short) ::
  maxLen(40, S ?? Name Too Long) :: super.validation
}
  }

  // we ask for the favorite pet
  val favoritePet = new Screen {
val petName = new Field with StringField {
  def title = S ?? Pet's name

  override def validation = minLen(2, S ?? Name Too Short) ::
  maxLen(40, S ?? Name Too Long) :: super.validation
}
  }

  // what to do on completion of the wizard
  def finish() {
S.notice(Thank you for registering your pet)
completeInfo.set(true)
  }
}

Each field has validation (and there's per-screen validation as well).

You can write a test for this wizard that runs independently of the UI:

object WizardSpec extends Specification {
  val session: LiftSession = new LiftSession(, Helpers.randomString(20),
Empty)

  A Wizard can be defined in {
MyWizard.nameAndAge.screenName must_== Screen 1

MyWizard.favoritePet.screenName must_== Screen 3
  }

  A field must have a correct Manifest in {
MyWizard.nameAndAge.age.manifest.erasure.getName must_==
classOf[Int].getName
  }

  A wizard must transition from first screen to second screen in {
S.initIfUninitted(session) {
  MyWizard.currentScreen.open_! must_== MyWizard.nameAndAge

  MyWizard.nextScreen

  MyWizard.currentScreen.open_! must_== MyWizard.nameAndAge

  MyWizard.nameAndAge.name.set(David)
  MyWizard.nameAndAge.age.set(14)

  MyWizard.nextScreen

  MyWizard.currentScreen.open_! must_== MyWizard.parentName

  MyWizard.prevScreen

  MyWizard.currentScreen.open_! must_== MyWizard.nameAndAge

  MyWizard.nameAndAge.age.set(45)

  MyWizard.nextScreen

  MyWizard.currentScreen.open_! must_== MyWizard.favoritePet

  S.clearCurrentNotices

  MyWizard.favoritePet.petName.set(Elwood)

  MyWizard.nextScreen

  MyWizard.currentScreen must_== Empty

  MyWizard.completeInfo.is must_== true
}
  }

  A wizard must be able to snapshot itself in {
val ss = S.initIfUninitted(session) {
  MyWizard.currentScreen.open_! must_== MyWizard.nameAndAge

  MyWizard.nextScreen

  MyWizard.currentScreen.open_! must_== MyWizard.nameAndAge

  MyWizard.nameAndAge.name.set(David)
  MyWizard.nameAndAge.age.set(14)

  MyWizard.nextScreen

  MyWizard.currentScreen.open_! must_== MyWizard.parentName

  MyWizard.createSnapshot
}

S.initIfUninitted(session) {
  MyWizard.currentScreen.open_! must_== MyWizard.nameAndAge


}


S.initIfUninitted(session) {
  ss.restore()

  MyWizard.prevScreen

  MyWizard.currentScreen.open_! must_== MyWizard.nameAndAge

  MyWizard.nameAndAge.age.set(45)

  MyWizard.nextScreen

  MyWizard.currentScreen.open_! must_== MyWizard.favoritePet

  S.clearCurrentNotices

  MyWizard.favoritePet.petName.set(Elwood)

  MyWizard.nextScreen

  MyWizard.currentScreen must_== Empty

  MyWizard.completeInfo.is must_== true
}
  }
}

The building of HTML forms from the given field type is based on the type
(currently, there's support for String and Int, but more to come) and it's
based on plugable functions, so you can build date pickers that are
localized, etc.

What needs to be done:

   - The naming (including the names that the various parts of the wizard
   bind to) need a good going-over
   - Support for many different input types (not just Int and String)
   - Feedback

So, it should be off the review board in a day or two and then I'm going to
ask for folks to try it out