1 /*
2 * Copyright (C) 2011 Emweb bv, Herent, Belgium.
3 *
4 * See the LICENSE file for terms of use.
5 */
6
7 #include <Wt/WFormModel.h>
8 #include <Wt/WLogger.h>
9
10 namespace Wt {
11
12 LOGGER("WFormModel");
13
14 const WValidator::Result WFormModel::Valid(ValidationState::Valid, WString());
15 const cpp17::any WFormModel::NoValue;
16
FieldData()17 WFormModel::FieldData::FieldData()
18 : validator(nullptr),
19 visible(true),
20 readOnly(false),
21 validated(false)
22 {
23 //TODO
24 //this is a workaround for cnor,
25 //because cnor seems to be unable to map initalizer ctors
26 //fix this in cnor
27 value = cpp17::any();
28 }
29
WFormModel()30 WFormModel::WFormModel()
31 { }
32
addField(Field field,const WString & info)33 void WFormModel::addField(Field field, const WString& info)
34 {
35 fields_[field] = FieldData();
36 fields_[field].validation
37 = WValidator::Result(ValidationState::Invalid, info);
38 }
39
removeField(Field field)40 void WFormModel::removeField(Field field)
41 {
42 fields_.erase(field);
43 }
44
fields()45 std::vector<WFormModel::Field> WFormModel::fields() const
46 {
47 std::vector<WFormModel::Field> result;
48
49 for (FieldMap::const_iterator i = fields_.begin(); i != fields_.end(); ++i)
50 result.push_back(i->first);
51
52 return result;
53 }
54
setReadOnly(Field field,bool readOnly)55 void WFormModel::setReadOnly(Field field, bool readOnly)
56 {
57 FieldMap::iterator i = fields_.find(field);
58
59 if (i != fields_.end())
60 i->second.readOnly = readOnly;
61 else
62 LOG_ERROR("setReadOnly(): " << field << " not in model");
63 }
64
isReadOnly(Field field)65 bool WFormModel::isReadOnly(Field field) const
66 {
67 FieldMap::const_iterator i = fields_.find(field);
68
69 if (i != fields_.end())
70 return i->second.readOnly;
71 else
72 return false;
73 }
74
setVisible(Field field,bool visible)75 void WFormModel::setVisible(Field field, bool visible)
76 {
77 FieldMap::iterator i = fields_.find(field);
78
79 if (i != fields_.end())
80 i->second.visible = visible;
81 else
82 LOG_ERROR("setVisible(): " << field << " not in model");
83 }
84
isVisible(Field field)85 bool WFormModel::isVisible(Field field) const
86 {
87 FieldMap::const_iterator i = fields_.find(field);
88
89 if (i != fields_.end())
90 return i->second.visible;
91 else
92 return true;
93 }
94
label(Field field)95 WString WFormModel::label(Field field) const
96 {
97 return WString::tr(field);
98 }
99
setValue(Field field,const cpp17::any & value)100 void WFormModel::setValue(Field field, const cpp17::any& value)
101 {
102 fields_[field].value = value;
103 }
104
value(Field field)105 const cpp17::any& WFormModel::value(Field field) const
106 {
107 FieldMap::const_iterator i = fields_.find(field);
108
109 if (i != fields_.end())
110 return i->second.value;
111 else
112 return NoValue;
113 }
114
valueText(Field field)115 WT_USTRING WFormModel::valueText(Field field) const
116 {
117 auto v = validator(field);
118
119 return asString(value(field), v ? v->format() : WT_USTRING());
120 }
121
setValidator(Field field,const std::shared_ptr<WValidator> & validator)122 void WFormModel::setValidator(Field field,
123 const std::shared_ptr<WValidator>& validator)
124 {
125 FieldMap::iterator i = fields_.find(field);
126
127 if (i != fields_.end()) {
128 FieldData& d = i->second;
129 d.validator = validator;
130 } else
131 LOG_ERROR("setValidator(): " << field << " not in model");
132 }
133
validator(Field field)134 std::shared_ptr<WValidator> WFormModel::validator(Field field) const
135 {
136 FieldMap::const_iterator i = fields_.find(field);
137
138 if (i != fields_.end()) {
139 const FieldData& d = i->second;
140
141 return d.validator;
142 }
143
144 return nullptr;
145 }
146
validateField(Field field)147 bool WFormModel::validateField(Field field)
148 {
149 if (!isVisible(field))
150 return true;
151
152 FieldMap::iterator i = fields_.find(field);
153
154 if (i != fields_.end()) {
155 FieldData& d = i->second;
156
157 if (d.validator)
158 setValidation(field, d.validator->validate(asString(valueText(field))));
159 else
160 setValidation(field, Valid);
161
162 return d.validation.state() == ValidationState::Valid;
163 } else
164 return true;
165 }
166
reset()167 void WFormModel::reset()
168 {
169 for (FieldMap::iterator i = fields_.begin(); i != fields_.end(); ++i) {
170 i->second.value = cpp17::any();
171 i->second.validated = false;
172 }
173 }
174
valid()175 bool WFormModel::valid() const
176 {
177 for (FieldMap::const_iterator i = fields_.begin(); i != fields_.end(); ++i) {
178 const FieldData& fd = i->second;
179
180 if (!fd.visible)
181 continue;
182
183 if (!fd.validated
184 || fd.validation.state() != ValidationState::Valid)
185 return false;
186 }
187
188 return true;
189 }
190
validate()191 bool WFormModel::validate()
192 {
193 bool result = true;
194
195 for (FieldMap::iterator i = fields_.begin(); i != fields_.end(); ++i) {
196 if (!validateField(i->first))
197 result = false;
198 }
199
200 return result;
201 }
202
isValidated(Field field)203 bool WFormModel::isValidated(Field field) const
204 {
205 FieldMap::const_iterator i = fields_.find(field);
206
207 if (i != fields_.end())
208 return i->second.validated;
209 else
210 return false;
211 }
212
setValidated(Field field,bool validated)213 void WFormModel::setValidated(Field field, bool validated)
214 {
215 FieldMap::iterator i = fields_.find(field);
216
217 if (i != fields_.end())
218 i->second.validated = validated;
219 else
220 LOG_ERROR("setValidated(): " << field << " not in model");
221 }
222
setValidation(Field field,const WValidator::Result & result)223 void WFormModel::setValidation(Field field,
224 const WValidator::Result& result)
225 {
226 FieldMap::iterator i = fields_.find(field);
227
228 if (i != fields_.end()) {
229 i->second.validation = result;
230 setValidated(field, true);
231 } else
232 LOG_ERROR("setValidation(): " << field << " not in model");
233 }
234
validation(Field field)235 const WValidator::Result& WFormModel::validation(Field field) const
236 {
237 FieldMap::const_iterator i = fields_.find(field);
238
239 if (i != fields_.end())
240 return i->second.validation;
241 else
242 return Valid;
243 }
244
245 }
246