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