|
I have developed a new server control - PromptClickOnce button based on ClickOnce button. Besides the features of validation and ClickOnce, it integrates a new feature: prompt a confirmation dialog box. When it is clicked, it first validates the page, then popup a dialog to ask user's confirmation before performing ClickOnce. If you need this button, simply add it to ClickOnceButton project, and build new ClickOnceButton assemly. After you add the new assemly to your .NET toolbox, you will see this new server control. Have fun to play with it!
Imports System.ComponentModel
Imports System.Web.UI
Imports System.Drawing
<br />
<ToolboxBitmap(GetType(System.Web.UI.WebControls.Button)), DefaultEvent("Click")> _<br />
Public Class PromptClickOnceButton<br />
Inherits System.Web.UI.WebControls.WebControl<br />
Implements IPostBackEventHandler<br />
<br />
Public Event Click As EventHandler<br />
Public Event Command As System.Web.UI.WebControls.CommandEventHandler<br />
<br />
Private Const OnceClickBtnName As String = "__onceClickBtn"<br />
<br />
<br />
<Browsable(True), Category("Behavior")> _<br />
Public Property DisableAfterClick() As Boolean<br />
Get<br />
Dim o As Object = MyBase.ViewState("DisableAfterClick")<br />
Return IIf(IsNothing(o), False, CBool(o))<br />
End Get<br />
Set(ByVal Value As Boolean)<br />
MyBase.ViewState("DisableAfterClick") = Value<br />
End Set<br />
End Property<br />
<br />
<Browsable(True), Category("Behavior")> _<br />
Public Property CommandName() As String<br />
Get<br />
Dim o As Object = MyBase.ViewState("CommandName")<br />
Return IIf(IsNothing(o), String.Empty, CStr(o))<br />
End Get<br />
Set(ByVal Value As String)<br />
MyBase.ViewState("CommandName") = Value<br />
End Set<br />
End Property<br />
<br />
<Browsable(True), Category("Behavior")> _<br />
Public Property CommandArgument() As String<br />
Get<br />
Dim o As Object = MyBase.ViewState("CommandArgument")<br />
Return IIf(IsNothing(o), String.Empty, CStr(o))<br />
End Get<br />
Set(ByVal Value As String)<br />
MyBase.ViewState("CommandArgument") = Value<br />
End Set<br />
End Property<br />
<br />
<Browsable(True), Category("Appearance")> _<br />
Public Property DisabledText() As String<br />
Get<br />
Dim o As Object = MyBase.ViewState("DisabledText")<br />
Return IIf(IsNothing(o), String.Empty, CStr(o))<br />
End Get<br />
Set(ByVal Value As String)<br />
MyBase.ViewState("DisabledText") = Value<br />
End Set<br />
End Property<br />
<br />
<Browsable(True), Category("Appearance")> _<br />
Public Property Text() As String<br />
Get<br />
Dim o As Object = MyBase.ViewState("Text")<br />
Return IIf(IsNothing(o), "Button", CStr(o))<br />
End Get<br />
Set(ByVal Value As String)<br />
MyBase.ViewState("Text") = Value<br />
End Set<br />
End Property<br />
<br />
<Browsable(True), Category("Behavior")> _<br />
Public Property CausesValidation() As Boolean<br />
Get<br />
Dim o As Object = MyBase.ViewState("CausesValidation")<br />
Return IIf(IsNothing(o), True, CBool(o))<br />
End Get<br />
Set(ByVal Value As Boolean)<br />
MyBase.ViewState("CausesValidation") = Value<br />
End Set<br />
End Property<br />
<br />
<Browsable(True), Category("Behavior")> _<br />
Public Property ConfirmBeforeSubmit() As Boolean<br />
Get<br />
Dim o As Object = MyBase.ViewState("ConfirmBeforeSubmit")<br />
Return IIf(IsNothing(o), True, CBool(o))<br />
End Get<br />
Set(ByVal Value As Boolean)<br />
MyBase.ViewState("ConfirmBeforeSubmit") = Value<br />
End Set<br />
End Property<br />
<br />
<Browsable(True), Category("Appearance")> _<br />
Public Property ConfirmationMessage() As String<br />
Get<br />
Dim o As Object = MyBase.ViewState("ConfirmationMessage")<br />
Return IIf(IsNothing(o), String.Empty, CStr(o))<br />
End Get<br />
Set(ByVal Value As String)<br />
MyBase.ViewState("ConfirmationMessage") = Value<br />
End Set<br />
End Property<br />
<br />
Public Sub New()<br />
MyBase.New(HtmlTextWriterTag.Input)<br />
End Sub<br />
<br />
<br />
<Browsable(False)> _<br />
Friend ReadOnly Property GetClientValidate() As String<br />
Get<br />
Return "if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate(); "<br />
End Get<br />
End Property<br />
<br />
<Browsable(False)> _<br />
Friend ReadOnly Property GetClickOnceClientValidate() As String<br />
Get<br />
Return "if (typeof(Page_ClientValidate) == 'function') { if(Page_ClientValidate()) { " + _<br />
GetClickOnceJavascript + " }} else { " + _<br />
GetClickOnceJavascript + " }"<br />
End Get<br />
End Property<br />
<br />
<Browsable(False)> _<br />
Friend ReadOnly Property GetClickOnceJavascript() As String<br />
Get<br />
Return "document.getElementsByName('" + Me.OnceClickBtnName + "').item(0).setAttribute('name'," + _<br />
"this.getAttribute('name')); this.disabled = true; " + _<br />
IIf(DisabledText = String.Empty, String.Empty, "this.value = '" + DisabledText + "';") + _<br />
"this.form.submit();"<br />
End Get<br />
End Property<br />
<br />
<Browsable(False)> _<br />
Friend ReadOnly Property GetConfirmJavascript() As String<br />
Get<br />
Return "return confirm('" + EscapedMessage(ConfirmationMessage) + "');"<br />
<br />
End Get<br />
End Property<br />
<br />
<Browsable(False)> _<br />
Friend ReadOnly Property GetConfirm() As String<br />
Get<br />
<br />
Return "confirm('" + EscapedMessage(ConfirmationMessage) + "')"<br />
<br />
End Get<br />
End Property<br />
<br />
<Browsable(False)> _<br />
Friend ReadOnly Property GetConfirmReturn() As String<br />
Get<br />
<br />
Return "if (confirm('" + EscapedMessage(ConfirmationMessage) + "')) " + _<br />
"{ return true;} else {return false;} "<br />
<br />
End Get<br />
End Property<br />
<br />
<Browsable(False)> _<br />
Friend ReadOnly Property GetConfirmClientValidate() As String<br />
Get<br />
Return "if (typeof(Page_ClientValidate) == 'function') { if(Page_ClientValidate()) { " + _<br />
GetConfirmReturn + " }} else { " + _<br />
GetConfirmReturn + " }"<br />
End Get<br />
<br />
End Property<br />
<br />
<Browsable(False)> _<br />
Friend ReadOnly Property GetConfirmClickOnce() As String<br />
Get<br />
Return " if( " + GetConfirm + ") { " + _<br />
GetClickOnceJavascript + " } else {return false;}"<br />
End Get<br />
<br />
End Property<br />
<br />
<Browsable(False)> _<br />
Friend ReadOnly Property GetConfirmClickOnceClientValidate() As String<br />
Get<br />
Return "if (typeof(Page_ClientValidate) == 'function') { if(Page_ClientValidate()) { " + _<br />
GetConfirmClickOnce + " }} else { " + _<br />
GetConfirmClickOnce + " }"<br />
End Get<br />
End Property<br />
<br />
Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)<br />
End Sub<br />
<br />
Protected Overrides Sub AddAttributesToRender(ByVal writer As HtmlTextWriter)<br />
Dim strOnClick As String<br />
<br />
If IsNothing(MyBase.Page) Then<br />
MyBase.Page.VerifyRenderingInServerForm(Me)<br />
End If<br />
<br />
writer.AddAttribute(HtmlTextWriterAttribute.Type, "submit")<br />
writer.AddAttribute(HtmlTextWriterAttribute.Name, MyBase.UniqueID)<br />
writer.AddAttribute(HtmlTextWriterAttribute.Value, Me.Text)<br />
<br />
If Not IsNothing(MyBase.Page) And Me.CausesValidation And MyBase.Page.Validators.Count > 0 Then<br />
If Me.DisableAfterClick Then<br />
If Me.ConfirmBeforeSubmit Then<br />
strOnClick = Me.GetConfirmClickOnceClientValidate<br />
Else<br />
strOnClick = Me.GetClickOnceClientValidate<br />
End If<br />
Else<br />
If Me.ConfirmBeforeSubmit Then<br />
strOnClick = Me.GetConfirmClientValidate<br />
Else<br />
strOnClick = Me.GetClientValidate<br />
End If<br />
End If<br />
If MyBase.Attributes.Count > 0 And Not IsNothing(MyBase.Attributes("onclick")) Then<br />
strOnClick = String.Concat(MyBase.Attributes("onclick"), strOnClick)<br />
MyBase.Attributes.Remove("onclick")<br />
End If<br />
<br />
writer.AddAttribute("language", "javascript")<br />
writer.AddAttribute(HtmlTextWriterAttribute.Onclick, strOnClick)<br />
<br />
ElseIf Me.DisableAfterClick Or Me.ConfirmBeforeSubmit Then<br />
If Me.DisableAfterClick Then<br />
If Me.ConfirmBeforeSubmit Then<br />
strOnClick = Me.GetConfirmClickOnce<br />
Else<br />
strOnClick = Me.GetClickOnceJavascript<br />
End If<br />
Else<br />
If Me.ConfirmBeforeSubmit Then<br />
strOnClick = Me.GetConfirmJavascript<br />
End If<br />
End If<br />
<br />
If MyBase.Attributes.Count > 0 And Not IsNothing(MyBase.Attributes("onclick")) Then<br />
strOnClick = String.Concat(MyBase.Attributes("onclick"), strOnClick)<br />
MyBase.Attributes.Remove("onclick")<br />
End If<br />
<br />
writer.AddAttribute("language", "javascript")<br />
writer.AddAttribute(HtmlTextWriterAttribute.Onclick, strOnClick)<br />
End If<br />
<br />
MyBase.AddAttributesToRender(writer)<br />
<br />
End Sub<br />
<br />
Protected Overrides Sub OnInit(ByVal e As EventArgs)<br />
If Me.DisableAfterClick And Not Me.IsHiddenFieldRegistered Then<br />
MyBase.Page.RegisterHiddenField(Me.OnceClickBtnName, "")<br />
End If<br />
MyBase.OnInit(e)<br />
End Sub<br />
<br />
Private Function IsHiddenFieldRegistered() As Boolean<br />
For Each ctl As Control In MyBase.Page.Controls<br />
If TypeOf ctl Is HtmlControls.HtmlInputHidden Then<br />
If ctl.ID = Me.OnceClickBtnName Then<br />
Return True<br />
End If<br />
End If<br />
Next<br />
Return False<br />
End Function<br />
<br />
Protected Overridable Sub OnClick(ByVal e As EventArgs)<br />
RaiseEvent Click(Me, e)<br />
End Sub<br />
<br />
Protected Overridable Sub OnCommand(ByVal e As System.Web.UI.WebControls.CommandEventArgs)<br />
RaiseEvent Command(Me, e)<br />
End Sub<br />
<br />
Private Sub RaisePostBackEvent(ByVal eventArgument As String) Implements System.Web.UI.IPostBackEventHandler.RaisePostBackEvent<br />
If Me.CausesValidation Then<br />
MyBase.Page.Validate()<br />
End If<br />
Me.OnClick(New EventArgs)<br />
Me.OnCommand(New System.Web.UI.WebControls.CommandEventArgs(Me.CommandName, Me.CommandArgument))<br />
End Sub<br />
<br />
Private Function EscapedMessage(ByVal strMsg As String) As String<br />
Return Replace(ConfirmationMessage, "'", "\'")<br />
End Function<br />
<br />
End Class
-- modified at 10:49 Tuesday 2nd May, 2006
|
|
|
|
|
Hi,
Have u ever tested with asp.net/c#. I have tried to use your dll but it does not work with c# application, whereas it works fine with vb application.
Please solve this issue.
Compiler Error Message: CS0234: The type or namespace name 'ClickOnceButton' does not exist in the class or namespace 'ClickOnceButton.ClickOnceButton' (are you missing an assembly reference?)
-- modified at 1:55 Tuesday 2nd May, 2006
|
|
|
|
|
Hi Anjum Rizwi,
Simply add namespace to the vb class, like following:
Namespace ClickOnceButton<br />
<br />
<ToolboxData("<{0}:PromptClickOnceButton runat=""server"" />"), ToolboxBitmap(GetType(System.Web.UI.WebControls.Button)), DefaultEvent("Click")> _<br />
Public Class PromptClickOnceButton<br />
Inherits System.Web.UI.WebControls.WebControl<br />
Implements IPostBackEventHandler<br />
<br />
.....<br />
<br />
End Class<br />
<br />
End Namespace
The namespace name have to be different with the class name. Complile it, and then you could use the new dll in your C# project. I have tested it in a C# web application. It works fine.
By the way, I added a new feature to this PromptClickOnce button. The idea is from Mika. All buttons become disabled on the web form when one button is clicked. Only one property's code (GetClickOnceJavascript) is changed.
<br />
<Browsable(False)> _<br />
Friend ReadOnly Property GetClickOnceJavascript() As String<br />
<br />
Get<br />
<br />
Dim sb As New StringBuilder<br />
<br />
sb.Append("for(var f=0; f < document.forms.length; f++)")<br />
sb.Append("{")<br />
sb.Append("var lForm = document.forms[f];")<br />
sb.Append("for(var e=0; e < lForm.elements.length; e++)")<br />
sb.Append("{")<br />
sb.Append("var lElement = lForm.elements[e];")<br />
sb.Append("if (lElement.type == 'button' || lElement.type == 'submit')")<br />
sb.Append("lElement.disabled = true;")<br />
sb.Append("}")<br />
sb.Append("}")<br />
sb.Append("document.getElementsByName('")<br />
sb.Append(Me.OnceClickBtnName)<br />
sb.Append("').item(0).setAttribute('name',")<br />
sb.Append("this.getAttribute('name'));")<br />
<br />
If Not (DisabledText = String.Empty) Then<br />
<br />
sb.Append("this.value = '")<br />
sb.Append(DisabledText)<br />
sb.Append("';")<br />
<br />
End If<br />
<br />
sb.Append("this.form.submit();")<br />
<br />
Return sb.ToString()<br />
<br />
End Get<br />
<br />
End Property
Hope this can help you.
Xiang Qin
-- modified at 10:53 Tuesday 2nd May, 2006
|
|
|
|
|
Thank You qherb
for promt reply with solution
I have tested it is OK. Now I m going to use in my application
|
|
|
|
|
This is great, I think Microsoft should have added this functionality to ASP.NET 2.0 as standard.
I would like to see something like this with Images, where you can set
Image.Visible = True without refreshing, just like VB windows forms.
Thank you
|
|
|
|
|
I got the same assembly problem when adding it to C# project.
|
|
|
|
|
one issue that can happen with the implementation of this control is that if you do a javascript document.form.submit(), it will not fire the OnSubmit javascript event on the page, which I need for another control i developed. I came up with a solution. The following subroutine was changed:
Friend ReadOnly Property GetOnceClickJavascript() As String
Get
Return "document.getElementsByName('" + Me.OnceClickBtnName + "').item(0).setAttribute('name'," + _
"this.getAttribute('name')); this.disabled = true; " + _
IIf(DisabledText = String.Empty, String.Empty, "this.value = '" + DisabledText + "';") + _
Me.Page.GetPostBackEventReference(Me) & ";"
'"this.form.submit();"
End Get
End Property
notice the last part of the string now using GetPostBackEventReference. I just discovered this little function a few days ago. never even knew it existed, but it seems to work perfect. now i get a click once button that also fires the onsubmit event on the page.
|
|
|
|
|
Hey this thread is awesome! Thanks everybody for your input.
Here is my modified C# version - it's very simple and works pretty well for my purpose, but I'd like to extend it further.
- It works fine so that when you click a button:
it will disable ALL buttons, links and hyperlinks on the form until it reloads.
(to use this scenario, I send 'true' to the SetSafeButton() function.
The feature that is NOT working the way I'd like is that if you click the button and set the code to also disable things like textboxes, dropdown lists, and checkboxes(Sending 'false' to the SetSafeButton() function) - it will clear out their values. Does anybody have a quick fix for that one for the code below?
Thanks!!!
------------
<br />
private void Page_Load(object sender, System.EventArgs e)<br />
{<br />
if(!IsPostBack)<br />
setSafeAllControls(this.Page);<br />
}<br />
<br />
void setSafeAllControls(Page thispage)<br />
{<br />
foreach (Control elem in thispage.Controls)<br />
{<br />
if (elem.GetType().ToString().Equals("System.Web.UI.HtmlControls.HtmlForm"))<br />
{<br />
foreach (Control child in elem.Controls)<br />
{<br />
if (child.GetType().ToString().Equals("System.Web.UI.WebControls.Button"))<br />
{<br />
SetSafeButton(this.Page, true, (Button)child);<br />
}<br />
}<br />
}<br />
}<br />
}<br />
<br />
<br />
public static void SetSafeButton(Page thisPage, bool lockStaticControlsOnly, System.Web.UI.WebControls.Button button)<br />
{<br />
StringBuilder sb = new System.Text.StringBuilder();<br />
if(button.CausesValidation)<br />
{
sb.Append("if (typeof(Page_ClientValidate) == 'function') { ");<br />
sb.Append("if (Page_ClientValidate() == false) { return false; }} "); <br />
}<br />
sb.Append("this.disabled = true;");
foreach (Control elem in thisPage.Controls)<br />
if (elem.GetType().ToString().Equals("System.Web.UI.HtmlControls.HtmlForm"))
{<br />
foreach (Control child in elem.Controls)<br />
{<br />
if(!lockStaticControlsOnly)<br />
{<br />
switch(child.GetType().ToString().Replace("System.Web.UI.WebControls.",""))<br />
{<br />
case "Button":<br />
case "LinkButton":<br />
case "HyperLink":<br />
case "TextBox": <br />
case "CheckBox":<br />
case "CheckBoxList":<br />
case "RadioButton":<br />
case "RadioButtonList":<br />
sb.Append(child.ClientID+".disabled = true;");<br />
break;<br />
default:
break;<br />
}<br />
}<br />
else<br />
{<br />
switch(child.GetType().ToString().Replace("System.Web.UI.WebControls.",""))<br />
{
case "Button":<br />
case "LinkButton": <br />
case "HyperLink":<br />
sb.Append(child.ClientID+".disabled = true;");<br />
break;<br />
default:
break;<br />
}<br />
}<br />
}<br />
}<br />
sb.Append(thisPage.Page.GetPostBackEventReference(button));<br />
sb.Append(";");<br />
button.Attributes.Add("onclick", sb.ToString());<br />
}<br />
<br />
<br />
private void btnSubmit_Click(object sender, System.EventArgs e)<br />
{<br />
Thread.Sleep(2000);
Label1.Text+="<BR>OK"; <br />
}<br />
<br />
private void btnCancel_Click(object sender, System.EventArgs e)<br />
{<br />
Thread.Sleep(2000);
Label1.Text = ""; <br />
}<br />
Trond
|
|
|
|
|
ok so I plugged this in and realized it has bugs. If the page is already invalid from for example a requiredFieldValidator kicking in, and I click a button - the clicked button will just stay disabled - as Eric mentioned initially.
My goal for my approach is to have one function that I could invoke once per page (e.g. in page_load for a usercontrol for my projects navbar) that will scan the page automatically for buttons and attach the javascript to them... So if anyone has a suggestion on how to fix this, i'd be psyked!!!
Thanks again,
T
|
|
|
|
|
OK I got that bug fixed so now it seems pretty flawless - I'll post the code if anyone's interested. It is however limited to only work for buttons....
Trond
|
|
|
|
|
Hey Trondborg,
I am trying to use the DLL to implement it in my web solution which is written in C#. I am referencing the DLL, Added the modified button control to my Tool Box, added this control to the page with all required steps. When I run the page, I comeup with the following error (see below). It seems you were able to run this control in your c# code, what changes did you make? I dont understand the code which you posted. Please help!!
=================================================================================================
Compilation Error
Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.
Compiler Error Message: CS0234: The type or namespace name 'ClickOnceButton' does not exist in the class or namespace 'ClickOnceButton.ClickOnceButton' (are you missing an assembly reference?)
Source Error:
Line 1607:
Line 1608: private System.Web.UI.Control __BuildControlClickOnceButton1() {
Line 1609: ClickOnceButton.ClickOnceButton __ctrl;
Line 1610:
Line 1611: #line 240 "http://localhost/GiantBed/ControlModules/RegistrationForm.ascx"
Source File: c:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\Temporary ASP.NET Files\giantbed\48896e80\3e53f560\nhb1rk62.0.cs Line: 1609
|
|
|
|
|
I tink that is alot for work for the simple task you want to achieve. You could have simple made the button invisible and make another button that is disabled visible. But make sure that the new button is in the exact place as the old one, which would only take one line of code.
|
|
|
|
|
here is the script, copy and paste this script before </body> tag at the bottom of your page. do not forgot to change the button id/name. enjoy
<script language="javascript">
//Umar 10/27/2004
//Make sure the Page_ClientValidate function exists
if( typeof( Page_ClientValidate ) == "function" )
{
//Stash the old implementation in a temp variable
Page_ClientValidateOld = Page_ClientValidate;
//Create a new implementation and store it
//in Page_ClientValidate. Callers will now get
//this implementation.
Page_ClientValidate = function()
{
var isValid;
//Call the old implementation first…
isValid = Page_ClientValidateOld();
//and then call our extension
if(isValid)
{
document.frmMain.cmdSave.disabled=true;//disable button
}
return isValid;
}
}
</script>
|
|
|
|
|
Looks good Umar. The concept of this control was to make it packaged and all inclusive.
Both are simple, sure mine took a bit more code, but the end result is simply dragging and dropping the control onto your form and you're done with it.
thanks!
Eric
|
|
|
|
|
i found this on another forum, this worked the first time without adding a new webcontrol, the code goes in your Page_Load area (and you need to replace in 3 spots 'btnSubmit' with whatever your C# ASP.NET Button web control is called, it forces a postback after disabling the button, pretty sweet:
System.Text.StringBuilder sbValid = new System.Text.StringBuilder();
sbValid.Append("if (typeof(Page_ClientValidate) == 'function') { ");
sbValid.Append("if (Page_ClientValidate() == false) { return false; }} ");
sbValid.Append("this.value = 'Please wait...';");
sbValid.Append("this.disabled = true;");
sbValid.Append("document.all.btnSubmit.disabled = true;");
//GetPostBackEventReference obtains a reference to a client-side script function that causes the server to post back to the page.
sbValid.Append(this.Page.GetPostBackEventReference(this.btnSubmit));
sbValid.Append(";");
this.btnSubmit.Attributes.Add("onclick", sbValid.ToString());
James D. Semple
Boomtrek Travel Services
www.boomtrek.com
|
|
|
|
|
<br />
public static void SetSafeButton(Page thisPage, System.Web.UI.WebControls.Button button)<br />
{<br />
System.Text.StringBuilder sb = new System.Text.StringBuilder();<br />
sb.Append("if (typeof(Page_ClientValidate) == 'function') { ");<br />
sb.Append("if (Page_ClientValidate() == false) { return false; }} ");<br />
sb.Append("this.value = 'Please wait...';");<br />
sb.Append("this.disabled = true;");<br />
sb.Append(thisPage.Page.GetPostBackEventReference(button));<br />
sb.Append(";");<br />
button.Attributes.Add("onclick", sb.ToString());<br />
}
|
|
|
|
|
Wow! That really worked s_tarassov!!! Thanks - I love simplicity. For those of you who tried it and didn't see it probably thought it didn't work - ahh the code is quicker than the eye. Copy the function into your WebForm. In the Page_Load() function add the line: SetSafeButton(Page, Btn_MyButton); where Btn_MyButton is the button on your webform. Next add this function (or add the line to this function):
private void Btn_MyButton_Click(object sender, System.EventArgs e)
{
while(1==1); //WOW!!! It really does work! COOL!
}
This "while" loop will hold the pages attention indefinitally when you click the button, so now you can see the button's text change and become disabled.
WARNING: This "while" loop will put your CPU into over-drive, even if you stop the page and close the browser. What I did was simply open up the task-manager and kill the "aspnet_wp" worker process - this (in effect) restarts it. And there, it's no longer sucking up resources with our little infinite loop. Please do this on a development box as doing this type of testing on a live site will cause any users connected to re-login. A better way to test it would have been to loop like a million times, but each machine will crunch the same numbers differently - the best way to pause (I suppose) would be to take a time snapshot and add five seconds to it and check when then current time is greater than or equal to it - but this was just a simple test - so I didn't go that route.
|
|
|
|
|
YESSS IT WORKSSSS
I have spent hours trying to embed Eric Plowe's original DLL into my C# code. Though the concept of dragging and dropping from the toolbox is neat. It just doesnt work. But this method, though manual, seems to work perfectly.
Thanks,
Hyder
|
|
|
|
|
This code does not work if you have validator like required field validator. I just put a textbox and validator on a webform, then it does not fire button click event. If I remove validators, its fine.
Do you know how do I get it worked ?
Thanks
|
|
|
|
|
Hi,
I have used the following code in ASP.NET 1.1 and it seems to work.
Its a lot like the other code/technique I have seen.
*********************************************************
Javascript file
--------------------------------------------------------
/*
USAGE example:
- in pageload
Me.btnLogin.Attributes.Add("onClick", "DisableButton(" & Me.btnLogin.ClientID & ", '" & Me.btnLogin.ID & "', " & Me.Validators.Count & ");")
Me.Page.GetPostBackClientHyperlink(Me, "")
NOTE:
- MUST wrap the ID within single quotes
REF: http://aspzone.com/articles/207.aspx === does not work anymore???
*/
function DisableButton(field, id, validatorCount)
{
if (validatorCount > 0)
{
if (typeof(Page_ClientValidate) == 'function')
{
if (Page_ClientValidate() == false)
{
return false;
}
}
}
field.disabled = true;
__doPostBack(id,'');
}
*********************************************************
html design view of webform (to include javascript file)
--------------------------------------------------------
<HEAD>
<title>
<asp:Literal id="litHeader" runat="server"></asp:Literal>
</title>
<meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
<meta content="C#" name="CODE_LANGUAGE">
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
<LINK href="../css/Main.css" type="text/css" rel="stylesheet">
<script language="JavaScript" src="../javascript/FormFunctions.js" type="text/javascript"></script>
</HEAD>
*********************************************************
C# code-behind usage
--------------------------------------------------------
private void Page_Load(object sender, System.EventArgs e)
{
if (!this.IsPostBack)
{
//trying to have a "one-click" button
this.btnClear.Attributes.Add("onClick",
"DisableButton(" + this.btnClear.ClientID +
", '" +
this.btnClear.ID +
"', " + this.Validators.Count +
");");
this.btnSubmit.Attributes.Add("onClick",
"DisableButton(" + this.btnSubmit.ClientID +
", '" +
this.btnSubmit.ID +
"', " + this.Validators.Count +
");");
this.Page.GetPostBackClientHyperlink(this, "");
}//if (!this.IsPostBack)
}//Page_Load
That seems to do the trick for me, even if webform has valdators.
Good luck
Sheir
|
|
|
|
|
This is such a hack, but it works great. I'm not doing any validation, so I cannot speak to that, but this code does work with the UpdatePanel/UpdateProgress controls.
In ASP.NET 2.0, the GetPostBackEventReference method (in the Page class) is deprecated, so to get rid of the warning, change the thisPage.GetPostBackEventReference line to:
sb.Append(thisPage.ClientScript.GetPostBackEventReference(button, ""));
|
|
|
|
|
I converted the code to work with an ImageButton. Didnt test it with validation controls. Will display and preload a disabled image when the user clicks the button
Imports System.ComponentModel
Imports System.Web.UI
Imports System.Drawing
<toolboxbitmap(gettype(system.web.ui.webcontrols.imagebutton)), defaultevent("click"),="" defaultproperty("imageurl")=""> _
Public Class ClickOnceImage
Inherits System.Web.UI.WebControls.WebControl
Implements IPostBackEventHandler
Public Event Click As EventHandler
Public Event Command As System.Web.UI.WebControls.CommandEventHandler
Private Const OnceClickBtnName As String = "__onceClickImageBtn"
<browsable(true), category("behavior")=""> _
Public Property DisableAfterClick() As Boolean
Get
Dim o As Object = MyBase.ViewState("DisableAfterClick")
Return IIf(IsNothing(o), True, CBool(o))
End Get
Set(ByVal Value As Boolean)
MyBase.ViewState("DisableAfterClick") = Value
End Set
End Property
<browsable(true), category("behavior")=""> _
Public Property CommandName() As String
Get
Dim o As Object = MyBase.ViewState("CommandName")
Return IIf(IsNothing(o), String.Empty, CStr(o))
End Get
Set(ByVal Value As String)
MyBase.ViewState("CommandName") = Value
End Set
End Property
<browsable(true), category("behavior")=""> _
Public Property CommandArgument() As String
Get
Dim o As Object = MyBase.ViewState("CommandArgument")
Return IIf(IsNothing(o), String.Empty, CStr(o))
End Get
Set(ByVal Value As String)
MyBase.ViewState("CommandArgument") = Value
End Set
End Property
<browsable(true), category("appearance"),="" _
="" editorattribute(gettype(urlgraphiceditor),="" gettype(system.drawing.design.uitypeeditor)),="" defaultvalue(""),="" description("the="" disabled="" image")=""> _
Public Property ImageUrlDisabled() As String
Get
Dim o As Object = MyBase.ViewState("ImageUrlDisabled")
Return IIf(IsNothing(o), String.Empty, CStr(o))
End Get
Set(ByVal Value As String)
MyBase.ViewState("ImageUrlDisabled") = Value
End Set
End Property
<browsable(true), category("appearance"),="" _
="" editorattribute(gettype(urlgraphiceditor),="" gettype(system.drawing.design.uitypeeditor)),="" defaultvalue(""),="" description("the="" image="" to="" display")=""> _
Public Property ImageUrl() As String
Get
Dim o As Object = MyBase.ViewState("ImageUrl")
Return IIf(IsNothing(o), String.Empty, CStr(o))
End Get
Set(ByVal Value As String)
MyBase.ViewState("ImageUrl") = Value
End Set
End Property
<browsable(true), category("behavior")=""> _
Public Property CausesValidation() As Boolean
Get
Dim o As Object = MyBase.ViewState("CausesValidation")
Return IIf(IsNothing(o), True, CBool(o))
End Get
Set(ByVal Value As Boolean)
MyBase.ViewState("CausesValidation") = Value
End Set
End Property
Public Sub New()
MyBase.New(HtmlTextWriterTag.Input)
End Sub
<browsable(false)> _
Friend ReadOnly Property GetClientValidateEvent() As String
Get
Return "if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate(); "
End Get
End Property
<browsable(false)> _
Friend ReadOnly Property GetClickOnceClientValidateEvent() As String
Get
Return "if (typeof(Page_ClientValidate) == 'function') { if(Page_ClientValidate()) { " + _
GetOnceClickJavascript + " }} else { " + _
GetOnceClickJavascript + " }"
End Get
End Property
<browsable(false)> _
Friend ReadOnly Property GetOnceClickJavascript() As String
Get
Return "document.getElementsByName('" + Me.OnceClickBtnName + "').item(0).setAttribute('name'," + _
"this.getAttribute('name')); this.disabled = true; " + _
IIf(ImageUrlDisabled = String.Empty, String.Empty, "this.src = '" + ImageUrlDisabled + "';") + _
"this.form.submit();"
End Get
End Property
<browsable(false)> _
Friend ReadOnly Property GetClientPreLoadScriptBlock() As String
Get
Return "" + _
"var imgSaveButtonAlternate = new Image().src = '" & Me.ImageUrlDisabled & "'" + _
""
End Get
End Property
Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)
End Sub
Protected Overrides Sub AddAttributesToRender(ByVal writer As HtmlTextWriter)
Dim strOnClick As String
If IsNothing(MyBase.Page) Then
MyBase.Page.VerifyRenderingInServerForm(Me)
End If
writer.AddAttribute(HtmlTextWriterAttribute.Type, "image")
writer.AddAttribute(HtmlTextWriterAttribute.Name, MyBase.UniqueID)
writer.AddAttribute(HtmlTextWriterAttribute.Src, Me.ImageUrl)
If Not IsNothing(MyBase.Page) And Me.CausesValidation And MyBase.Page.Validators.Count > 0 Then
If Me.DisableAfterClick Then
strOnClick = Me.GetClickOnceClientValidateEvent()
Else
strOnClick = Me.GetClientValidateEvent()
End If
If MyBase.Attributes.Count > 0 And Not IsNothing(MyBase.Attributes("onclick")) Then
strOnClick = String.Concat(MyBase.Attributes("onclick"), strOnClick)
MyBase.Attributes.Remove("onclick")
End If
writer.AddAttribute("language", "javascript")
writer.AddAttribute(HtmlTextWriterAttribute.Onclick, strOnClick)
ElseIf DisableAfterClick = True Then
strOnClick = GetOnceClickJavascript()
If MyBase.Attributes.Count > 0 And Not IsNothing(MyBase.Attributes("onclick")) Then
strOnClick = String.Concat(MyBase.Attributes("onclick"), strOnClick)
MyBase.Attributes.Remove("onclick")
End If
writer.AddAttribute("language", "javascript")
writer.AddAttribute(HtmlTextWriterAttribute.Onclick, strOnClick)
End If
MyBase.AddAttributesToRender(writer)
End Sub
Protected Overrides Sub OnInit(ByVal e As EventArgs)
If Me.DisableAfterClick And Not Me.IsHiddenFieldRegistered Then
MyBase.Page.RegisterHiddenField(Me.OnceClickBtnName, "")
Me.Page.RegisterClientScriptBlock("ImagePreLoad", GetClientPreLoadScriptBlock)
End If
MyBase.OnInit(e)
End Sub
Private Function IsHiddenFieldRegistered() As Boolean
For Each ctl As Control In MyBase.Page.Controls
If TypeOf ctl Is HtmlControls.HtmlInputHidden Then
If ctl.ID = Me.OnceClickBtnName Then
Return True
End If
End If
Next
Return False
End Function
Protected Overridable Sub OnClick(ByVal e As EventArgs)
RaiseEvent Click(Me, e)
End Sub
Protected Overridable Sub OnCommand(ByVal e As System.Web.UI.WebControls.CommandEventArgs)
RaiseEvent Command(Me, e)
End Sub
Private Sub RaisePostBackEvent(ByVal eventArgument As String) Implements System.Web.UI.IPostBackEventHandler.RaisePostBackEvent
If Me.CausesValidation Then
MyBase.Page.Validate()
End If
Me.OnClick(New EventArgs)
Me.OnCommand(New System.Web.UI.WebControls.CommandEventArgs(Me.CommandName, Me.CommandArgument))
End Sub
End Class
Public Class UrlGraphicEditor
Inherits System.Web.UI.Design.UrlEditor
Protected Overrides ReadOnly Property Caption() As String
Get
Return "Select Image"
End Get
End Property
Protected Overrides ReadOnly Property Filter() As String
Get
Return "Image Files(*.gif,*.jpg,*.jpeg)|*.gif;*.jpg;*.jpeg;|All Files(*.*)|*.*"
End Get
End Property
End Class
Martin
|
|
|
|
|
Your code has a lot of underscores ("_") that make it look like some attributes you added are missing.
You also have code similar to the following where it's clear that the leading "<" is missing.
Martin McNally wrote:
EditorAttribute(GetType(UrlGraphicEditor), GetType(System.Drawing.Design.UITypeEditor)), _
DefaultValue(""), _
Description("The image to display")> _
Public Property ImageUrl() As String
Can you make your code available for DL somewhere?
|
|
|
|
|
|
Great control, thanks Eric. I would really love to see this as an ImageButton.
|
|
|
|
|