1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle
.MonoRail
.Framework
.Helpers
.ValidationStrategy
18 using System
.Collections
;
19 using System
.Globalization
;
21 using System
.Threading
;
22 using Castle
.Components
.Validator
;
26 /// Provides an interface for the Zebda client side JS validator
27 /// http://labs.cavorite.com/zebda
29 public class ZebdaWebValidator
: IBrowserValidatorProvider
32 /// Read the configuration
34 /// <returns></returns>
35 public BrowserValidationConfiguration
CreateConfiguration(IDictionary parameters
)
37 ZebdaValidationConfiguration config
= new ZebdaValidationConfiguration();
38 config
.Configure(parameters
);
46 /// <returns></returns>
47 public IBrowserValidationGenerator
CreateGenerator(BrowserValidationConfiguration config
, InputElementType inputType
,
48 IDictionary attributes
)
50 return new ZebdaWebValidationGenerator(inputType
, attributes
);
57 /// Configuration for the Zebda validation
59 public class ZebdaValidationConfiguration
: BrowserValidationConfiguration
61 private IDictionary jsOptions
= new Hashtable();
64 /// Render the validation init script
66 /// <param name="formId"></param>
67 /// <returns></returns>
68 public override string CreateAfterFormOpened(string formId
)
70 string display
= CommonUtils
.ObtainEntryAndRemove(jsOptions
, "display");
72 StringBuilder script
= new StringBuilder();
73 script
.Append("$('" + formId
+ "').setAttribute('z:options','" + AjaxHelper
.JavascriptOptions(jsOptions
) + "')");
74 script
.AppendLine(";");
76 script
.Append("$('" + formId
+ "').setAttribute('z:display','" + display
+ "')");
77 script
.AppendLine(";");
79 return AbstractHelper
.ScriptBlock(script
.ToString());
83 /// read the validator configuration values
85 /// <param name="parameters"></param>
86 public override void Configure(IDictionary parameters
)
88 CultureInfo cultureInfo
= Thread
.CurrentThread
.CurrentCulture
;
90 string display
= CommonUtils
.ObtainEntryAndRemove(parameters
, "display", "inline");
91 string dateFormat
= CommonUtils
.ObtainEntryAndRemove(parameters
, "dateFormat", string.Empty
);
92 string thousandSeparator
= CommonUtils
.ObtainEntryAndRemove(parameters
, "thousandSeparator", string.Empty
);
93 string decimalSeparator
= CommonUtils
.ObtainEntryAndRemove(parameters
, "decimalSeparator", string.Empty
);
94 string immediate
= CommonUtils
.ObtainEntryAndRemove(parameters
, "immediate", "true");
95 string inlineFilters
= CommonUtils
.ObtainEntryAndRemove(parameters
, "inlineFilters", "false");
97 if (dateFormat
== string.Empty
)
99 dateFormat
= cultureInfo
.DateTimeFormat
.ShortDatePattern
;
102 if (thousandSeparator
== string.Empty
)
104 thousandSeparator
= cultureInfo
.NumberFormat
.NumberGroupSeparator
;
107 if (decimalSeparator
== string.Empty
)
109 decimalSeparator
= cultureInfo
.NumberFormat
.NumberDecimalSeparator
;
112 jsOptions
["inline"] = immediate
;
113 jsOptions
["inlineFilters"] = inlineFilters
;
114 jsOptions
["dateFormat"] = "\\'" + dateFormat
+ "\\'";
115 jsOptions
["thousandSeparator"] = "\\'" + thousandSeparator
+ "\\'";
116 jsOptions
["decimalSeparator"] = "\\'" + decimalSeparator
+ "\\'";
117 jsOptions
["display"] = display
;
123 #region Validation Generator
126 /// The generator for the Zebda JS validator
128 public class ZebdaWebValidationGenerator
: IBrowserValidationGenerator
130 private readonly IDictionary attributes
;
133 /// Initializes a new instance of the <see cref="ZebdaWebValidationGenerator"/> class.
135 /// <param name="inputType">Type of the input.</param>
136 /// <param name="attributes">The attributes.</param>
137 public ZebdaWebValidationGenerator(InputElementType inputType
, IDictionary attributes
)
139 this.attributes
= attributes
;
143 /// Set that a field should only accept digits.
145 /// <param name="target">The target name (ie, a hint about the controller being validated)</param>
146 /// <param name="violationMessage">The violation message.</param>
147 public void SetDigitsOnly(string target
, string violationMessage
)
149 AddZebdaAttribute("numeric", "{isFloat:false}");
150 AddTitle(violationMessage
);
154 /// Set that a field should only accept numbers.
156 /// <param name="target">The target name (ie, a hint about the controller being validated)</param>
157 /// <param name="violationMessage">The violation message.</param>
158 public void SetNumberOnly(string target
, string violationMessage
)
160 AddZebdaAttribute("numeric", "{isFloat:true}");
161 AddTitle(violationMessage
);
165 /// Sets that a field is required.
167 /// <param name="target">The target name (ie, a hint about the controller being validated)</param>
168 /// <param name="violationMessage">The violation message.</param>
169 public void SetAsRequired(string target
, string violationMessage
)
171 AddZebdaAttribute("required", "true");
172 AddClass("required");
173 AddTitle(violationMessage
);
177 /// Sets that a field value must match the specified regular expression.
179 /// <param name="target">The target name (ie, a hint about the controller being validated)</param>
180 /// <param name="regExp">The reg exp.</param>
181 /// <param name="violationMessage">The violation message.</param>
182 public void SetRegExp(string target
, string regExp
, string violationMessage
)
184 AddZebdaAttribute("regexp", "{exp: " + regExp + "}");
185 AddTitle(violationMessage
);
189 /// Sets that a field value must be a valid email address.
191 /// <param name="target">The target name (ie, a hint about the controller being validated)</param>
192 /// <param name="violationMessage">The violation message.</param>
193 public void SetEmail(string target
, string violationMessage
)
195 AddZebdaAttribute("email", "true");
196 AddTitle(violationMessage
);
200 /// Sets that field must have an exact lenght.
202 /// <param name="target">The target name (ie, a hint about the controller being validated)</param>
203 /// <param name="length">The length.</param>
204 public void SetExactLength(string target
, int length
)
206 AddZebdaAttribute("length", "{max: " + length + ", min: " + length + "}");
210 /// Sets that field must have an exact lenght.
212 /// <param name="target">The target name (ie, a hint about the controller being validated)</param>
213 /// <param name="length">The length.</param>
214 /// <param name="violationMessage">The violation message.</param>
215 public void SetExactLength(string target
, int length
, string violationMessage
)
217 AddZebdaAttribute("length", "{max: " + length + ", min: " + length + "}");
218 AddTitle(violationMessage
);
222 /// Sets that field must have an minimum lenght.
224 /// <param name="target">The target name (ie, a hint about the controller being validated)</param>
225 /// <param name="minLength">The minimum length.</param>
226 public void SetMinLength(string target
, int minLength
)
228 AddZebdaAttribute("length", "{min: " + minLength + "}");
232 /// Sets that field must have an minimum lenght.
234 /// <param name="target">The target name (ie, a hint about the controller being validated)</param>
235 /// <param name="minLength">The minimum length.</param>
236 /// <param name="violationMessage">The violation message.</param>
237 public void SetMinLength(string target
, int minLength
, string violationMessage
)
239 AddZebdaAttribute("length", "{min: " + minLength + "}");
240 AddTitle(violationMessage
);
244 /// Sets that field must have an maximum lenght.
246 /// <param name="target">The target name (ie, a hint about the controller being validated)</param>
247 /// <param name="maxLength">The maximum length.</param>
248 public void SetMaxLength(string target
, int maxLength
)
250 AddZebdaAttribute("length", "{max: " + maxLength + "}");
254 /// Sets that field must have an maximum lenght.
256 /// <param name="target">The target name (ie, a hint about the controller being validated)</param>
257 /// <param name="maxLength">The maximum length.</param>
258 /// <param name="violationMessage">The violation message.</param>
259 public void SetMaxLength(string target
, int maxLength
, string violationMessage
)
261 AddZebdaAttribute("length", "{max: " + maxLength + "}");
262 AddTitle(violationMessage
);
266 /// Sets that field must be between a length range.
268 /// <param name="target">The target name (ie, a hint about the controller being validated)</param>
269 /// <param name="minLength">The minimum length.</param>
270 /// <param name="maxLength">The maximum length.</param>
271 public void SetLengthRange(string target
, int minLength
, int maxLength
)
273 AddZebdaAttribute("length", "{max: " + maxLength + ", min: " + minLength + "}");
277 /// Sets that field must be between a length range.
279 /// <param name="target">The target name (ie, a hint about the controller being validated)</param>
280 /// <param name="minLength">The minimum length.</param>
281 /// <param name="maxLength">The maximum length.</param>
282 /// <param name="violationMessage">The violation message.</param>
283 public void SetLengthRange(string target
, int minLength
, int maxLength
, string violationMessage
)
285 AddZebdaAttribute("length", "{max: " + maxLength + ", min: " + minLength + "}");
286 AddTitle(violationMessage
);
290 /// Sets that field must be between a value range.
292 /// <param name="target">The target name (ie, a hint about the controller being validated)</param>
293 /// <param name="minValue">Minimum value.</param>
294 /// <param name="maxValue">Maximum value.</param>
295 /// <param name="violationMessage">The violation message.</param>
296 public void SetValueRange(string target
, int minValue
, int maxValue
, string violationMessage
)
298 AddZebdaAttribute("numeric", "{isFloat:false, minValue: " + minValue + ", maxValue: " + maxValue + "}");
299 AddTitle(violationMessage
);
303 /// Sets that field must be between a value range.
305 /// <param name="target">The target name (ie, a hint about the controller being validated)</param>
306 /// <param name="minValue">Minimum value.</param>
307 /// <param name="maxValue">Maximum value.</param>
308 /// <param name="violationMessage">The violation message.</param>
309 public void SetValueRange(string target
, decimal minValue
, decimal maxValue
, string violationMessage
)
311 AddZebdaAttribute("numeric", "{isFloat:true, minValue: " + minValue + ", maxValue: " + maxValue + "}");
312 AddTitle(violationMessage
);
316 /// Sets that field must be between a value range.
318 /// <param name="target">The target name (ie, a hint about the controller being validated)</param>
319 /// <param name="minValue">Minimum value.</param>
320 /// <param name="maxValue">Maximum value.</param>
321 /// <param name="violationMessage">The violation message.</param>
322 public void SetValueRange(string target
, DateTime minValue
, DateTime maxValue
, string violationMessage
)
327 /// Sets that field must be between a value range.
329 /// <param name="target">The target name (ie, a hint about the controller being validated)</param>
330 /// <param name="minValue">Minimum value.</param>
331 /// <param name="maxValue">Maximum value.</param>
332 /// <param name="violationMessage">The violation message.</param>
333 public void SetValueRange(string target
, string minValue
, string maxValue
, string violationMessage
)
338 /// Set that a field value must be the same as another field's value.
340 /// <param name="target">The target name (ie, a hint about the controller being validated)</param>
341 /// <param name="comparisonFieldName">The name of the field to compare with.</param>
342 /// <param name="violationMessage">The violation message.</param>
343 public void SetAsSameAs(string target
, string comparisonFieldName
, string violationMessage
)
345 AddZebdaAttribute("compare", "{field:'" + comparisonFieldName + "'}");
346 AddTitle(violationMessage
);
350 /// Set that a field value must _not_ be the same as another field's value.
352 /// <param name="target">The target name (ie, a hint about the controller being validated)</param>
353 /// <param name="comparisonFieldName">The name of the field to compare with.</param>
354 /// <param name="violationMessage">The violation message.</param>
355 public void SetAsNotSameAs(string target
, string comparisonFieldName
, string violationMessage
)
360 /// Set that a field value must be a valid date.
362 /// <param name="target">The target name (ie, a hint about the controller being validated)</param>
363 /// <param name="violationMessage">The violation message.</param>
364 public void SetDate(string target
, string violationMessage
)
366 AddZebdaAttribute("date", "true");
367 AddTitle(violationMessage
);
370 private void AddTitle(string message
)
372 AddZebdaAttribute("message", message
);
375 private void AddZebdaAttribute(string attributeName
, string attriubteValue
)
377 if (attributeName
.IndexOf("z:") == -1)
378 attributeName
= "z:" + attributeName
;
380 string existingAttributeValue
= (string) attributes
[attributeName
];
382 if (existingAttributeValue
!= null)
384 attributes
[attributeName
] = existingAttributeValue
+ " " + attriubteValue
;
388 attributes
[attributeName
] = attriubteValue
;
392 private void AddClass(string className
)
394 string existingClass
= (string) attributes
["class"];
396 if (existingClass
!= null)
398 attributes
["class"] = existingClass
+ " " + className
;
402 attributes
["class"] = className
;