tags:

views:

81

answers:

2

Hi, there's a simple form in Lift framework and a Class with render method that handles the form:

 def render(xhtml:NodeSeq) = {
        var name = ""
        var role = ""
        var human = ""
        def register = {
            val person = new Person
            person.name = name
            person.role = role
            person.human = if (human == "yes") "true" else "false"
            model.create(person)
            S.redirectTo("/index")
        }
        bind("user",
        xhtml,
        ("name" -> SHtml.text(name, name = _)),
        ("role" -> SHtml.text(role, role = _)),
        ("human" -> SHtml.text(human,human = _)),
        ("submit" -> SHtml.submit("Register",register)))
    }

When I run this example, eg. I access the url which is binded to the according form, I get following error:

Message: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number
...
...
...
    epsilon.sjbs.CrudModel$class.create(Sjbs.scala:14)
    epsilon.sjbs.PersonModel.create(Sjbs.scala:7)
    epsilon.snippet.PersonSnippet.register$1(Snippet.scala:33)
    epsilon.snippet.PersonSnippet.render(Snippet.scala:41)

this looks like that the register method is ran even there's no click on submit, just accessing the url. Why?
EDIT:this is my original entity

@NamedQuery(name = "findAll", query = "select x from Person x")
@Entity class Person extends Id with Name{
    @OneToMany(mappedBy="person", cascade=Array(CascadeType.REMOVE))
    var participated:java.util.List[Participant] = new java.util.ArrayListParticipant
    var role:String = Role.User
    var human:String = _
}

+1  A: 

As pr1001 wrote person.human is likely to be boolean.

register is not called, but person.human is already evaluated because human string is set out of register method. You have only to change the assignment:

person.human = if (human == "yes") true else false
onof
but seriously, i've fixed the issue with CastException and now the access to the page does immediate redirect to "/index"
coubeatczech
+3  A: 

I think that Person.human is a Boolean, not a String...

It looks like you're using something that looks like Mapper. If you were using Mapper, I'd do it like so:

def render(xhtml:NodeSeq) = {
  val person = Person.create
  bind(
    "user",
    xhtml,
    "name" -> SHtml.text(person.name, person.name(_)),
    "role" -> SHtml.text(person.role, person.role(_)),
    "human" -> SHtml.text(
      if (person.human) ? "yes" else "no",
      (human) => person.human(if (human == "yes") true else false)
    ),
    "submit" -> SHtml.submit("Register", () => {
      person.save
      S.redirectTo("/index")
    })
  )
}

Just personal preference of course, but that way you're not using an explicit vars and can easily reuse it to edit an existing Person...

pr1001