2002-07-28 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / BaseValidator.cs
1 /**\r
2  * Namespace: System.Web.UI.WebControls\r
3  * Class:     BaseValidator\r
4  *\r
5  * Authors:  Gaurav Vaish, Gonzalo Paniagua Javier\r
6  * Maintainer: gvaish@iitk.ac.in\r
7  * Contact: <my_scripts2001@yahoo.com>, <gvaish@iitk.ac.in>, <gonzalo@ximian.com>\r
8  * Implementation: yes\r
9  * Status:  80%\r
10  *\r
11  * (C) Gaurav Vaish (2001)\r
12  * (c) 2002 Ximian, Inc. (http://www.ximian.com)\r
13  */\r
14 \r
15 using System;\r
16 using System.ComponentModel;\r
17 using System.Web;\r
18 using System.Web.UI;\r
19 using System.Drawing;\r
20 \r
21 namespace System.Web.UI.WebControls\r
22 {\r
23         [DefaultProperty("ErrorMessage")]\r
24         //TODO: [Designer("??")]\r
25         public abstract class BaseValidator: Label, IValidator\r
26         {\r
27                 private bool isValid;\r
28                 private bool isPreRenderCalled;\r
29                 private bool isPropertiesChecked;\r
30                 private bool propertiesValid;\r
31                 private bool renderUplevel;\r
32 \r
33                 protected BaseValidator() : base()\r
34                 {\r
35                         isValid = true;\r
36                         ForeColor = Color.Red;\r
37                         propertiesValid = true;\r
38                         isPropertiesChecked = false;\r
39                         renderUplevel = false;\r
40                 }\r
41 \r
42                 public string ControlToValidate\r
43                 {\r
44                         get\r
45                         {\r
46                                 object o = ViewState["ControlToValidate"];\r
47                                 if(o != null)\r
48                                 {\r
49                                         return (string)o;\r
50                                 }\r
51                                 return String.Empty;\r
52                         }\r
53                         set\r
54                         {\r
55                                 ViewState["ControlToValidate"] = value;\r
56                         }\r
57                 }\r
58 \r
59                 public ValidatorDisplay Display\r
60                 {\r
61                         get\r
62                         {\r
63                                 object o = ViewState["Display"];\r
64                                 if(o != null)\r
65                                 {\r
66                                         return (ValidatorDisplay)o;\r
67                                 }\r
68                                 return ValidatorDisplay.Static;\r
69                         }\r
70                         set\r
71                         {\r
72                                 if(!Enum.IsDefined(typeof(ValidatorDisplay), value))\r
73                                 {\r
74                                         throw new ArgumentException();\r
75                                 }\r
76                                 ViewState["ValidatorDisplay"] = value;\r
77                         }\r
78                 }\r
79 \r
80                 public bool EnableClientScript\r
81                 {\r
82                         get\r
83                         {\r
84                                 object o = ViewState["EnableClientScript"];\r
85                                 if(o != null)\r
86                                 {\r
87                                         return (bool)o;\r
88                                 }\r
89                                 return true;\r
90                         }\r
91                         set\r
92                         {\r
93                                 ViewState["EnableClientScript"] = value;\r
94                         }\r
95                 }\r
96 \r
97                 public override bool Enabled\r
98                 {\r
99                         get\r
100                         {\r
101                                 return base.Enabled;\r
102                         }\r
103                         set\r
104                         {\r
105                                 if (value == false)\r
106                                         isValid = true;\r
107                                 base.Enabled = value;\r
108                         }\r
109                 }\r
110 \r
111                 public string ErrorMessage\r
112                 {\r
113                         get\r
114                         {\r
115                                 object o = ViewState["ErrorMessage"];\r
116                                 if(o != null)\r
117                                 {\r
118                                         return (string)o;\r
119                                 }\r
120                                 return String.Empty;\r
121                         }\r
122                         set\r
123                         {\r
124                                 ViewState["ErrorMessage"] = value;\r
125                         }\r
126                 }\r
127 \r
128                 public override Color ForeColor\r
129                 {\r
130                         get\r
131                         {\r
132                                 return base.ForeColor;\r
133                         }\r
134                         set\r
135                         {\r
136                                 base.ForeColor = value;\r
137                         }\r
138                 }\r
139 \r
140                 public bool IsValid\r
141                 {\r
142                         get { return isValid; }\r
143                         set { isValid = value; }\r
144                 }\r
145 \r
146                 public static PropertyDescriptor GetValidationProperty(object component)\r
147                 {\r
148                         System.ComponentModel.AttributeCollection coll = TypeDescriptor.GetAttributes (component);\r
149                         Type type = typeof (ValidationPropertyAttribute);\r
150                         ValidationPropertyAttribute attrib = (ValidationPropertyAttribute) coll [type];\r
151                         if (attrib != null && attrib.Name != null)\r
152                                 return (TypeDescriptor.GetProperties (component)) [attrib.Name];\r
153                         return null;\r
154                 }\r
155 \r
156                 public void Validate()\r
157                 {\r
158                         if(!Visible || (Visible && !Enabled))\r
159                         {\r
160                                 IsValid = true;\r
161                         }\r
162                         Control ctrl = Parent;\r
163                         while(ctrl != null)\r
164                         {\r
165                                 if(!ctrl.Visible)\r
166                                 {\r
167                                         IsValid = true;\r
168                                         return;\r
169                                 }\r
170                                 ctrl = ctrl.Parent;\r
171                         }\r
172                         isPropertiesChecked = false;\r
173                         if(!PropertiesValid)\r
174                         {\r
175                                 IsValid = true;\r
176                                 return;\r
177                         }\r
178                         IsValid = EvaluateIsValid();\r
179                 }\r
180 \r
181                 protected bool PropertiesValid\r
182                 {\r
183                         get\r
184                         {\r
185                                 if(!isPropertiesChecked)\r
186                                 {\r
187                                         propertiesValid = ControlPropertiesValid();\r
188                                         isPropertiesChecked = true;\r
189                                 }\r
190                                 return propertiesValid;\r
191                         }\r
192                 }\r
193 \r
194                 protected bool RenderUplevel\r
195                 {\r
196                         get\r
197                         {\r
198                                 return renderUplevel;\r
199                         }\r
200                 }\r
201 \r
202                 protected override void AddAttributesToRender(HtmlTextWriter writer)\r
203                 {\r
204                         bool enabled = base.Enabled;\r
205                         if (enabled)\r
206                                 Enabled = true;\r
207 \r
208                         base.AddAttributesToRender(writer);\r
209                         if(RenderUplevel)\r
210                         {\r
211                                 if(ID == null)\r
212                                 {\r
213                                         writer.AddAttribute("id", ClientID);\r
214                                 }\r
215                                 if(ControlToValidate.Length > 0)\r
216                                 {\r
217                                         writer.AddAttribute("controltovalidate", GetControlRenderID(ControlToValidate));\r
218                                 }\r
219                                 if(ErrorMessage.Length > 0)\r
220                                 {\r
221                                         writer.AddAttribute("errormessage", ErrorMessage, true);\r
222                                 }\r
223                                 if(Display == ValidatorDisplay.Static)\r
224                                 {\r
225                                         writer.AddAttribute("display", Enum.Format(typeof(ValidatorDisplay), Display, "G").Replace('_','-'));\r
226                                         //writer.AddAttribute("display", PropertyConverter.EnumToString(typeof(ValidatorDisplay), Display));\r
227                                 }\r
228                                 if(!IsValid)\r
229                                 {\r
230                                         writer.AddAttribute("isvalid", "False");\r
231                                 }\r
232 \r
233                                 ControlStyle.AddAttributesToRender (writer, this);\r
234                                 if(!enabled)\r
235                                 {\r
236                                         writer.AddAttribute("enabled", "False");\r
237                                 }\r
238                         }\r
239 \r
240                         if(enabled)\r
241                         {\r
242                                 Enabled = false;\r
243                         }\r
244                 }\r
245 \r
246                 protected void CheckControlValidationProperty(string name, string propertyName)\r
247                 {\r
248                         Control ctrl = NamingContainer.FindControl(name);\r
249                         if(ctrl == null)\r
250                         {\r
251                                 throw new HttpException(HttpRuntime.FormatResourceString("Validator_control_not_found",\r
252                                                  name, propertyName/*, ID*/));\r
253                         }\r
254                         PropertyDescriptor pd = GetValidationProperty(ctrl);\r
255                         if(pd == null)\r
256                         {\r
257                                 throw new HttpException(HttpRuntime.FormatResourceString("Validator_bad_control_type",\r
258                                                  name, propertyName/*, ID*/));\r
259                         }\r
260                 }\r
261 \r
262                 protected virtual bool ControlPropertiesValid()\r
263                 {\r
264                         if(ControlToValidate.Length == 0)\r
265                         {\r
266                                 throw new HttpException(HttpRuntime.FormatResourceString("Validator_control_blank", ID));\r
267                         }\r
268                         CheckControlValidationProperty(ControlToValidate, "ControlToValidate");\r
269                         return true;\r
270                 }\r
271 \r
272                 [MonoTODO]\r
273                 protected virtual bool DetermineRenderUplevel()\r
274                 {\r
275                         Page page = Page;\r
276                         if(page == null || page.Request == null)\r
277                         {\r
278                                 return false;\r
279                         }\r
280 \r
281                         if(EnableClientScript)\r
282                         {\r
283                                 // By now, return false\r
284                                 return false;\r
285                                 ////throw new NotImplementedException();\r
286                                 ////TODO: I need to get the (Browser->Dom_version_major >= 4 &&\r
287                                 ////                         Brower->Ecma_script_version >= 1.2)\r
288                         }\r
289                         return false;\r
290                 }\r
291 \r
292                 protected string GetControlRenderID(string name)\r
293                 {\r
294                         Control ctrl = FindControl(name);\r
295                         if(ctrl != null)\r
296                         {\r
297                                 return ctrl.ClientID;\r
298                         }\r
299                         return String.Empty;\r
300                 }\r
301 \r
302                 protected string GetControlValidationValue(string name)\r
303                 {\r
304                         Control ctrl = NamingContainer.FindControl(name);\r
305                         if(ctrl != null)\r
306                         {\r
307                                 PropertyDescriptor pd = GetValidationProperty(ctrl);\r
308                                 if(pd != null)\r
309                                 {\r
310                                         object item = pd.GetValue(ctrl);\r
311                                         if(item is ListItem)\r
312                                         {\r
313                                                 return ((ListItem)item).Value;\r
314                                         }\r
315                                         return item.ToString();\r
316                                 }\r
317                         }\r
318                         return null;\r
319                 }\r
320 \r
321                 protected override void OnInit(EventArgs e)\r
322                 {\r
323                         base.OnInit(e);\r
324                         Page.Validators.Add(this);\r
325                 }\r
326 \r
327                 protected override void OnPreRender(EventArgs e)\r
328                 {\r
329                         base.OnPreRender(e);\r
330                         isPreRenderCalled   = true;\r
331                         isPropertiesChecked = false;\r
332                         renderUplevel       = DetermineRenderUplevel();\r
333                         if(renderUplevel)\r
334                         {\r
335                                 RegisterValidatorCommonScript();\r
336                         }\r
337                 }\r
338 \r
339                 protected override void OnUnload(EventArgs e)\r
340                 {\r
341                         if(Page != null)\r
342                         {\r
343                                 Page.Validators.Remove(this);\r
344                         }\r
345                         base.OnUnload(e);\r
346                 }\r
347 \r
348                 [MonoTODO("What_do_I_have_to_do")]\r
349                 protected void RegisterValidatorCommonScript()\r
350                 {\r
351                         // Keep going\r
352                         //throw new NotImplementedException();\r
353                 }\r
354 \r
355                 [MonoTODO("I_have_to_know_javascript_for_this_I_know_it_but_for_ALL_browsers_NO")]\r
356                 protected virtual void RegisterValidatorDeclaration()\r
357                 {\r
358                         throw new NotImplementedException();\r
359                         //TODO: Since I have to access document.<ClientID> and register\r
360                         // as page validator. Now this is Browser dependent :((\r
361 \r
362                         // This does not render anything on Mozilla, and does on IE\r
363                 }\r
364 \r
365                 [MonoTODO("Render_ing_always_left")]\r
366                 protected override void Render (HtmlTextWriter writer)\r
367                 {\r
368                         bool valid;\r
369 \r
370                         if (!Enabled)\r
371                                 return;\r
372 \r
373                         if (isPreRenderCalled) {\r
374                                 valid = IsValid;\r
375                         } else {\r
376                                 isPropertiesChecked = true;\r
377                                 propertiesValid     = true;\r
378                                 renderUplevel       = false;\r
379                                 valid               = true;\r
380                         }\r
381 \r
382                         if (PropertiesValid) {\r
383                                 if (Page != null)\r
384                                         Page.VerifyRenderingInServerForm (this);\r
385 \r
386                                 ValidatorDisplay dis = Display;\r
387                                 if (RenderUplevel) {\r
388                                         //FIXME: by now, don't do client-side validation\r
389                                 }\r
390                                 \r
391                                 if (!valid) {\r
392                                         RenderBeginTag (writer);\r
393                                         if (Text.Trim ().Length > 0 || HasControls ()) {\r
394                                                 RenderContents (writer);\r
395                                                 RenderEndTag (writer);\r
396                                         } else {\r
397                                                 writer.Write (ErrorMessage);\r
398                                         }\r
399                                         RenderEndTag (writer);\r
400                                         return;\r
401                                 }\r
402                         } else {\r
403                                 writer.Write ("&nbsp;");\r
404                         }\r
405                 }\r
406 \r
407                 protected abstract bool EvaluateIsValid();\r
408         }\r
409 }\r
410 \r