@@ -5,32 +5,47 @@ import org.apache.log4j.Logger
5
5
import kara.internal.*
6
6
import kara.InputType.*
7
7
8
- /* *
9
- * Allows forms to be built based on a model object.
10
- */
11
- class FormBuilder (val model : Any , val modelName : String = model.javaClass.getSimpleName().toLowerCase(), val formId : String = " form-${modelName} " ) : FORM() {
8
+ public trait FormModel <P > {
9
+ fun modelName (): String
10
+ fun propertyValue (property : P ): String
11
+ fun propertyName (property : P ): String
12
+ }
13
+
14
+ class BeanFormModel (val model : Any ) : FormModel<String> {
15
+ val modelName = model.javaClass.getSimpleName().toLowerCase()
12
16
13
- {
14
- id = formId
17
+ override fun modelName (): String {
18
+ return modelName
15
19
}
16
20
17
- val logger = Logger .getLogger(this .javaClass)!!
21
+ override fun propertyValue (property : String ): String {
22
+ return model.propertyValue(property).toString() // TODO: Use provided parameter serialization instead of toString
23
+ }
18
24
19
- val modelClass = model.javaClass
25
+ override fun propertyName (property : String ): String {
26
+ return property
27
+ }
28
+ }
29
+
30
+ /* *
31
+ * Allows forms to be built based on a model object.
32
+ */
33
+ class FormBuilder <P >(val model : FormModel <P >) : FORM() {
34
+ val logger = Logger .getLogger(this .javaClass)!!
20
35
21
36
/* * If true, the form will have enctype="multipart/form-data" */
22
37
var hasFiles : Boolean = false
23
38
24
- fun propertyValue (property : String ) : Any? {
39
+ fun propertyValue (property : P ) : String {
25
40
return model.propertyValue(property)
26
41
}
27
42
28
- fun propertyName (property : String ) : String {
29
- return " ${modelName} [${property} ]"
43
+ fun propertyName (property : P ) : String {
44
+ return " ${model. modelName() } [${model.propertyName( property) } ]"
30
45
}
31
46
32
- fun propertyId (property : String ) : String {
33
- return " form-${modelName} -${property} "
47
+ fun propertyId (property : P ) : String {
48
+ return " form-${model. modelName() } -${model.propertyName( property) } "
34
49
}
35
50
36
51
/* *
@@ -51,35 +66,30 @@ class FormBuilder(val model : Any, val modelName : String = model.javaClass.getS
51
66
*
52
67
* @param text the text to use for the label (defaults to the property name)
53
68
*/
54
- public fun labelFor (property : String , text : String? = null, classes : StyleClass ? = null) {
69
+ public fun labelFor (property : P , text : String? = null, classes : StyleClass ? = null) {
55
70
currentTag.label(
56
- text = text ? : property.decamel().capitalize(),
57
71
forId= propertyId(property),
58
- c= classes)
72
+ c= classes) {
73
+ + (text ? : model.propertyName(property).decamel().capitalize())
74
+ }
59
75
}
60
76
61
77
/* *
62
78
* Creates an input of the given type for the given property.
63
79
* This method should not generally be used, as all valid input types are mapped to their own methods.
64
80
* It may be convenient, however, if you're trying to assign the input type programmatically.
65
81
*/
66
- public fun inputFor (inputType : InputType , property : String , init : INPUT .() -> Unit = {}) {
82
+ public fun inputFor (inputType : InputType , property : P , init : INPUT .() -> Unit = {}) {
67
83
val value = propertyValue(property)
68
- var valueString = " "
69
- if (value != null )
70
- valueString = value.toString()
71
- currentTag.input(inputType= inputType, id= propertyId(property), name= propertyName(property), value= valueString, init = init )
84
+ currentTag.input(inputType= inputType, id= propertyId(property), name= propertyName(property), value= value, init = init )
72
85
}
73
86
74
87
/* *
75
88
* Creates a textarea for the given property.
76
89
*/
77
- public fun textAreaFor (property : String , init : TEXTAREA .() -> Unit = {}) {
90
+ public fun textAreaFor (property : P , init : TEXTAREA .() -> Unit = {}) {
78
91
val value = propertyValue(property)
79
- var valueString = " "
80
- if (value != null )
81
- valueString = value.toString()
82
- currentTag.textarea(id= propertyId(property), name= propertyName(property), text= valueString, init = init )
92
+ currentTag.textarea(id= propertyId(property), name= propertyName(property), text= value, init = init )
83
93
}
84
94
85
95
/* *
@@ -92,105 +102,105 @@ class FormBuilder(val model : Any, val modelName : String = model.javaClass.getS
92
102
/* *
93
103
* Creates an input of type text for the given property.
94
104
*/
95
- public fun textFieldFor (property : String , init : INPUT .() -> Unit = {}) {
105
+ public fun textFieldFor (property : P , init : INPUT .() -> Unit = {}) {
96
106
inputFor(InputType .text, property, init )
97
107
}
98
108
99
109
/* *
100
110
* Creates an input of type password for the given property.
101
111
*/
102
- public fun passwordFieldFor (property : String , init : INPUT .() -> Unit = {}) {
112
+ public fun passwordFieldFor (property : P , init : INPUT .() -> Unit = {}) {
103
113
inputFor(InputType .password, property, init )
104
114
}
105
115
106
116
/* *
107
117
* Creates an input of type email for the given property.
108
118
*/
109
- public fun emailFieldFor (property : String , init : INPUT .() -> Unit = {}) {
119
+ public fun emailFieldFor (property : P , init : INPUT .() -> Unit = {}) {
110
120
inputFor(InputType .email, property, init )
111
121
}
112
122
113
123
/* *
114
124
* Creates an input of type tel for the given property.
115
125
*/
116
- public fun telFieldFor (property : String , init : INPUT .() -> Unit = {}) {
126
+ public fun telFieldFor (property : P , init : INPUT .() -> Unit = {}) {
117
127
inputFor(InputType .tel, property, init )
118
128
}
119
129
120
130
/* *
121
131
* Creates an input of type date for the given property.
122
132
*/
123
- public fun dateFieldFor (property : String , init : INPUT .() -> Unit = {}) {
133
+ public fun dateFieldFor (property : P , init : INPUT .() -> Unit = {}) {
124
134
inputFor(InputType .date, property, init )
125
135
}
126
136
127
137
/* *
128
138
* Creates an input of type datetime for the given property.
129
139
*/
130
- public fun dateTimeFieldFor (property : String , init : INPUT .() -> Unit = {}) {
140
+ public fun dateTimeFieldFor (property : P , init : INPUT .() -> Unit = {}) {
131
141
inputFor(InputType .datetime, property, init )
132
142
}
133
143
134
144
/* *
135
145
* Creates an input of type color for the given property.
136
146
*/
137
- public fun colorFieldFor (property : String , init : INPUT .() -> Unit = {}) {
147
+ public fun colorFieldFor (property : P , init : INPUT .() -> Unit = {}) {
138
148
inputFor(InputType .color, property, init )
139
149
}
140
150
141
151
/* *
142
152
* Creates an input of type number for the given property.
143
153
*/
144
- public fun numberFieldFor (property : String , init : INPUT .() -> Unit = {}) {
154
+ public fun numberFieldFor (property : P , init : INPUT .() -> Unit = {}) {
145
155
inputFor(InputType .number, property, init )
146
156
}
147
157
148
158
/* *
149
159
* Creates an input of type month for the given property.
150
160
*/
151
- public fun monthFieldFor (property : String , init : INPUT .() -> Unit = {}) {
161
+ public fun monthFieldFor (property : P , init : INPUT .() -> Unit = {}) {
152
162
inputFor(month, property, init )
153
163
}
154
164
155
165
/* *
156
166
* Creates an input of type range for the given property.
157
167
*/
158
- public fun rangeFieldFor (property : String , init : INPUT .() -> Unit = {}) {
168
+ public fun rangeFieldFor (property : P , init : INPUT .() -> Unit = {}) {
159
169
inputFor(range, property, init )
160
170
}
161
171
162
172
/* *
163
173
* Creates an input of type search for the given property.
164
174
*/
165
- public fun searchFieldFor (property : String , init : INPUT .() -> Unit = {}) {
175
+ public fun searchFieldFor (property : P , init : INPUT .() -> Unit = {}) {
166
176
inputFor(search, property, init )
167
177
}
168
178
169
179
/* *
170
180
* Creates an input of type time for the given property.
171
181
*/
172
- public fun timeFieldFor (property : String , init : INPUT .() -> Unit = {}) {
182
+ public fun timeFieldFor (property : P , init : INPUT .() -> Unit = {}) {
173
183
inputFor(time, property, init )
174
184
}
175
185
176
186
/* *
177
187
* Creates an input of type url for the given property.
178
188
*/
179
- public fun urlFieldFor (property : String , init : INPUT .() -> Unit = {}) {
189
+ public fun urlFieldFor (property : P , init : INPUT .() -> Unit = {}) {
180
190
inputFor(url, property, init )
181
191
}
182
192
183
193
/* *
184
194
* Creates an input of type week for the given property.
185
195
*/
186
- public fun weekFieldFor (property : String , init : INPUT .() -> Unit = {}) {
196
+ public fun weekFieldFor (property : P , init : INPUT .() -> Unit = {}) {
187
197
inputFor(week, property, init )
188
198
}
189
199
190
200
/* *
191
201
* Creates an input of type file for the given property.
192
202
*/
193
- public fun fileFieldFor (property : String , init : INPUT .() -> Unit = {}) {
203
+ public fun fileFieldFor (property : P , init : INPUT .() -> Unit = {}) {
194
204
inputFor(file, property, init )
195
205
if (! hasFiles) {
196
206
hasFiles = true
@@ -201,7 +211,7 @@ class FormBuilder(val model : Any, val modelName : String = model.javaClass.getS
201
211
/* *
202
212
* Creates a radio button for the given property and value.
203
213
*/
204
- public fun radioFor (property : String , value : String , init : INPUT .() -> Unit = {}) {
214
+ public fun radioFor (property : P , value : String , init : INPUT .() -> Unit = {}) {
205
215
val modelValue = propertyValue(property).toString()
206
216
currentTag.input(inputType= radio, id= propertyId(property), name= propertyName(property), value= value) {
207
217
checked = value.equalsIgnoreCase(modelValue)
@@ -212,27 +222,28 @@ class FormBuilder(val model : Any, val modelName : String = model.javaClass.getS
212
222
/* *
213
223
* Creates a checkbox for the given property.
214
224
*/
215
- public fun checkBoxFor (property : String , init : INPUT .() -> Unit = {}) {
225
+ public fun checkBoxFor (property : P , init : INPUT .() -> Unit = {}) {
216
226
val modelValue = propertyValue(property)
217
227
currentTag.input(inputType= checkbox, id= propertyId(property), name= propertyName(property)) {
218
- checked = modelValue == " true" || modelValue == true
228
+ checked = modelValue == " true"
219
229
init ()
220
230
}
221
231
}
222
232
}
223
233
224
-
225
- /* *
226
- * Creates a [[FormBuilder]] for the given model object.
227
- */
228
- fun BodyTag.formFor (model : Any , action : Link , formMethod : FormMethod = FormMethod .post, init : FormBuilder .(form : FormBuilder ) -> Unit ) : FORM {
234
+ fun <P > BodyTag.formForModel (model : FormModel <P >, action : Link , formMethod : FormMethod = FormMethod .post, init : FormBuilder <P >.() -> Unit ) {
229
235
val builder = FormBuilder (model)
230
236
builder.action = action
231
237
builder.method = formMethod
232
238
builder.tagStack = this .tagStack
233
- builder.init (builder )
239
+ builder.init ()
234
240
children.add(builder)
235
- if (builder.hasFiles)
241
+
242
+ if (builder.hasFiles) {
236
243
builder.enctype = EncodingType .multipart
237
- return builder
244
+ }
245
+ }
246
+
247
+ fun BodyTag.formForBean (bean : Any , action : Link , formMethod : FormMethod = FormMethod .post, init : FormBuilder <String >.() -> Unit ) {
248
+ formForModel(BeanFormModel (bean), action, formMethod, init )
238
249
}
0 commit comments