By Alvin Alexander. Last updated: April 10, 2018
Just some quick notes on Play Framework (v2.3) controller form field mappings today ... I’ll add more here if/when I have time, but right now this is a reference page for my Cato CRUD Generator application.
1) The ResearchLink
form from my “Finance” application:
// code from my ResearchLinks controller // note: skipping `id` field // note: skipping `datetime` field val researchLinkForm: Form[ResearchLink] = Form( mapping( "symbol" -> nonEmptyText, "url" -> nonEmptyText, "notes" -> optional(text) ) // researchLinkForm -> ResearchLink ((symbol, url, notes) => ResearchLink(0, symbol, url, Calendar.getInstance.getTime, notes)) // ResearchLink -> researchLinkForm ((rl: ResearchLink) => Some(rl.symbol, rl.url, rl.notes)) )
2) My Stock
form from the same application (from the Stocks
controller):
val stockForm: Form[Stock] = Form( // defines a mapping that will handle Stock values. // the names you use in this mapping (such as 'companyName') must match the names that will be // POSTed to your methods in JSON. mapping( // verifying here creates a field-level error. // if your test returns false, the error is shown. "symbol" -> nonEmptyText.verifying("Doh - Stock already exists (1)!", Stock.findBySymbol(_) == 0), "companyName" -> nonEmptyText) ((symbol, companyName) => Stock(0, symbol, companyName)) ((s: Stock) => Some((s.symbol, s.companyName))) // verifying("Doh - Stock already exists (2)!", fields => fields match { // // this block creates a 'form' error // // this only gets called if all field validations are okay // case Stock(id, symbol, company) => Stock.findBySymbol(symbol) == 0 // }) )
3) My transactionForm
from the same application:
val transactionForm: Form[Transaction] = Form( // the names you use in this mapping (such as 'symbol') must match the names that will be // POSTed to your methods in JSON. // note: skipping `id` field // note: skipping `datetime` field mapping( // verifying here creates a field-level error; if your test returns false, the error is shown "symbol" -> nonEmptyText, "ttype" -> nonEmptyText, "price" -> bigDecimal, "quantity" -> number, "notes" -> text ) // transactionForm -> Transaction ((symbol, ttype, price, quantity, notes) => Transaction(0, symbol, ttype, price, quantity, Calendar.getInstance.getTime, notes)) // Transaction -> TransactionForm ((t: Transaction) => Some(t.symbol, t.ttype, t.price.toDouble, t.quantity, t.notes)) )
4) A Notes
form from a different application:
object Notes extends Controller with Secured { val noteForm: Form[Note] = Form( mapping( "id" -> longNumber, "title" -> text, "note" -> text, "sortOrder" -> longNumber )((id, title, note, sortOrder) => Note(id, title, note, 1, currentDate, currentDate)) // from Form to Note (add process) ((note: Note) => Some(note.id, note.title, note.note, note.sortOrder)) // from Note to Form (edit process) ) // more controller code here ...
5) And finally a Urls
Play form mapping from a different application:
object Urls extends Controller with Secured { /** * Problems: * * - don't need to see 'id' * - don't need/want to see 'user_id' * - 'shortUrl' really can be empty * - don't need to see 'created' * - 'clicks' isn't needed on an input form, just output */ val urlForm = Form( tuple( "id" -> longNumber, "url" -> nonEmptyText, "shortUrl" -> text, "note" -> optional(text) ) verifying ("Short URL is already in the database", result => result match { // TODO this works, but it could be more clear case (id, url, shortUrl, note) => { val uriIsAlreadyInDb = Url.uriIsInDatabase(shortUrl) !uriIsAlreadyInDb } }) ) def list = IsAuthenticated { username => implicit request => val urls = Url.findAll() Ok(html.urls.list(urls, urlForm)) } def listDetails(shortUri: String) = IsAuthenticated { username => implicit request => val details = BrowserHeaders.findAll(shortUri) Ok(html.urls.listUrlHits(details)) }
Other form mapping information
I’ll describe this more when I have more time, but I also have these notes on creating Play Framework form field mappings:
//-------------------------------------- // OTHER PLAY FRAMEWORK EXAMPLES & TYPES //-------------------------------------- "date" -> optional(date("yyyy-MM-dd")), // java.util.Date "date" -> date("yyyy-MM-dd"), // java.util.Date "username" -> nonEmptyText, "username" -> nonEmptyText(6), // requires a minimum of six characters "notes" -> text, "password" -> text(minLength = 10), "count" -> number, "addToMailingList" -> boolean, "email" -> email, "company" -> optional(text), "numberOfShares" -> optional(number), "stocks" -> list(text), "emailAddresses" -> list(email), "id" -> ignored(1234), boolean checked date email ignored list longNumber nonEmptyText number optional seq single sqlDate text
That’s all for today, gotta run.