Field validation

13 views
Skip to first unread message

wstrange

unread,
Dec 4, 2009, 4:22:49 PM12/4/09
to Lift

I have searched the archives, but the answer is not immediately clear
to me...

How does one provide field validation feedback on a form (e.g. turn
the phone number field red if an error is made in data entry)? The
S.error approach of collecting all the errors into one big message
seems unwieldy, and does not give the user very good feedback. I am
using JPA if that makes any difference.


Any tips would be appreciated


Alex Siman

unread,
Dec 4, 2009, 7:06:29 PM12/4/09
to Lift
Checkout my code, especially parts with "cssClass".

import net.liftweb.http.S._
import net.liftweb.http.SHtml._

// input can be SHtml.text
def formField(label: String, input: Elem): NodeSeq = {
val fixedLabel = label match {
case "" => ""
case s: String => s + ":"
}

val id = (input \ "@id").toString
val messageList = messagesById(id)(errors)
val hasMessages = messageList.size > 0
val cssClass = if (hasMessages) "ErrorField" else ""
val messages = messageList match {
case list: List[NodeSeq] if hasMessages => {
<ul>{messageList.map(m => <li>{m}</li>)}</ul>
}
case _ => Nil
}

<table class={cssClass} style="width: 100%;">
<tr>
<td style="text-align: right; vertical-align: top; width: 10em;">
<b>{fixedLabel}</b>&nbsp;
</td>
<td style="text-align: left;">
{input}{messages}
</td>
</tr>
</table>

wstrange

unread,
Dec 5, 2009, 7:39:05 PM12/5/09
to Lift

Hi Alex

Thank you so much for the tip.

Just so I am clear (I am a lift newbie), I assume I would call this
function in my snippet:

bind(......
"phoneNumber" -> formField("Phone Number", user.phoneNumber)
)

Is that the idea?

wstrange

unread,
Dec 5, 2009, 8:38:01 PM12/5/09
to Lift

OK, figured it out. This should be:


bind(...
"mobilePhone" -> formField("Mobile Phone", SHtml.text
(user.mobilePhone, user.mobilePhone = _) ),

wstrange

unread,
Dec 6, 2009, 12:53:08 AM12/6/09
to Lift

After more experimenting ... I think this approach only works with
Mapper/Record? It requires a field id to be set, and validations
errors to be set on that id ( e.g. S.error("mobilePhone", "bad
phone...") )


Is there an example of how to do this using JPA and JSR 303 (aka
Hibernate Validators)?

wstrange

unread,
Dec 7, 2009, 7:20:35 PM12/7/09
to Lift

After some experimenting I have field validation working with JSR 303
annotations. See:


http://wstrange.wordpress.com/2009/12/07/inline-field-validation-in-scalalift-using-jpa-and-jsr-303/




On Dec 5, 10:53 pm, wstrange <warren.stra...@gmail.com> wrote:
> After more experimenting ... I think this approach only works with
> Mapper/Record? It requires afieldid to be set, and validations
> > > > > How does one providefieldvalidationfeedback on a form (e.g. turn
> > > > > the phone numberfieldred if an error is made in data entry)? The

Alex Siman

unread,
Dec 8, 2009, 8:35:01 AM12/8/09
to Lift
Hi!

Cool to see me there:
* @author Alex Siman

You can also set attribute "maxlength" of HTML input tag based of JPA
size anno. See http://www.w3schools.com/TAGS/att_input_maxlength.asp

Checkout full code for more ideas. You can create more generic
architecture and wrap existent JPA entities with methods for printing
entity fields to HTML:

package xxx.snippet

import scala.xml._

import net.liftweb.http._
import net.liftweb.http.S._
import net.liftweb.http.SHtml._
import net.liftweb.util.Helpers._

import xxx.model._

class AdminProduct {
// Holder to store entered values for Product between requests.
object Product extends RequestVar[Gift](new Gift())
Product.is.requestObject = Product
println("AdminProduct: Product.is.requestObject = Product")

def render(xhtml: Group): NodeSeq = {
println("--> AdminProduct.render()")

def doSubmit() = {
println("-->--> AdminProduct.doSubmit()")
// Do smth... Ex open/close JPA session
println("<--<-- AdminProduct.doSubmit()")

val valid = Product.is.validate
val product = Product.is
if (!valid) {
S.error("Form has errors.")
} else {
val msg = ("AdminProduct.doSubmit: Product saved: {" +
product.title + " @ $" + product.price + "}")
println(msg)
notice(msg)
redirectTo("/checkout/product/saved")
}
}

println("<-- AdminProduct.render()")

// Request scoped.
bind("product", xhtml,
"title" -> Product.is.titleToForm(),
"price" -> Product.is.descToForm(),
"desc" -> Product.is.priceToForm(),
"submit" -> Product.is.formField("", submit("Save", doSubmit)))
}
}

package xxx.model

import scala.xml._

import net.liftweb.http.SHtml._
import net.liftweb.http.S._
import net.liftweb.util.Helpers._
import net.liftweb.http.RequestVar
import net.liftweb.http.LiftSession._

case class Gift() {
var title = ""
var desc = ""
var price = "0.0"

val titleId = "title"
val descId = "desc"
val priceId = "price"

var requestObject: RequestVar[Gift] = null

private def getProduct() = {
requestObject.is
}

def validate(): Boolean = {
var valid = true
// TODO: Replace by JPA validators.
title match {
case "" => {
valid = false
error(titleId, "Title required.")
}
case _ =>
}
desc match {
case _ =>
}
// TODO: Price must be converted to Double/BigDecimal etc.
price match {
case "0.0" => {
valid = false
error(priceId, "Price required.")
error(priceId, "Price must be > $0.")
}
case "100.0" => {
valid = false
error(priceId, "Price must be < $100.")
}
case _ =>
}
valid
}

def formField(label: String, input: Elem): NodeSeq = {
// ... Body from prev. email.
}

def titleToForm() = {
formField("Title", text(title, getProduct().title = _, ("id",
titleId)))
}

def descToForm() = {
formField("Description", textarea(desc, getProduct().desc = _,
("id", descId)))
}

def priceToForm() = {
formField("Price", text(price, getProduct().price = _, ("id",
priceId)))
}

// TODO: Also there can be more complex method:
//def toForm() = {...}
}

On 8 дек, 02:20, wstrange <warren.stra...@gmail.com> wrote:
> After some experimenting I have field validation working with JSR 303
> annotations. See:
>
> http://wstrange.wordpress.com/2009/12/07/inline-field-validation-in-s...

Alex Siman

unread,
Dec 8, 2009, 9:11:25 AM12/8/09
to Lift
Also take a look at JPA example from Lift sources:
http://github.com/dpp/liftweb/tree/master/lift-examples/JPADemo/

On 8 дек, 02:20, wstrange <warren.stra...@gmail.com> wrote:
> After some experimenting I have field validation working with JSR 303
> annotations. See:
>
> http://wstrange.wordpress.com/2009/12/07/inline-field-validation-in-s...
Reply all
Reply to author
Forward
0 new messages