
рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЖрдк рдореЗрдВ рд╕реЗ рдмрд╣реБрдд рд╕реЗ HTML рдлреЙрд░реНрдо рдмрдирд╛рдиреЗ рдФрд░ рдкреНрд░реЛрд╕реЗрд╕ рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реИрдВред рдпрд╣ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡реЗрдм рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреЗ рд▓рд┐рдП рддреБрдЪреНрдЫ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк рдХреЙрд░реНрдкреЛрд░реЗрдЯ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╕реНрдерд┐рддрд┐ рдереЛрдбрд╝реА рдЕрд▓рдЧ рд╣реИред рдХреНрд▓рд╛рдЗрдВрдЯреНрд╕, рдбреЙрдХреНрдпреВрдореЗрдВрдЯреНрд╕ рдмрдирд╛рдиреЗ рдФрд░ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд░реВрдк рдФрд░ рдмрд╣реБрдд рдХреБрдЫ рджреИрдирд┐рдХ рджрд┐рдирдЪрд░реНрдпрд╛ рдмрди рдЬрд╛рддреЗ рд╣реИрдВред рдЬрд╛рд╡рд╛ рдлреНрд░реЗрдорд╡рд░реНрдХ, рд╡рд┐рдХрд╛рд╕, рдЙрдирдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рд╕реЗ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдПрдкреАрдЖрдИ рдФрд░ рдШрдЯрдХреЛрдВ рдХреА рдкреЗрд╢рдХрд╢ рдХрд░рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдХрдИ рд▓реЛрдЧ рдЖрд╢реНрдЪрд░реНрдпрдЪрдХрд┐рдд рдереЗ рдХрд┐ рдХреНрдпрд╛ рд░реВрдкреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛрдЧрд╛ред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдореИрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдпрдерд╛рд╕рдВрднрд╡ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд░реВрдкрд░реЗрдЦрд╛ рдЪрд╛рд╣реВрдВрдЧрд╛:
- рдкреНрд░рдХрд╛рд░ рдлрд╝реАрд▓реНрдб, рдЬреИрд╕реЗ рдХрд┐ рд╢реАрд░реНрд╖рдХ, рдпрд╛ рд╡реИрдзрддрд╛ рдХреЗ рдЧреБрдгреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдирд╛
- рд╕рдмрдорд┐рдЯ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдлреЙрд░реНрдо рдбреЗрдЯрд╛;
- рд░реЗрдВрдбрд░рд┐рдВрдЧ рдлреЙрд░реНрдоред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рд╡рд╛рдВрдЫрдиреАрдп рд╣реИ рдХрд┐ рд╕рдВрдХрд▓рди рдЪрд░рдг рдореЗрдВ рдХрдИ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рд╕реНрдХрд╛рд▓рд╛ рдореЗрдВ рдЕрдкрдирд╛ рд╕реНрд╡рдпрдВ рдХрд╛ рдбреАрдПрд╕рдПрд▓ рдмрдирд╛рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реВрдВрдЧрд╛, рдФрд░ рдлрд┐рд░ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ рдХрд┐ рдкреНрд▓реЗ рдлреНрд░реЗрдорд╡рд░реНрдХ 2 рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рд░реВрдкреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХрд╛ рдирдпрд╛ рддрд░реАрдХрд╛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПред
рд╢рдмреНрджрд╛рд╡рд▓реА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ред
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рдЖрдВрддрд░рд┐рдХ DSL рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░ рд░рд╣рд╛ рд╣реВрдБред рдЖрдВрддрд░рд┐рдХ рдбреАрдПрд╕рдПрд▓ рдПрдХ рдирдИ рднрд╛рд╖рд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рд╣реЛрд╕реНрдЯ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдХреЗ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбреЛрдореЗрди рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХрд╛ рдХреЗрд╡рд▓ рдПрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рддрд░реАрдХрд╛ рд╣реИред рд╕рдЪ рд╣реИ, рдпрджрд┐ рд╣реЛрд╕реНрдЯ рднрд╛рд╖рд╛ рдХрд╛ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдкрд░реНрдпрд╛рдкреНрдд рд▓рдЪреАрд▓рд╛ рд╣реИ, рддреЛ рдЖрдВрддрд░рд┐рдХ рдбреАрдПрд╕рдПрд▓ рдРрд╕рд╛ рд▓рдЧ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХреА рдЧрдИ рдирдИ рднрд╛рд╖рд╛ рд╣реИред рдЗрд╕ рд╡рд┐рдХрд▓реНрдк рдХреЗ рдлрд╛рдпрджреЛрдВ рдореЗрдВ рдпрд╣ рддрдереНрдп рд╢рд╛рдорд┐рд▓ рд╣реИ рдХрд┐ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд╡рд╛рддрд╛рд╡рд░рдг рдЖрдВрддрд░рд┐рдХ рдбреАрдПрд╕рдПрд▓ рдХреЛ рд╕рдордЭрддреЗ рд╣реИрдВ, рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдХреЛ рдЙрдЬрд╛рдЧрд░ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рд╕реНрд╡рдд: рдкреВрд░реНрдг рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреА рдкреЗрд╢рдХрд╢ рдХрд░рддреЗ рд╣реИрдВред рддреБрд▓рдирд╛ рдХреЗ рд▓рд┐рдП, рдмрд╛рд╣рд░реА рдбреАрдПрд╕рдПрд▓ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдирдИ рднрд╛рд╖рд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкрд╛рд░реНрд╕рд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
рдЖрд▓реЗрдЦ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдбреАрдПрд╕рдПрд▓ рдореВрд▓ рд░реВрдк рд╕реЗ рдкреНрд▓реЗ рдлреНрд░реЗрдорд╡рд░реНрдХ 2 рдореЗрдВ рдлреЙрд░реНрдо рдЗрдВрдЬрди рдХреА рдХреБрдЫ рд╕реАрдорд╛рдУрдВ рдХреЗ рдХрд╛рд░рдг рдЙрддреНрдкрдиреНрди рд╣реБрдИ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд▓реЗрдХрд┐рди рдЕрдм рдпрд╣ рдкреНрд▓реЗ рд╕реЗ рд╕реНрд╡рддрдВрддреНрд░ рд╣реИ рдФрд░ рдЙрдкрдпреБрдХреНрдд рдПрдбреЗрдкреНрдЯрд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдкрд░ рдХрд┐рд╕реА рднреА рдЬреЗрд╡реАрдПрдо рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рд╕рд╛рде рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
DSL рд╡рд┐рдХрд╛рд╕ рдХрд╣рд╛рдБ рд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдВ?
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рддрдп рдХрд░реЗрдВ рдХрд┐ рдЖрдк рдкрд░рд┐рдгрд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ рдХреНрдпрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рд╣рдореЗрдВ рдЗрд╕ рд╡рд┐рд╖рдп рдкрд░ рдХрд▓реНрдкрдирд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ: "рдПрдХ рдЖрджрд░реНрд╢ рдбреАрдПрд╕рдПрд▓ рдХреЛ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреИрд╕рд╛ рджрд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП", рдереЛрдбрд╝реА рджреЗрд░ рдХреЗ рд▓рд┐рдП рднреВрд▓ рдЬрд╛рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдореЗрдЬрдмрд╛рди рднрд╛рд╖рд╛ рд╕рд┐рдВрдЯреИрдХреНрд╕ рджреНрд╡рд╛рд░рд╛ рд╕реАрдорд┐рдд рд╣реИрдВред
рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлрд╝реАрд▓реНрдб рдХреЗ рд╕рд╛рде рдкрдВрдЬреАрдХрд░рдг рдлреЙрд░реНрдо рд▓реЗрдВ:
- рдореЗрд▓ - рдкрд╛рда, рдЕрдирд┐рд╡рд╛рд░реНрдп, рдореЗрд▓рд┐рдВрдЧ рдкрддреЗ рдХреА рд╢реБрджреНрдзрддрд╛ рдХреЗ рд▓рд┐рдП рд╕рддреНрдпрд╛рдкрди;
- рдирд╛рдо - рдЖрд╡рд╢реНрдпрдХ рдкрд╛рда;
- рдЬрдиреНрдо рдХреА рддрд╛рд░реАрдЦ - рддрд╛рд░реАрдЦ, рд╡реИрдХрд▓реНрдкрд┐рдХред
рдЗрд╕рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдЫрджреНрдордХреЛрдб рдореЗрдВ рдРрд╕реА рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
form( string(email, required, validate(EmailAddress)) string(name, required) date(birthDate) )
рдЕрдм рдпрд╣ рд╕реЛрдЪрдиреЗ рдХрд╛ рд╕рдордп рд╣реИ рдХрд┐ рдЗрд╕реЗ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдкреНрд░рдкрддреНрд░ рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рд╡рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ, рдЕрд░реНрдерд╛рддреН рдлрд╝реАрд▓реНрдб рдФрд░ рдЙрдирдХреЗ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдПрдХ рд╕реЗрдЯред рд╕реНрдХрд╛рд▓рд╛ рд╣рдореЗрдВ рдРрд╕рд╛ рд╡рд┐рд╡рд░рдг рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ:
1. рдмрд┐рд▓реНрдбрд░ рдкреИрдЯрд░реНрди рдФрд░ рд╡рд┐рдзрд┐ рдЬрдВрдЬреАрд░
рдлрд╛рд░реНрдо рдХреЗ рд▓рд┐рдП рдлреИрдХреНрдЯрд░реА рд╡рд┐рдзрд┐ рд╣рд╕реНрддрд╛рдХреНрд╖рд░:
def form(builderFoo: FormBuilder => FormBuilder)
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:
form(_ .string(...) .string(...) .extend(commonFields) .date(...) )
рдпрд╣рд╛рдВ рд╣рдо
рдмрд┐рд▓реНрдбрд░ рдФрд░
рдореЗрдердб рдЪреЗрдирд┐рдВрдЧ рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕рд╕реЗ рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд▓рд╛рдн рдорд┐рд▓рддреЗ рд╣реИрдВ:
- рдЖрдк рдмрд┐рд▓реНрдбрд░ рдХреЗ рд╕рд╛рд░ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдлрд╝реЙрд░реНрдо рдХрд╛ рд╡рд┐рд╡рд░рдг рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ - рдпрд╣ рдЖрдкрдХреЛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдиреЗ рдкрд░ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ;
- рдХреЙрд▓ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдПрдХ рдЕрд▓рдЧ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдирд┐рдХрд╛рд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рд╡рд┐рднрд┐рдиреНрди рд░реВрдкреЛрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ;
- рдХрдо рд╕рд╣рд╛рдпрдХ рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ;
- рдХреНрд▓реЛрдЬрд░ рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдлреЙрд░реНрдо (...) рд╕реЗ рдЕрдиреБрдорд╛рдирд┐рдд рд╣реИред
рдЖрдЧреЗ рджреЗрдЦрддреЗ рд╣реБрдП, рдореИрдВ рдХрд╣реВрдВрдЧрд╛ рдХрд┐ рдпрд╣ рд╡рд┐рдХрд▓реНрдк рдЪреБрдирд╛ рдЧрдпрд╛ рдерд╛ ред
2. рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдПрдХ рдЪрд░ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рд╕рдорд╛рд░реЛрд╣ рдХреЗ рд░реВрдк рдореЗрдВ
рдлреИрдХреНрдЯрд░реА рд╡рд┐рдзрд┐:
def form(fields: FormBuilder => FormBuilder*)
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:
form( _.string(...), _.string(...), _.date(...), commonFields:_* )
рдЗрд╕ рд╡рд┐рдХрд▓реНрдк рдХреЗ рдХрдИ рдиреБрдХрд╕рд╛рди рд╣реИрдВ:
- рдЕрдзрд┐рдХ рд╕рд╣рд╛рдпрдХ рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛;
- рдЕрддрд┐рд░рд┐рдХреНрдд рдлрд╝реАрд▓реНрдб рдХреЛ рдХреЗрд╡рд▓ рддрд░реНрдХ рд╕реВрдЪреА рдХреЗ рдЕрдВрдд рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
3. рдХреЙрд▓ рдЕрдиреБрдХреНрд░рдо рдХреЗ рд╕рд╛рде рдХреЛрдб рдмреНрд▓реЙрдХ
рдлреИрдХреНрдЯрд░реА рд╡рд┐рдзрд┐:
def form(fields: => ())
: form{ string(...) date(...) commonFields() }
рдпрд╣ рддрд░реАрдХрд╛ рдмреБрд░рд╛ рд╣реИ:
- рдлреЙрд░реНрдо рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЗ рд╕рдордп, рд╣рдо рд╕реНрдЯреНрд░рд┐рдВрдЧ, рджрд┐рдирд╛рдВрдХ рдФрд░ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕реЗ рдмрдВрдзреЗ рд╣реИрдВред
- рдЗрд╕рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рдкрд░рд┐рд╡рд░реНрддрдирд╢реАрд▓ рд╕реНрдерд┐рддрд┐ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЬрд┐рд╕рд╕реЗ рд╣рдо рдмрдЪрдирд╛ рдЪрд╛рд╣реЗрдВрдЧреЗ;
- рдкреНрд░реЗрд╖рд┐рдд рднрд╛рд╡реЛрдВ рдХреА рдХреЛрдИ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдирд╣реАрдВ рд╣реИред
рддреЛ, рдПрдХ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рд╕реЗ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдкреНрд░рд╕рд┐рджреНрдз рдбрд┐рдЬрд╛рдЗрди рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рд╡рд┐рдХрд▓реНрдк рд╕рдмрд╕реЗ рдЙрдкрдпреБрдХреНрдд рд╣реИред рдЖрд╢реНрдЪрд░реНрдпред
рдЦреЗрддреЛрдВ рдХрд╛ рд╡рд░реНрдгрди
рдЦреЗрддреЛрдВ рдХреЗ рд╡рд┐рд╕реНрддреГрдд рд╡рд┐рд╡рд░рдг рдХреЗ рд▓рд┐рдП, рд╡рд┐рдзрд┐ рдЬрдВрдЬреАрд░ рдФрд░ рдмрд┐рд▓реНрдбрд░ рдХрд╛ рдЪрдпрди рднреА рдЙрдиреНрд╣реАрдВ рдХрд╛рд░рдгреЛрдВ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдлрд╝реАрд▓реНрдб рдкрд░рд┐рднрд╛рд╖рд╛ рд╡рд┐рдзрд┐ рд╣рд╕реНрддрд╛рдХреНрд╖рд░:
def string(fieldFoo: FieldBuilder => FieldBuilder): FormBuilder
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:
.string(_.name("email").required.validate(EmailAddress))
рдирд┐рд░реНрдорд╛рдг рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рд╕реНрдХреЗрдЪ
рд╕реНрдХреЗрд▓рд╛ рдореЗрдВ рдПрдХ рдмрд┐рд▓реНрдбрд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХреА рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд
copy
рд╡рд┐рдзрд┐ рдХреЗ рд╕рд╛рде рдПрдХ
case class
рдорд╣рд╛рди рд╣реИред рдпрд╣ рд╡рд┐рдзрд┐ рд╡рд░реНрддрдорд╛рди рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдХреЙрдкреА рдХрд░рддреА рд╣реИ, рдЖрд╡рд╢реНрдпрдХ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рддреА рд╣реИред рдПрдХ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд┐рд▓реНрдбрд░ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:
case class FieldBuilderImpl(fieldType: String, label: String, isRequired: Boolean, validators: Seq[Validator]) extends FieldBuilder { def fieldType(t: String): FieldBuilder = copy(fieldType = t) def label(l: String): FieldBuilder = copy(label = l) def required: FieldBuilder = copy(isRequired = true) def validate(vs: Validator*): FieldBuilder = copy(validators = validators ++ vs) def build: FieldDescription = ??? }
рдореБрдЦреНрдп рд░реВрдк рдкреИрд░рд╛рдореАрдЯрд░ рдЗрд╕рдХреЗ рдЦреЗрддреЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХреЗ рд▓рд┐рдП рдмрд┐рд▓реНрдбрд░ рдереЛрдбрд╝рд╛ рдЕрд▓рдЧ рджрд┐рдЦреЗрдЧрд╛:
case class FormBuilderImpl(fields: Map[String, FieldDescription]) extends FormBuilder { def field[F](name: String)(foo: FieldBuilder[F] => FieldBuilder[F]) = copy(fields = fields ++ Map(name -> foo(newFieldBuilder[F]).asInstanceOf[FieldBuilderImpl[F]].build)) def string(name: String)(foo: FieldBuilder[String] => FieldBuilder[String]) = field[String](name)(foo andThen (_.fieldType("string"))) def newFieldBuilder[F]: FieldBuilder[F] = ??? def build: FormDescription = ??? }
рдпрд╣ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рд╣рдореЗрдВ рдЕрднреА рднреА рдлрд╝реАрд▓реНрдб рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЙрд╕реА рд╕рдордп, рдпрджрд┐ рд╣рдо рдЧрд▓рддреА рд╕реЗ рдЧрд▓рдд рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕реЗ рд╕реАрд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ), рддреЛ рд╣рдо рдХреЗрд╡рд▓ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рджреМрд░рд╛рди рддреНрд░реБрдЯрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдиреЗрдВрдЧреЗред
рдкреНрд░рдкрддреНрд░ рдбреЗрдЯрд╛ рдХреА рдкреНрд░рд╕реНрддреБрддрд┐
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдлреЙрд░реНрдо рдЬрдорд╛ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╡реЗрдм рдврд╛рдВрдЪрд╛ рдЕрдиреБрд░реЛрдз рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдлреНрд░реЗрдорд╡рд░реНрдХ-рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рддрд╛ рд╣реИред рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рд╕рд╛рде рдПрдХреАрдХрд░рдг рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣рдорд╛рд░реА рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд░реВрдк рдХреЗ рдЖрдВрддрд░рд┐рдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд╛ рдкрд░рд┐рд╡рд░реНрддрди рд╣реИ (рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдкреНрд▓реЗ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ)
рдкреНрд░рдкрддреНрд░ рдбреЗрдЯрд╛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдирд╛
case class
рдХреА рдПрдХ рдорд┐рд╕рд╛рд▓ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред рд╕рдВрдХреНрд╖рд┐рдкреНрддрддрд╛ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЗрд╕реЗ "рдкреНрд░рдкрддреНрд░ рдбреЗрдЯрд╛ рдСрдмреНрдЬреЗрдХреНрдЯ" рдпрд╛ рдХреЗрд╡рд▓ "рдлрд╝реЙрд░реНрдо рдбреЗрдЯрд╛" рдХрд╣реЗрдВрдЧреЗред рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдХреЗ рдЯрд╛рдЗрдк рдХрд┐рдП рдЧрдП рдлрд╝реАрд▓реНрдб рджреНрд╡рд╛рд░рд╛ рдлреЙрд░реНрдо рдлрд╝реАрд▓реНрдб рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рд╣рдо рдлреЙрд░реНрдо рдлрд╝реАрд▓реНрдбреНрд╕ рдХреЛ рдПрдХ рдХреНрд▓реЛрдЬрд░ рд╕реЗ рдкрд╣рдЪрд╛рди рд╕рдХрддреЗ рд╣реИрдВ - рдлреЙрд░реНрдо рдбреЗрдЯрд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдЗрдЪреНрдЫрд┐рдд рдлрд╝реАрд▓реНрдб рдХреЗ
(_.someField)
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреНрд▓реЛрдЬрд░
(_.someField)
"someField"
рдирд╛рдордХ рдлреЙрд░реНрдо рдлрд╝реАрд▓реНрдб рдХреЗ рдЕрдиреБрд░реВрдк рд╣реЛрдЧрд╛ред
рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рдмрдЬрд╛рдп рдПрдХ рдХреНрд▓реЛрдЬрд░ рдкрд╛рд╕ рдХрд░рдирд╛ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд▓рд╛рдн рд╣реИ - рдпрд╣ рд╣рдореЗрдВ рдлреЙрд░реНрдо рдлрд╝реАрд▓реНрдб рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдХреНрд▓реЛрдЬрд░ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдЬрд╛рдирддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП,
UserFormData => String
рдХреЗ рдкреНрд░рдХрд╛рд░ рд╕реЗ
UserFormData => String
рд╣рдо рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдлреЙрд░реНрдо рдлрд╝реАрд▓реНрдб рдХреЗрд╡рд▓ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред
рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдлрд╝реАрд▓реНрдб рдирд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛
рд╕реНрдХрд╛рд▓рд╛ рдореЗрдВ рдлрд╝реАрд▓реНрдб рдирд╛рдо рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдо рд╕реЗ рдХрдо рджреЛ рддрд░реАрдХреЗ рд╣реИрдВ: рдкрд╣рд▓рд╛, рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдкрд╛рд░рдВрдкрд░рд┐рдХ, рджреВрд╕рд░рд╛ рдореИрдХреНрд░реЛрдЬрд╝ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ред рдкреНрд░рддрд┐рдмрд┐рдВрдм рдЗрд╕ рдмрд╛рдд рдореЗрдВ рдЕрдЪреНрдЫрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рд╕реНрдерд╛рдкрд┐рдд, рдмрд▓реНрдХрд┐ рдЕрдкреНрд░рдорд╛рдгрд┐рдд рддрдВрддреНрд░ рд╣реИ, рдЬрдмрдХрд┐ рдореИрдХреНрд░реЛрдЬрд╝ рдПрдХ рдирдИ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдкреНрд░рдпреЛрдЧ рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рдЙрдкрдпреЛрдЧ рдХреА рдХреБрдЫ рд╕реАрдорд╛рдПрдВ рд╣реИрдВред рд▓реЗрдХрд┐рди рд╡реЗ рдЖрдкрдХреЛ рд╕рдВрдХрд▓рди рдХреЗ рд╕рдордп рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдирд╛рдо рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ, рдЬреЛ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдкреНрд▓рд╕ рд╣реИред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рд╣рдо рдЦреБрдж рдХреЛ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВ (рд╣рдо рдЕрдЧрд▓реА рдмрд╛рд░ рдореИрдХреНрд░реЛрдЬрд╝ рдХреЛ рдорд┐рд▓реЗрдВрдЧреЗ)ред
рддреЛ, рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддрд░реАрдХреЗ рд╕реЗ рдПрдХ рдХреНрд╖реЗрддреНрд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ:
form[FormData](_.string( _.someField )(_.someProperty))
рдпрд╛рдиреА
_.someField
рдХреЛ рдмрдВрдж
_.someField
"someField"
рдирд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред
рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдорд╛рд░реЛрд╣ рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ:
fieldName[T:Manifest](fieldFoo: T => Any): String
рд╕рдВрдХреЗрддрди
[T:Manifest]
рдЕрд░реНрде рд╣реИ рдХрд┐ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд,
рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рд╕реВрдЪреА рдХреЛ рд╡рд┐рдзрд┐ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛, рдЬреЛ рдХрдВрдкрд╛рдЗрд▓рд░ рд╕реЗ рдореИрдирд┐рдлреЗрд╕реНрдЯ [рдЯреА] рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХ рдХреА рдЙрдореНрдореАрдж рдХрд░рддрд╛ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ JVM рдореЗрдВ
рдЯрд╛рдЗрдк рдПрд░рд╛рд╕реБрд░реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдРрд╕реА рдШрдЯрдирд╛ рдкрд░ рдХрд╛рдмреВ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдмреИрд╕рд╛рдЦреА рд╕реЗ рдЬреНрдпрд╛рджрд╛ рдХреБрдЫ рдирд╣реАрдВ рд╣реИред рдореИрдирд┐рдлрд╝реЗрд╕реНрдЯ рдХреЗ рд╕рд╛рде, рд╣рдореЗрдВ рд░рди рдЯрд╛рдЗрдо рдХреЗ рджреМрд░рд╛рди рдПрдХ
рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкреИрд░рд╛рдореАрдЯрд░ (рдЬрд╛рд╡рд╛ рдореЗрдВ рдЬреЗрдиреЗрд░рд┐рдХ рдХреНрд▓рд╛рд╕ рдХреЗ рдЯрд╛рдЗрдк рд╡реЗрд░рд┐рдПрдмрд▓ рдХрд╛ рдПрдирд╛рд▓реЙрдЧ) рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рдорд┐рд▓рддрд╛ рд╣реИред
рдкреНрд░рдХрдЯ рд╕реЗ рдПрдХ рд╡рд░реНрдЧ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдЗрд╕реЗ рдПрдХ
рдЧрддрд┐рд╢реАрд▓ рдкреНрд░реЙрдХреНрд╕реА рдкреНрд░реЙрдХреНрд╕реАрдмреЙрдЬ рд╕реЗ proxyObject
: рдПрдХ рд╡рд╕реНрддреБ рдЬреЛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рджрд┐рдП рдЧрдП рдкреНрд░рдХрд╛рд░ рдХреЛ рд╕рдВрддреБрд╖реНрдЯ рдХрд░рддреА рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдПрдХрдорд╛рддреНрд░ рдХрд╛рд░реНрдп рдкрд╣рд▓реЗ рд╡рд┐рдзрд┐ рдХреЗ рдирд╛рдо рдХреЛ рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рдирд╛ рд╣реИред рдпрджрд┐ рдХреНрд▓реЛрдЬрд░
(_: T).someField
рдХреЛ
fieldFoo: T => Any
рд░реВрдк рдореЗрдВ рдкрд╛рд╕ рдХрд┐рдпрд╛
fieldFoo: T => Any
, рддреЛ
fieldFoo(proxyObject)
рдХреЙрд▓ рдХрд░рдиреЗ рд╕реЗ рд╣рдореЗрдВ рд╕реНрдЯреНрд░рд┐рдВрдЧ
"someField"
ред рдпреЗ рдХрд╛рд░реНрд░рд╡рд╛рдИ
рд╕реНрдХрд╛рд▓рд╛-рд░рд┐рдлреНрд▓реЗрдХреНрдЯрд┐рд╡-рдЯреВрд▓реНрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рдХреА рдЧрдИред
рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
case class MyClass(fieldA: String) import FieldNameGetter._ assertTrue $[MyClass](_.fieldA) == "fieldA"
рдЕрдм рд╣рдо рдлреЙрд░реНрдо рдмрд┐рд▓реНрдбрд░ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ:
case class FormBuilderImpl[T:Manifest](fields: Map[String, FieldDescription]) extends FormBuilder[T] with FieldNameGetter { def field[F](fieldFoo: T => F)(foo: FieldBuilder[F] => FieldBuilder[F]) = copy(fields = fields ++ Map($[T](fieldFoo) -> foo(newFieldBuilder[F]).asInstanceOf[FieldBuilderImpl[F]].build)) def string(fieldFoo: T => String)(foo: FieldBuilder[String] => FieldBuilder[String]) = field[String](fieldFoo)(foo andThen (_.fieldType("string"))) ... }
рдкреНрд░рдкрддреНрд░ рдлрд╝реАрд▓реНрдб рдЖрд╡рд╢реНрдпрдХ рдФрд░ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдо рдорд╛рдорд▓реЗ рдХреА рд╢реНрд░реЗрдгреА рдореЗрдВ рдХреНрд╖реЗрддреНрд░ рдХреА рд╡реИрдХрд▓реНрдкрд┐рдХрддрд╛ рдХреА рд╕рдВрдкрддреНрддрд┐ рдХреЛ рджрд░реНрд╢рд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕реА рдХреНрд╖реЗрддреНрд░ рдХреЛ рдЯрд╛рдЗрдк рд╡рд┐рдХрд▓реНрдк рджреЗ [тАж]ред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдлреЙрд░реНрдо рдХреЗ рд▓рд┐рдП, рдПрдХ рдХреЗрд╕ рдХреНрд▓рд╛рд╕ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:
case class RegistrationFormData( name: String, surname: Option[String], email: String, birthDate: Option[Date] )
name
рдлрд╝реАрд▓реНрдб рдХрд╛ рдЧреЗрдЯреНрдЯрд░ рдкреНрд░рдХрд╛рд░ рд╣реИ
RegistrationFormData => String
, рдФрд░
surname
рдЧреЗрдЯреНрдЯрд░ рдкреНрд░рдХрд╛рд░ рд╣реИ
RegistrationFormData => Option[String]
ред рддрджрдиреБрд╕рд╛рд░, рдЦреЗрддреЛрдВ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рджреЛ рддрд░реАрдХреЗ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдПред
рдЖрд╡рд╢реНрдпрдХ рдХреЗ рд▓рд┐рдП:
(def string(fieldFoo: T => String)(foo: FieldBuilder[String] => FieldBuilder[String])
рд╡реИрдХрд▓реНрдкрд┐рдХ рдХреЗ рд▓рд┐рдП:
def stringOpt(fieldFoo: T => Option[String])(foo: FieldBuilder[String] => FieldBuilder[String])
рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдХреНрд╖реЗрддреНрд░ (рдмреВрд▓рд┐рдпрди рдХреЛ рдЫреЛрдбрд╝рдХрд░) рдХреЗ рд▓рд┐рдП, рджреЛрдиреЛрдВ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рд╣рдо
string
рд╡рд┐рдзрд┐ рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рдореЗрдВ
required
рд╕рдВрдкрддреНрддрд┐ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рддреЗ рд╣реИрдВред рдХрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдореИрдВ рдПрдХ рдХрд╛рдлреА рдХреЙрдореНрдкреИрдХреНрдЯ рдХреЛрдб рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рд░рд╣рд╛:
case class FormBuilderImpl[T: Manifest](fields: Map[String, FieldDescription]) extends FormBuilder[T] with FieldNameGetter {
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣рд╛рдВ рд╣рдо рдЯрд╛рдЗрдк рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ
fieldType
рдЯрд╛рдЗрдк рд╕рдВрдкрддреНрддрд┐ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред
DSL рд╡рд┐рд╕реНрддрд╛рд░
рдлрд┐рд▓рд╣рд╛рд▓, рд╣рдорд╛рд░реЗ
FieldBuilder
рдХреА рдорджрдж рд╕реЗ рд╣рдо рдХреЗрд╡рд▓
label
рдФрд░
required
рдЧреБрдгреЛрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИред рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рдлрд╝реАрд▓реНрдб рдЧреБрдгреЛрдВ рдХреЗ рд╕реЗрдЯ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдпрджрд┐ рдХрд╛рд░реНрдп рдХреЛ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЧреБрдгреЛрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо
рдирд┐рд╣рд┐рдд рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдФрд░
рдкрд┐рдВрдк рдорд╛рдИ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╡рд┐рдзрд┐ рдХреЛ
FieldBuilder
рдЬреЛрдбрд╝реЗрдВ:
def addProperty(key: String, value: Any): FieldBuilder[T]
рдЕрдЧрд▓рд╛, рд╣рдо рдЗрд╕рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рдВрдкреВрд░реНрдг рдлрд╝реАрд▓реНрдб рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕реЗрдЯ рдХрд░реЗрдВрдЧреЗред рд╣рдорд╛рд░реЗ рдбреАрдПрд╕рдПрд▓ рдХреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрд╕реЗ рд╕реАрдзреЗ рдПрдХреНрд╕реЗрд╕ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ, рдпреВрдЬрд░ рдПрдкреАрдЖрдИ рдлреЙрд░реНрдо рдХреЗ
рдирд┐рд╣рд┐рддрд╛рд░реНрде- рдкреНрд░рдХрд╛рд░ рдХрдиреНрд╡рд░реНрдЯрд░реНрд╕ рдмрдирд╛ рджреЗрдЧрд╛:
object FieldDslExtenders { import FieldAttributes._ implicit class StringFieldBuilderExtender(val fb: FieldBuilder[String]) extends AnyVal { def minLength(length: Int) = fb.addProperty(MinLength, length) def maxLength(length: Int) = fb.addProperty(MaxLength, length) } implicit class SeqFieldBuilderExtender[A](val fb: FieldBuilder[Seq[A]]) extends AnyVal { ... } implicit class DateFieldBuilderExtender(val fb: FieldBuilder[Date]) extends AnyVal { def format(datePattern: String) = fb.addProperty(DatePattern, datePattern) } }
рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐
рдирд┐рд╣рд┐рдд рд╡рд░реНрдЧ
AnyVal
рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ
AnyVal
ред рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рддрд╛рдХрд┐ рд░рди рдЯрд╛рдЗрдо рдкрд░ рдЗрд╕ рд░реИрдкрд░ рдХреНрд▓рд╛рд╕ рдХреА рд╡рд╕реНрддреБ рдХреЛ рддрддреНрдХрд╛рд▓ рди рд▓рдЧрд╛рдпрд╛ рдЬрд╛рдП, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рд╕реНрдереИрддрд┐рдХ рд╡рд┐рдзрд┐ рдХреЛ рд╕рд╛рдереА рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рд╕рдВрдХрд▓рдХ рджреНрд╡рд╛рд░рд╛ рдмрдирд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рд╕рдм рдХреБрдЫ рд╣рдорд╛рд░реЗ
FormBuilder
рд╕рд╛рде рдкрд░рд┐рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИ: рдЗрд╕рдХреА рдорджрдж рд╕реЗ, рдЖрдк рдЕрднреА рдХреЗ рд▓рд┐рдП рдлрд╝реАрд▓реНрдб рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдПрдХ рдмрд╣реБрдд рд╕реАрдорд┐рдд рд╕реЗрдЯ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рд╕рднреА рд╕рдмрд╕реЗ рдЖрдо рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдЬреЛрдбрд╝рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдПрдХ рдирдП рдкреНрд░рдХрд╛рд░ рдХреЗ рдлрд╝реАрд▓реНрдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдЬреЛ
FormBuilder
рдореЗрдВ рдирд╣реАрдВ рд╣реИ? рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╕рднреА рд╕рдорд╛рди
рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рд╡реЗрдВ рдХрдиреНрд╡рд░реНрдЯрд░реНрд╕ рдХреА рдорджрдж рд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдмреЗрд╕
fieldBase
рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдЙрдирдХреА рдорджрдж рд╕реЗ, рд╣рдо
FormBuilder
рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рддрд┐рдерд┐ рдХреЗ рд╕рд╛рде рдПрдХ рдлрд╝реАрд▓реНрдб рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ:
object FormDslExtensions extends FieldNameGetter { val defaultDateFormat = new SimpleDateFormat("dd.MM.yyyy").toPattern import FieldDslExtenders._ implicit class DateFormExtension[T: Manifest](val fb: FormBuilder[T]) extends AnyVal { def dateOpt(fieldFoo: T => Option[Date]) = fb.fieldBase[Date](fieldFoo)(_.format(defaultDateFormat)) _ def date(fieldFoo: T => Date) = fb.fieldBase[Date](fieldFoo)(_.required.format(defaultDateFormat)) _ } }
рдлреЙрд░реНрдо рдХрд╛ рдЖрдВрддрд░рд┐рдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡
рд╣рдорд╛рд░реЗ рдмрд┐рд▓реНрдбрд░реЛрдВ рдХреЗ рдХрд╛рдо рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╣рдореЗрдВ рдлреЙрд░реНрдордбреЗрд╕рдХреНрд░рд┐рдкреНрд╢рди рдлреЙрд░реНрдо рдХрд╛ рд╡рд┐рд╡рд░рдг рдСрдмреНрдЬреЗрдХреНрдЯ рдорд┐рд▓рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ
String -> FieldDescription
ред рдмрджрд▓реЗ рдореЗрдВ,
FieldDescription
рдореЗрдВ рдПрдХ
String -> Any
рдирдХреНрд╢рд╛ рд╣реЛрддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдо рдЙрди рдлрд╝реАрд▓реНрдбреНрд╕ рдХреЛ рдХрд┐рд╕реА рднреА рд╡рд┐рд╢реЗрд╖рддрд╛ рдкрд░ рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рдирдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИред рдлреЙрд░реНрдо рдХрд╛ рдкрд░рд┐рдгрд╛рдореА рд╡рд┐рд╡рд░рдг, рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдлреНрд░реЗрдорд╡рд░реНрдХ-рдЕрдЬреНрдЮреЗрдпрд╡рд╛рджреА рд╣реИ, рдЕрд░реНрдерд╛рддреНред рд╡рд┐рднрд┐рдиреНрди рдЪреМрдЦрдЯреЗ рдХреЗ рд╕рд╛рде рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рдиреЗ рд╡рд╛рд▓реА рд░реВрдкрд░реЗрдЦрд╛ рдХреЗ рд╕реНрд╡рд░реВрдк рдореЗрдВ рд░реВрдкрд╛рдВрддрд░рдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдЗрд╕рдХреЗ рдмрд╛рдж, рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдпрд╣ рдкреНрд▓реЗ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рд▓рд┐рдП рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдПрдХреАрдХрд░рдг рдЦреЗрд▓реЗрдВ
рдкреНрд▓реЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рддрдВрддреНрд░ рд╣реИ рдЬреЛ рдмрд╣реБрдд рдЬрдЯрд┐рд▓ рд░реВрдкреЛрдВ рдХреЗ рд▓рд┐рдП рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдирд╣реАрдВ рд╣реИред рд▓реЗрдХрд┐рди рдЗрд╕рдХреА рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕реАрдорд╛рдПрдБ рд╣реИрдВ:
- 18 рдХреНрд╖реЗрддреНрд░реЛрдВ рдореЗрдВ рдкреНрд░рддрд┐рдмрдВрдз;
- рдХреЗрд╡рд▓ рдлрд╝реАрд▓реНрдб рдФрд░ рд╕рддреНрдпрд╛рдкрди рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛;
- рдПрдХрд╛рдзрд┐рдХ рдкрд╕рдВрдж рдлрд╝реАрд▓реНрдб рдХреА рдХрдореА (рд▓реЗрдЦрди рдХреЗ рд╕рдордп, рдЬрд▓реНрдж рд╣реА рдЙрдкрд▓рдмреНрдз рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП)ред
рдлрд╝реЙрд░реНрдо рд╕рдмрдорд┐рдЯ рдХрд░рддреЗ рд╕рдордп, Play рдПрдХ HTTP рдЕрдиреБрд░реЛрдз рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ, рдЗрд╕реЗ deserializes рдФрд░
Map[String, Seq[String]]
рд░реВрдк рдореЗрдВ рдЕрдиреБрд░реЛрдз рдкреИрд░рд╛рдореАрдЯрд░ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИред рддрдм рдЙрдиреНрд╣реЗрдВ рдорд╛рдиреНрдп рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдХрд╕реНрдЯрдо рдХреЛрдб рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдпреБрдХреНрдд рджреГрд╢реНрдп рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдкреНрд▓реЗ рдЯреВрд▓ рдЖрдкрдХреЛ рдЗрд╕ рдбреЗрдЯрд╛ рдХреЛ рдЯрдкрд▓ рдореЗрдВ рдпрд╛ рдПрдХ рдордирдорд╛рдиреА рд╡рд╕реНрддреБ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ - рдЗрд╕рдХреЗ рд▓рд┐рдП, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЖрдкрдХреЛ рдЗрд╕реЗ рдмрдирд╛рдиреЗ рдХрд╛ рдХрд╛рд░реНрдп рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдпрджрд┐ рдкреНрд░рдкрддреНрд░ рдореЗрдВ рдкрд░реНрдпрд╛рдкреНрдд рдлрд╝реАрд▓реНрдб рд╣реИрдВ, рддреЛ рдЗрд╕рд╕реЗ рд╕рдВрднрд╛рд╡рд┐рдд рддреНрд░реБрдЯрд┐-рд╕рдореГрджреНрдз рдХреЛрдб рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ: рдЖрдкрдХреЛ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ 18 рдлрд╝рдВрдХреНрд╢рди рддрд░реНрдХ рд╕рд╣реА рдХреНрд░рдо рдореЗрдВ рд╣реИрдВред
рдХрдЪреНрдЪреЗ рдбреЗрдЯрд╛ рдХреЛ рдорд╛рдиреНрдп рдФрд░ рд░реВрдкрд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкреНрд▓реЗ
рдореИрдкрд┐рдВрдЧ рдХреНрд▓рд╛рд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред
рдкреНрд▓реЗ рдореЗрдВ рдирд┐рд░реНрдорд┐рдд рдкреНрд░рдкрддреНрд░реЛрдВ рдХреА рдореИрдкрд┐рдВрдЧ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рддрд░реНрдХреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдлрд╝реАрд▓реНрдбреНрд╕ рдХреЗ рдореИрдк рдореИрдкрд┐рдВрдЧ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреА рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:
ObjectMapping9 ), рдЗрд╕рд▓рд┐рдП рдПрдХ рдлреЙрд░реНрдо рдореЗрдВ рдЗрд╕рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЗ рд╕рдордп рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдлрд╝реАрд▓реНрдб рдХрд╛ рдХреЗрд╡рд▓ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╕реЗрдЯ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╣рдорд╛рд░реА рдХрдХреНрд╖рд╛, рдЬрд┐рд╕реЗ рд╣рдо
рдлреЙрд░реНрдордореИрдкрд┐рдВрдЧ рдХрд╣реЗрдВрдЧреЗ , рдПрдХ рдЕрдирд┐рдпрдВрддреНрд░рд┐рдд рдХреНрд╖реЗрддреНрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддреА рд╣реИред рджреВрд╕рд░реА рдУрд░, рдЗрд╕реЗ рдкрд╛рд╕ рдХрд┐рдП рдЧрдП рдлрд╝реАрд▓реНрдб рдЯрд╛рдЗрдкрд┐рдВрдЧ рдЦреЛ рджреЗрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдбрд░рд╛рд╡рдирд╛ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐
FormMapping
рдЙрджреНрджреЗрд╢реНрдп рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдлрд╝реАрд▓реНрдб рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдирд╣реАрдВ рд╣реИред рдлрд╝реАрд▓реНрдбреНрд╕ рдХреА рдЯрд╛рдЗрдкрд┐рдВрдЧ рдбреАрдПрд╕рдПрд▓ рджреНрд╡рд╛рд░рд╛ рдЧрд╛рд░рдВрдЯреАрдХреГрдд рд╣реИ, рдФрд░ рдлреЙрд░реНрдо рдбреЗрдЯрд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рдФрд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд рдореЗрдВ рд░реВрдкрд╛рдВрддрд░рдг рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд╣реИред
рдкреНрд▓реЗ рдкрд░ рдлреЙрд░реНрдо рдХреЗрд╕ рдХреНрд▓рд╛рд╕
play.api.data.Form рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ
рджрд░реНрд╢рд╛рдП рдЬрд╛рддреЗ рд╣реИрдВ , рдФрд░ рдлрд╝реАрд▓реНрдб
play.api.data.Field рд╣реИрдВ ред
рдкреНрд░рдкрддреНрд░реЛрдВ рдФрд░
рдХреНрд╖реЗрддреНрд░реЛрдВ рдХрд╛ рд╣рдорд╛рд░рд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЗрди рд╡рд░реНрдЧреЛрдВ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рд╣реЛрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рд╣рдореЗрдВ рдкреБрд░рд╛рдиреЗ рдПрдкреАрдЖрдИ рдХреЗ рд╕рд╛рде рд╕рдВрдЧрддрддрд╛ рд╣рд╛рд╕рд┐рд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдПрдХ рдирдпрд╛
attributes
рдлрд╝реАрд▓реНрдб рдкреНрд░рдкрддреНрд░ рдлрд╝реАрд▓реНрдб рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛ - рдЗрд╕рдХреА рд╕рд╣рд╛рдпрддрд╛ рд╕реЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреИрд░рд╛рдореАрдЯрд░ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдП рдЬрд╛рдПрдВрдЧреЗред
рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ
рдЖрдХрд╛рд░ рдкрд░рд┐рднрд╛рд╖рд╛:
PlayFormFactory.form[FormData](_.string(_.name)(_.label("").someAttribute(42))
рдлреЙрд░реНрдо рдХреЗ рд╕рд╛рде рдЯреЗрдореНрдкреНрд▓реЗрдЯ:
@(form: com.naumen.scala.forms.play.ExtendedForm[RegistrationFormData]) <div> .... @myComponent(form(_.name)) .... </div>
MyComponent рдШрдЯрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ:
@(customField: com.naumen.scala.forms.play.ExtendedField) <div> .... @customField.ext.attrs("someAttribute") .... </div>
рдкреНрд░рдкрддреНрд░ рдХрд╛ рдирд┐рд░реНрдзрд╛рд░рдг рдХрд░рдиреЗ рдХреЗ рдЪрд░рдг рдореЗрдВ рдордирдорд╛рдирд╛ рдХреНрд╖реЗрддреНрд░ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдЖрдкрдХреЛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рд▓реЗрдЖрдЙрдЯ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рдиреЗ рдФрд░ рдЧреИрд░-рд▓реЗрдЖрдЙрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдирд┐рдпрдВрддреНрд░рдХ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред