[playframework 2 필기 정리] 4, form

12051 단어 playframework
본문 은 다음 과 같다.http://fair-jm.iteye.com/  절 개 를 바 꾸 어 출처 를 밝 혀 주 십시오.
 
오 랜 만 에 업 데 이 트 를... 그냥 게 을 러 서...
 
play.api.data.Form
컨트롤 러 에서 사용: 실체 만 들 기:
case class User(username: String,realname: Option[String],email: String)

 
폼 개체 만 들 기
val userForm = Form(
 mapping(  //      
  "username" -> nonEmptyText(8),
  "realname" -> optional(text),
  "email" -> email)(User.apply)(User.unapply))

def createUser() = Action { implicit request =>
 userForm.bindFromRequest.fold(
  formWithErrors => BadRequest, //              Form     getErrors    
  user => Ok("User OK!"))       //              User  
}

 
fold 의 반환 값 은 play. api. mvc. Simple Result 로 BadRequest 와 Ok 의 조상 입 니 다.
표 의 Mapping 은 binding (바 인 딩) 과 unbinding 작업 을 하여 데 이 터 를 Form 에 넣 는 것 을 바 인 딩 Forms 라 고 부 르 는 변 함 없 는 binding 을 한 후에 새로운 복사 본 을 되 돌려 줍 니 다.
하나의 mapping 은 Mapping [T] 대상 이상 의 코드 중 Forms. nonEmptyText 에서 Mapping [String] email 을 만 들 었 습 니 다. Mapping [String] 더 많은 Forms. number 는 Mapping [Int] 더 많은 것 을 만 들 었 습 니 다.
■boolean:       Mapping[Boolean]
■ checked(msg:  String):    Mapping[Boolean]
■ date:       Mapping[Date]
■ email:       Mapping[String]
■ ignored[A](value:  A):     Mapping[A]
■ longNumber:      Mapping[Long]
■ nonEmptyText:      Mapping[String]
■ number:       Mapping[Int]
■ sqlDate:       Mapping[java.sql.Date]
■ text:       Mapping[String]
 
 
form helper:
name 과 mapping 의 대응 을 수 동 으로 쓸 수 있 었 으 면 좋 겠 습 니 다. form 의 값 을 가 져 오 려 면 data 속성 을 사용 하면 됩 니 다. data 는 Map 대상 이 고 helper 를 빌 릴 수 있 습 니 다.
 
@(productForm: Form[Product])
@main("Product Form") {
 @helper.form(action = routes.GeneratedForm.create) {
  @helper.inputText(productForm("name"))
  @helper.textarea(productForm("description"))
  @helper.inputText(productForm("ean"))
  @helper.inputText(productForm("pieces"))
  @helper.checkbox(productForm("active"))
  <div class="form-actions">
   <button type="submit">Create Product</button>
  </div>
 }
}

 
html 가 자동 으로 생 성 됩 니 다. 알림 정 보 를 사용자 정의 하려 면 trait Constraints Scaladoc 를 보십시오.
helper 의 input: ■ input Date   —Generates an input  tag with type date.■ inputPassword  —Generates an  input  tag with type password .■ inputFile   —Generates an input  tag with type file.■ inputText   —Generates an input  tag with type text.■ select   —Generates a select tag.■ inputRadioGroup  —Generates a set of input  tags with type  radio .■ checkbox    —Generates an  input  tag with type checkbox .■ textarea    —Generates a textarea  element.■ input    —Creates a custom input. 사용자 정의 속성 을 추가 할 수 있 습 니 다.
@helper.inputText(productForm("name"), '_class -> "important",
'size -> 40)

'size 와'class 는 symbol 형식의 더 많은 속성 입 니 다: ■label —Use to set a custom label■ _id   —Use to set the id attribute of the dl element■ _class —Use to set the class attribute of the dl element■ _help  —Use to show custom help text■ _showConstraints —Set to false to hide the constraints on this field■ _error   —Set to a Some[FormError]  instance to show a custom error■ _showErrors  —Set to false to hide the errors on this field
사용자 정의 입력:
@helper.input(myForm("mydatetime")) { (id, name, value, args) =>
 <input type="datetime" name="@name"
 id="@id" value="@value" @toHtmlArgs(args)>
}

 
두 번 째 매개 변 수 는 함수 매개 변 수 를 받 아들 이 는 것 입 니 다. (String, String, Option [String], Map [Symbol, Any]) (toHtmlArgs 는 play. api. templates. PlayMagic)
사용자 정의 html 생 성: views. helper 에서 (다른 가방 일 수도 있 고 views 아래 에서 편리 하 게) 만 들 수 있 습 니 다.
myFileConstructor. scala. html 사용자 정의 html 쓰기:
@(elements: helper.FieldElements)
<div id="@(elements.id)_field" class="clearfix @if(elements.hasErrors) {text-error}">
    <label for="name">@elements.label</label>
    <div class="input">
       @elements.input
        <span class="help-inline">@elements.errors.mkString(", ")</span>
    </div>
</div>

  첫 번 째 매개 변 수 는 helper. FieldElements 입 니 다. 잊 지 말고 object 를 만 듭 니 다.
package views.html.helper
object myHelper {
  implicit val fieldConstructor = new FieldConstructor {
    def apply(elements: FieldElements) =
      myFileConstructor(elements)
  }
}

  마지막 으로 필요 한 html 에서 가 져 오 면 됩 니 다: @ import helper. my Helper.원래 하 나 는 트 위 터: import helper. twitter Bootstrap. *
 
사용자 정의 제약 조건
Mapping [T] 에 대한 제약 을 추가 하려 면 verifying (constraints: Constraint [T *) 방법 (play. api. data. vaidation. constraints) 을 사용 할 수 있 습 니 다. "name" - > text. verifying (Constraints. nonEmpty) 사용자 정의 제약 은 verifying 으로 실현 하 는 것 도 간단 합 니 다. 안쪽 으로 T = > Boolean 방법 을 전달 하면 됩 니 다. 예 를 들 어 def eanExists (ean: Long) = Product. findByEan (ean). isEmpty 는 mapping 에서 "ean" - > longNumber. verifying (eanExists () 또는 약자: "ean" - > longNumber. verifying (Product. findByEan (). isEmpty) 도 오류 정 보 를 첫 번 째 매개 변수 로 가 져 올 수 있 습 니 다. "ean" - > longNumber. verifying ("This product already exists.", Product. findByEan (). isEmpty)
 
여러 필드 검증:
mapping 이 얻 은 것 도 Mapping [T] 이기 때문에 쓰기 가 간단 합 니 다.
val productForm = Form(mapping(
 "ean" -> longNumber.verifying("This product already exists!",Product.findByEan(_).isEmpty),
 "name" -> nonEmptyText,
 "description" -> text,
 "pieces" -> number,
 "active" -> boolean)(Product.apply)(Product.unapply).verifying(
 "Product can not be active if the description is empty",
 product =>
  !product.active || product.description.nonEmpty))

 
질문 이 적 혀 있 습 니 다. 오류 메 시 지 는 자동 으로 생 성 되 지 않 습 니 다. 맨 위 에 있 는 Mapping 은 html 에 id 가 없 기 때문에 맨 위 에 있 는 Mapping 을 수 동 으로 생 성 하 는 오류 가 Form 에서 globalError 입 니 다.
@productForm.globalError.map { error =>
 <span class="error">@error.message</span>
}

 
 
option 선택 가능:
case class Person(name: String, age: Option[Int])
val personMapping = mapping(
 "name" -> nonEmptyText,
 "age" -> optional(number) // optional   Mapping[Option[T]]
)(Person.apply)(Person.unapply)

 
list:
tags 가 List 라면 "tags" - > list (text) 라 고 쓸 수 있 습 니 다. Mapping [List [T]] 로 돌아 갑 니 다. 수 동 으로 쓰 면 < input type = "text" name = "tags [0]" > < input type = "text" name = "tags [1]" > input type = "text" name = "tags [2]" > helper 를 사용 하면 repeat 방법 으로 쓸 수 있 습 니 다.
@helper.repeat(form("tags"), min = 3) { tagField =>
 @helper.inputText(tagField, '_label -> "Tag")
}

tuple and mapping methods take a maximum of  18  parameters.
끼 워 넣 기:
val appointmentMapping = tuple(
 "location" -> text,
 "start" -> tuple(
 "date" -> date,
 "time" -> text),
 "attendees" -> list(mapping(
 "name" -> text,
 "email" -> email)(Person.apply)(Person.unapply))
)

 
돌아 온 것 은: Mapping [(String, (Date, String), List [Person]]] 입 니 다.
 
사용자 정의 매 핑
tuple (tuples 로 돌아 가기) 과 mapping (대상 으로 돌아 가기) 을 제외 하고 사용자 정의: 기 존 (transform) 을 바 꾸 고 새 것 을 만 듭 니 다.
변환 후 처리 와 유사: 만약 에 Mapping [A] 도 있 고 A = > B 도 있다 면 transform 으로 Mapping [B] 을 얻 을 수 있 습 니 다.
 val localDateMapping = text.transform(
 (dateString: String) =>
  LocalDate.parse(dateString),
 (localDate: LocalDate) =>
  localDate.toString)

  근 데 이렇게 되면 파 르 스 가 이상 을 던 질 수 있 으 니까 주의해 야 돼 요.
formatter play. api. data. format. formatter 를 새로 만 드 는 방법:
trait Formatter[T] {
 def bind(key: String, data: Map[String, String]):Either[Seq[FormError], T]
 
 def unbind(key: String, value: T): Map[String, String]
 
 val format: Option[(String, Seq[Any])] = None
}
implicit val localDateFormatter = new Formatter[LocalDate] {
 def bind(key: String, data: Map[String, String]) =
  data.get(key) map { value =>
  Try {
   Right(LocalDate.parse(value))
  } getOrElse Left(Seq(FormError(key, "error.date", Nil)))
 } getOrElse Left(Seq(FormError(key, "error.required", Nil)))
 def unbind(key: String, ld: LocalDate) = Map(key -> ld.toString)
 override val format = Some(("date.format", Nil))
}

 
또한 messages 에 date. format = Date (YYYY - MM - DD) error. date = Date formatted as YYYY - MM - DD expected 를 추가 하여 Forms. of 로 Mapping [T] 로 전환 시 킵 니 다. val localDateMapping = Forms. of (localDateFormatter) 는 Mapping [LocalDate] 를 받 았 습 니 다. of 의 매개 변 수 는 implict 이기 때문에 localDateFormatter 는 implicit 라 고 쓰 여 있 습 니 다. val localDateMapping = Forms. of[LocalDate] 마지막 에 사용 하면 Form 을 획득 할 수 있 습 니 다: val localDateForm = Form (single (single) "introductionDate" - > localDateMapping) single 과 tuple 이 같은 인자 라면 사용 할 수 있 습 니 다.
 
파일 업로드:
단일 파일 업로드 라면: 수 동 form 형식:
<form action="@routes.FileUpload.upload" method="post" enctype="multipart/form-data">
 <input type="file" name="image">
 <input type="submit">
</form>

  Action 의 처리:
def upload() = Action(parse.multipartFormData) { request =>
 request.body.file("image").map { file =>
  file.ref.moveTo(new File("/tmp/image"))
  Ok("Retrieved file %s" format file.filename)
 }.getOrElse(BadRequest("File missing!"))
}

 
 
 
form 과 함께 하 는 동작:
def upload() = Action(parse.multipartFormData) { implicit request =>
 val form = Form(tuple(
  "description" -> text,
  //  FilePart            ignored 
  "image" -> ignored(request.body.file("image")).verifying("File missing", _.isDefined)) 
  )
  
 form.bindFromRequest.fold(
 formWithErrors => {
  Ok(views.html.fileupload.uploadform(formWithErrors))
 },value => Ok)
}

  그래서 이 Form 은 Form [(String, Option [play. api. mvc. MultipartFormData. FilePart [play. api. libs. Files. Temporary File]]]]] 이 되 었 습 니 다. helper 를 사용 하면:
@(form:Form[_])
@helper.form(action = routes.FileUpload.upload,'enctype -> "multipart/form-data") {
 @helper.inputText(form("description"))
 @helper.inputFile(form("image"))
}

  근 데 이렇게 하면 upload 에 있 는 form 으로 빈 페이지 에 전달 할 수 없어 요. 왜냐하면 실현 에 request 를 사 용 했 기 때 문 이에 요.
def showUploadForm() = Action {
 val dummyForm = Form(ignored("dummy"))
 Ok(views.html.fileupload.uploadform(dummyForm))
}

아무것도 안 하 는 표 로 할 수 있어 요.
 
form 의 내용 이 많은 것 같 아 요. 그 이상 의 노트 는 이해 하기 어 려 운 부분 이 있 을 수 있어 요. 본인 이 많이 해 봐 야 될 것 같 아 요. form 을 처음 배 울 때 도 오래 걸 렸 어 요. 

좋은 웹페이지 즐겨찾기