Если поле формы имеет несколько валидаторов, как позволить play проверять их по одному, а не все? - PullRequest
2 голосов
/ 17 марта 2012

У меня есть форма входа в систему, есть name вход имеет много валидаторов:

object Users extends Controller {

    val loginForm = Form(tuple(
        "name" -> ( 
            nonEmptyText // (1)
            verifying ("Its length should >= 4", name=>{ println("#222");name.length>=4 }) // (2)
            verifying ("It should have numbers and letters", name=>{println("#333"); ...}) // (3)
        )
}

Тогда я ничего не ввожу, нажимаю «отправить», и я нашел отпечатки консоли:

#222
#333

Это означает, что все валидаторы выполняются и имеют отношение:

(1) & (2) & (3)

Но я надеюсь, что они:

(1) && (2) && (3)

Это означает, что если имя пустое, два последних валидатора будут игнорироваться.

Возможно ли это в play2?

1 Ответ

5 голосов
/ 17 марта 2012

Поведение по умолчанию - применять все ограничения, определенные для поля. Однако вы можете определить собственное ограничение проверки, которое прекращает применение ограничений при первом сбое:

def stopOnFirstFail[T](constraints: Constraint[T]*) = Constraint { field: T =>
  constraints.toList dropWhile (_(field) == Valid) match {
    case Nil => Valid
    case constraint :: _ => constraint(field)
  }
}

Может использоваться следующим образом:

val loginForm = Form(
  "name" -> (text verifying stopOnFirstFail(
    nonEmpty,
    minLength(4)
  ))
)
scala> loginForm.bind(Map("name"->"")).errors
res2: Seq[play.api.data.FormError] = List(FormError(name,error.required,WrappedArray()))

scala> loginForm.bind(Map("name"->"foo")).errors
res3: Seq[play.api.data.FormError] = List(FormError(name,error.minLength,WrappedArray(4)))

scala> loginForm.bind(Map("name"->"foobar")).errors
res4: Seq[play.api.data.FormError] = List()

(Обратите внимание, что моя реализация stopOnFirstFail применяет два раза превышающее ограничение, поэтому у этого не должно быть побочных эффектов)

...