2010-03-12 Jb Evain <jbevain@novell.com>
[mono.git] / mcs / class / System.Web / System.Web.UI.HtmlControls / HtmlInputButton.cs
1 //
2 // System.Web.UI.HtmlControls.HtmlInputButton.cs
3 //
4 // Authors:
5 //      Jackson Harper (jackson@ximian.com)
6 //
7 // (C) 2005 Novell, Inc.
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System.ComponentModel;
30 using System.Globalization;
31 using System.Reflection;
32 using System.Security.Permissions;
33 using System.Web.Util;
34
35 namespace System.Web.UI.HtmlControls {
36
37         // CAS
38         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
39         [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
40         // attributes
41         [DefaultEventAttribute ("ServerClick")]
42 #if NET_2_0
43         [SupportsEventValidation]
44 #endif
45         public class HtmlInputButton : HtmlInputControl, IPostBackEventHandler 
46         {
47                 static readonly object ServerClickEvent = new object();
48
49                 public HtmlInputButton () : this ("button")
50                 {
51                 }
52
53                 public HtmlInputButton (string type) :  base (type)
54                 {
55                 }
56
57                 [DefaultValue(true)]
58                 [WebSysDescription("")]
59                 [WebCategory("Behavior")]
60 #if NET_2_0
61                 public virtual
62 #else           
63                 public
64 #endif          
65                 bool CausesValidation {
66                         get {
67                                 string flag = Attributes["CausesValidation"];
68
69                                 if (flag == null)
70                                         return true;
71
72                                 return Boolean.Parse (flag);
73                         }
74                         set {
75                                 Attributes ["CausesValidation"] = value.ToString();
76                         }
77                 }
78
79 #if NET_2_0
80                 [DefaultValue ("")]
81                 public virtual string ValidationGroup
82                 {
83                         get {
84                                 string group = Attributes["ValidationGroup"];
85
86                                 if (group == null)
87                                         return "";
88
89                                 return group;
90                         }
91                         set {
92                                 if (value == null)
93                                         Attributes.Remove ("ValidationGroup");
94                                 else
95                                         Attributes["ValidationGroup"] = value;
96                         }
97                 }
98 #endif
99
100                 void RaisePostBackEventInternal (string eventArgument)
101                 {
102 #if NET_2_0
103                         ValidateEvent (UniqueID, eventArgument);
104 #endif
105                         if (CausesValidation) {
106 #if NET_2_0
107                                 Page.Validate (ValidationGroup);
108 #else
109                                 Page.Validate ();
110 #endif
111                         }
112                         
113                         if (String.Compare (Type, "reset", true, Helpers.InvariantCulture) != 0)
114                                 OnServerClick (EventArgs.Empty);
115                         else
116                                 ResetForm (FindForm ());
117                 }
118
119                 HtmlForm FindForm ()
120                 {
121 #if NET_2_0
122                         return Page.Form;
123 #else
124                         HtmlForm ret = null;
125                         Control p = Parent;
126                         while (p != null) {
127                                 ret = p as HtmlForm;
128                                 if (ret == null) {
129                                         p = p.Parent;
130                                         continue;
131                                 }
132                                 return ret;
133                         }
134
135                         return null;
136 #endif
137                 }
138                 
139                 void ResetForm (HtmlForm form)
140                 {
141                         if (form == null || !form.HasControls ())
142                                 return;
143                         
144                         ResetChildrenValues (form.Controls);
145                 }
146
147                 void ResetChildrenValues (ControlCollection children)
148                 {
149                         foreach (Control child in children) {
150                                 if (child == null)
151                                         continue;
152                                 
153                                 if (child.HasControls ())
154                                         ResetChildrenValues (child.Controls);
155                                 ResetChildValue (child);
156                         }
157                 }
158
159                 void ResetChildValue (Control child)
160                 {
161                         Type type = child.GetType ();
162                         object[] attributes = type.GetCustomAttributes (false);
163                         if (attributes == null || attributes.Length == 0)
164                                 return;
165
166                         string defaultProperty = null;
167                         DefaultPropertyAttribute defprop;
168                         
169                         foreach (object attr in attributes) {
170                                 defprop = attr as DefaultPropertyAttribute;
171                                 if (defprop == null)
172                                         continue;
173                                 defaultProperty = defprop.Name;
174                                 break;
175                         }
176
177                         if (defaultProperty == null || defaultProperty.Length == 0)
178                                 return;
179
180                         PropertyInfo pi = null;
181                         try {
182                                 pi = type.GetProperty (defaultProperty,
183                                                        BindingFlags.Instance |
184                                                        BindingFlags.Public |
185                                                        BindingFlags.Static |
186                                                        BindingFlags.IgnoreCase);
187                         } catch (Exception) {
188                                 // ignore
189                         }
190                         if (pi == null || !pi.CanWrite)
191                                 return;
192                         
193                         attributes = pi.GetCustomAttributes (false);
194                         if (attributes == null || attributes.Length == 0)
195                                 return;
196
197                         DefaultValueAttribute defval = null;
198                         object value = null;
199                         
200                         foreach (object attr in attributes) {
201                                 defval = attr as DefaultValueAttribute;
202                                 if (defval == null)
203                                         continue;
204                                 value = defval.Value;
205                                 break;
206                         }
207                         
208                         if (value == null || pi.PropertyType != value.GetType ())
209                                 return;
210
211                         try {
212                                 pi.SetValue (child, value, null);
213                         } catch (Exception) {
214                                 // ignore
215                         }
216                 }
217 #if NET_2_0
218                 protected virtual void RaisePostBackEvent (string eventArgument)
219                 {
220                         RaisePostBackEventInternal (eventArgument);
221                 }
222 #endif
223                 
224                 void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
225                 {
226 #if NET_2_0
227                         RaisePostBackEvent (eventArgument);
228 #else
229                         RaisePostBackEventInternal (eventArgument);
230 #endif
231                 }
232
233 #if NET_2_0
234                 protected internal
235 #else           
236                 protected
237 #endif          
238                 override void OnPreRender (EventArgs e)
239                 {
240                         base.OnPreRender (e);
241                         if (Events [ServerClickEvent] != null)
242                                 Page.RequiresPostBackScript ();
243                 }
244
245                 protected virtual void OnServerClick (EventArgs e)
246                 {
247                         EventHandler server_click = (EventHandler) Events [ServerClickEvent];
248                         if (server_click != null)
249                                 server_click (this, e);
250                 }
251
252 #if !NET_2_0
253                 bool RenderOnClick ()
254                 {
255                         if (Page == null || !CausesValidation)
256                                 return false;
257
258                         CultureInfo inv = Helpers.InvariantCulture;
259                         string input_type = Type;
260                         if (0 == String.Compare (input_type, "submit", true, inv) &&
261                                 Page.Validators.Count > 0)
262                                 return true;
263
264                         if (0 == String.Compare (input_type, "button", true, inv) &&
265                                 Events [ServerClickEvent] != null)
266                                 return true;
267
268                         return false;
269                 }
270 #endif
271
272                 protected override void RenderAttributes (HtmlTextWriter writer)
273                 {
274 #if NET_2_0
275                         CultureInfo inv = Helpers.InvariantCulture;
276                         string input_type = Type;
277                         if (0 != String.Compare (input_type, "reset", true, inv) &&
278                                 ((0 == String.Compare (input_type, "submit", true, inv)) ||
279                                 (0 == String.Compare (input_type, "button", true, inv) && Events [ServerClickEvent] != null))) {
280
281                                 string onclick = String.Empty;
282                                 if (Attributes ["onclick"] != null) {
283                                         onclick = ClientScriptManager.EnsureEndsWithSemicolon (Attributes ["onclick"] + onclick);
284                                         Attributes.Remove ("onclick");
285                                 }
286                                 if (Page != null) {
287                                         PostBackOptions options = GetPostBackOptions ();
288                                         onclick += Page.ClientScript.GetPostBackEventReference (options, true);
289                                 }
290
291                                 if (onclick.Length > 0) {
292                                         writer.WriteAttribute ("onclick", onclick, true);
293                                         writer.WriteAttribute ("language", "javascript");
294                                 }
295                         }
296 #else
297                         if (RenderOnClick ()) {
298                                 string oc = null;
299                                 ClientScriptManager csm = new ClientScriptManager (Page);
300                                 if (Page.AreValidatorsUplevel ()) {
301                                         oc = csm.GetClientValidationEvent ();
302                                 } else if (Events [ServerClickEvent] != null) {
303                                         oc = Attributes ["onclick"] + " " + csm.GetPostBackEventReference (this, "");
304                                 }
305                                 
306                                 if (oc != null) {
307                                         writer.WriteAttribute ("language", "javascript");
308                                         writer.WriteAttribute ("onclick", oc, true);
309                                 }
310                         }
311 #endif
312
313                         Attributes.Remove ("CausesValidation");
314 #if NET_2_0
315                         // LAMESPEC: MS doesn't actually remove this
316                         //attribute.  it shows up in the rendered
317                         //output.
318
319                         // Attributes.Remove("ValidationGroup");
320 #endif
321                         base.RenderAttributes (writer);
322                 }
323
324 #if NET_2_0
325                 PostBackOptions GetPostBackOptions () {
326                         PostBackOptions options = new PostBackOptions (this);
327                         options.ValidationGroup = null;
328                         options.ActionUrl = null;
329                         options.Argument = String.Empty;
330                         options.RequiresJavaScriptProtocol = false;
331                         options.ClientSubmit = (0 != String.Compare (Type, "submit", true, Helpers.InvariantCulture));
332                         options.PerformValidation = CausesValidation && Page != null && Page.Validators.Count > 0;
333                         if (options.PerformValidation)
334                                 options.ValidationGroup = ValidationGroup;
335
336                         return options;
337                 }
338 #endif
339
340                 [WebSysDescription("")]
341                 [WebCategory("Action")]
342                 public event EventHandler ServerClick {
343                         add { Events.AddHandler (ServerClickEvent, value); }
344                         remove { Events.RemoveHandler (ServerClickEvent, value); }
345                 }
346         }
347         
348 }
349