change text of asp.net button with javascript - javascript

I have a form submit button that has asp.net validators hooked up to it. If I make a javascript function to change the text to processing on click it does not work. The button flags the validators and also causes the whole page to post back. Heres the code I have:
C#
protected void Page_Load(object sender, EventArgs e)
{
btnPurchase.Attributes["onClick"] = "submit()";
}
Html
<script type="text/javascript">
function submit() {
document.getElementById("ctl00_ContentPlaceHolder1_btnPurchase").value = "Processing";
};
</script>
My goal is to change the buttons text to purchasing onclick if the form passes validation, and then in my code behind it will change back to the original value once the form posts back.

I ran across this solution which works 100% perfect. I'm using the script manager with update panels...
<script type="text/javascript">
// Get a reference to the PageRequestManager.
var prm = Sys.WebForms.PageRequestManager.getInstance();
// Using that prm reference, hook _initializeRequest
// and _endRequest, to run our code at the begin and end
// of any async postbacks that occur.
prm.add_initializeRequest(InitializeRequest);
// Executed anytime an async postback occurs.
function InitializeRequest(sender, args) {
// Get a reference to the element that raised the postback,
// and disables it.
$get(args._postBackElement.id).disabled = true;
$get(args._postBackElement.id).value = "Processing...";
}
// Executed when the async postback completes.
function EndRequest(sender, args) {
// Get a reference to the element that raised the postback
// which is completing, and enable it.
$get(args._postBackElement.id).disabled = false;
$get(args._postBackElement.id).value = "Purchase";
}
</script>

I just asked a very similar question (which was answered):
ASP.NET Custom Button Control - How to Override OnClientClick But Preserve Existing Behaviour?
Essentially you need to preserve the existing behaviour of the submit button (__doPostBack). You do this with Page.GetPostBackEventReference(myButton).
However with validation it's more difficult, so you'll need to do page validation inline (Page.Validate()) or create a custom control like i did and override the OnClientClick and PostBackOptions members.
Custom control is better, as i can now just drop this control on any page i want this behaviour.
You could do the same and expose a public property:
public string loadingText {get; set;}
Which could be used to customise the loading text on each page.
You basically need to set the onclick attribute to do the following:
onclick = "if (Page_Validate()) this.text = 'Processing';{0} else return false;"
{0} should be the regular postback action, retrieved from Page.GetPostBackEventReference.
The resulting logic will be: on click, validate the page, it it succeeds, change the text and postback, if it fails, return false - which will show the validation on the page.
Have the button set to default text "Submit" in the HTML, then wrap the above logic in !Page.IsPostBack so it will reset the text on form submit.
Hope that helps.

Related

JavaScript PopUp appears only ONCE on a page per user in ASP.NET

This is something I already know the answer to but I want to come up with a better way. I have a dropdown within a gridview. Within the method that populates the dropdown data I'm adding an an "onchange" attribute to the dropdown. The onchange calls a javascript function that is then used to fire a popup based on what the user selects on the dropdown.
My issues is I want the popup to display only once within that current page for that user. The easiest answer is to use JavaScript sessionStorage to store some dummy value that is checked before the javascript popup code is run and then set afterwards.
The problem I'm having is that I then have to manage the storage by either clearing the storage when the user goes to another page by attaching storage.clear to all the buttons dealing with moving to another page.
Is there a way that I can clear the storage after the person moves to another page other than the page they are on. BTW the dropdowns and javascript are all located within an ASP.NET custom control. That custom control is loaded within several pages, therefore I want the logic to be isolated within the custom control so that I don't have to make changes to every page that uses the control and for modularity.
You can in the page on load, just set a global js var to the page like this:
protected void Page_Load(object sender, EventArgs e)
{
string script;
if (IsPostBack)
{
script = "var isPostBack = true;";
}
else
{
script = "var isPostBack = false;";
}
Page.ClientScript.RegisterStartupScript(GetType(), "IsPostBack", script, true);
}
So, now in your js code, you can use isPostBack as a simple true/false var.

How do I pass in postback argument from JS to VB?

I am trying to pass in an image from an image editor to a function in VB. I have it setup as the following:
JS
var canvas = document.getElementById("canvas_minipaint");
var img = canvas.toDataURL("image/jpeg");
__doPostBack('SaveImage', img);
ASPX
<asp:LinkButton ID="SaveImage" runat="server" Visible="true"></asp:LinkButton>
VB
Private Sub SaveImage_Click(sender As Object, e As EventArgs) Handles SaveImage.Click
Call GetSession()
End Sub
When I click the SaveImage button right now i get the following error:
Invalid postback or callback argument. Event validation is enabled using in configuration or <%# Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.
How do I register the onClick for the button for the validator? Or am I missing something else?
Turn off event validation for this page. You can turn it off at page level by adding
Page EnableEventValidation="false"
to the top of your .aspx page. I would recommend doing that in this case, since you are doing a manual postback using JavaScript. It is not possible to turn it off for individual controls.
EDIT:
You could always store the value of the image in a hidden field, and that would prevent the need to disable event validation. You'd need a way of storing the image data (base64 string maybe?) in the field, but it would work.
I would suggest not disabling the EventValidation to avoid malicious users to mess with the form. You could store the data in an input hidden or override the page event and handle it.
protected override void RaisePostBackEvent(IPostBackEventHandler sourceControl, string eventArgument)
{
if (sourceControl is yourControl)
{
//sanitize data
}
}

Ask for client side confirmation when a DevExpress ASPxCheckBox changes

I'm trying to add a confirmation dialog to have the user confirm changes to the checked status of an ASPxCheckBox.
Take 1
Based on this DevExpress support center question I'm trying the following code:
<dx:ASPxCheckBox ID="ASPxCheckBox1" runat="server">
<ClientSideEvents CheckedChanged="ConfirmChange" />
</dx:ASPxCheckBox>
With this JavaScript:
function ConfirmChange (s, e) {
console.log(s);
console.log(e);
return false; // For testing
// return confirm(); // Should become this
}
I was hoping/expecting the return false bit to prevent the change, but it happens nonetheless. I've gone through the console logged parameters to see if I can affect anything there, but doesn't look like it. I've also read the CheckedChanged DevExpress documentation but it holds no clue to my purpose either.
Take 2
I've also tried doing this in code behind:
var checkbox = (ASPxCheckBox)myGridView.FindEditRowCellTemplateControl(myCol, "ASPxCheckBox1";
checkbox.Attributes.Add("onclick", "return confirm('You sure?')")
This also pops up the confirm dialog, which fails to prevent a change if cancel is clicked.
Take 3
Finally, based a suggestion in one of the early answers here, I've also tried going the validation route:
<dx:ASPxCheckBox ID="ASPxCheckBox1" runat="server">
<ClientSideEvents Validation="ConfirmChange" />
</dx:ASPxCheckBox>
JavaScript:
function ConfirmChange (s, e) {
e.isValid = confirm();
}
However, this doesn't prevent or revert the change, but presents a validation error if you hit cancel in the confirm dialog.
So, bottom line
How can I inject a client side confirmation dialog before the ASPxCheckBox's change happens?
You cannot prevent the change in ASPxClientCheckBox.CheckedChanged event because this event occurs on the client side when the editor's checked state is changed. You can revert value by using ASPxClientCheckBox.GetChecked method and ASPxClientCheckBox.SetChecked method.
Here is example:
<dx:ASPxCheckBox ID="ASPxCheckBox1" runat="server">
<ClientSideEvents CheckedChanged="ConfirmChange" />
</dx:ASPxCheckBox>
JavaScript:
function ConfirmChange (s, e) {
console.log(s);
console.log(e);
//Save the checked state
value = s.GetChecked();
//Revert changes immediately
s.SetChecked(!s.GetChecked());
result = false; // For testing
// result = confirm(); // Should become this
if (result) {s.SetChecked(value);}
}

launch two actions in one button ASP.NET

I'm developing a comment page in asp.net, this my page :
<form action="#">
<p><textarea id="textArea" rows="5" cols="30"></textarea></p>
<input type="submit" value="Submit" />
</form>
<p>Add some comments to the page</p>
And this is my javascript code :
window.onload = initAll;
function initAll() {
document.getElementsByTagName("form")[0].onsubmit = addNode;
}
function addNode() {
var inText = document.getElementById("textArea").value;
var newText = document.createTextNode(inText);
var newGraf = document.createElement("p");
newGraf.appendChild(newText);
var docBody = document.getElementsByTagName("body")[0];
docBody.appendChild(newGraf);
return false;
}
Until then, everything is fine, but I want when the user clicks the submit button, the button will trigger another action that will save the comment in the database.
How can I do this thing ?
Why don't you have a wrapper and still make it one function?
The addNode could have code to do both maybe based on something in the form?
You could have a submit function that wraps the addNode and addComment.
eg:
function handleSubmit()
{
addNode();
addComment();
return false;
}
EDIT: Since you want to call server code you have a couple of options. You can do it all via ajax and you would just need to implement the addComment function to call a server side event. See this article if you need help doing so:
http://www.dexign.net/post/2008/07/16/jQuery-To-Call-ASPNET-Page-Methods-and-Web-Services.aspx
The easiest way would be to change your button to an ASP.NET button and then implement the button click event which would call your server side method although this would cause a full page refresh.
A hybrid of the two, which is very easy to implement, would be to use an UpdatePanel. When you clicked your button you would get the look and feel of the AJAX solution but only need to know how to do all the server side code and let the UpdatePanel handle all the AJAX work. This method is a little heavier than just doing a raw ajax call but it is significantly more simple to do.
You can read up on UpdatePanels at: http://msdn.microsoft.com/en-us/library/bb399001.aspx
Instead of using an HTML input tag, use asp:Button, like so:
<asp:Button ID="btnSubmit" runat="server" OnClick="btnSubmit_Click" />
What this says is, use a Button that calls the "btnSubmit_Click" method whenever it is clicked on, and run this on the server (not on the client machine).
Then in your code-behind (you do have a code-behind, right? e.g., nameOfPage.aspx.cs), you can add the aforementioned btnSubmit_Click method:
protected void btnSubmit_Click(object sender, System.EventArgs e) {
// interact with database here.
}

How to programmatically change the OnClientClick event and call it?

I have a ListView that contains playlists. If the user wants to edit an album, they click the edit link and it allows them to remove or add songs to the playlist. If the user wants to Save a new playlist while keeping the original one, the would click a Save As Button. Here is what should happen:
If the user clicks Save As and they have not changed the name, I want to display an alert telling them they must change the name.
If the user clicks the Save As and they have changed the name, I want to display an a confirmation that they actually want to save it.
Currently, what is happening is that if I put something like the following in my code behind, the script does not register until the second click and whatever script was registered stays registered meaning that if I end up changing the name and the alert script was registered before, it will display the alert instead of the confirmation. Here is the code:
if (newname == oldname)
{
btnSaveAs.OnClientClick =
"javascript:alert('Save As requires you to change the name of the playlist. Please
change the name and try again.');";
}
else
{
btnSaveAs.OnClientClick = "javascript:confirm('Are you sure you want to save the
playlist" + newname + "?');";
}
I also tried adding the return false so it would not do a postback, but if I do that, then it does not doesn't actually do anything when I click OK on the confirmation.
What SLaks said is correct, you're misunderstanding the page lifecycle. The javascript code needs to be in place on the page before you click Save As. In your example as described, the user makes changes to the title/name and clicks Save As, after which the javascript code is applied to the button. The second time they click Save As, the validation results from the previous example pop up.
Option 1: Use a validator control
The simplest way to solve this is to use a RegularExpressionValidator control to compare the values.
Markup snippet:
<asp:Label ID="lblName" runat="server" Text="Name: " />
<asp:TextBox ID="txtName" runat="server" />
<asp:RegularExpressionvalidator ID="valName" runat="server" ControlToValidate="txtName" ErrorMessage="You must change the name before saving" Display="Dynamic" />
<asp:Button ID="btnSaveAs" runat="server" OnClick="btnSaveAs_Click" Text="Save As" CausesValidation="True" />
In your code-behind once the form fields (album name, etc.) are bound, run this:
valName.ValidationExpression = string.Format("[^{0}]", Regex.Escape(lblName.Text));
The above regular expression will be valid for any input except what was there to begin with. If the user changes the text for the album name, the save button will validate correctly. If they do not, the validator will kick in and display a message on the page saying they have to change it.
Then handle the OnClick event of the save button only for saving the values, because it will only fire if the page was validated:
protected void btnSaveAs_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
//do you save actions as needed
}
}
You can also still use your confirm box as you wanted, by doing:
protected void Page_Load(object sender, EventArgs e)
{
btnSave.OnClientClick = "return confirm('Are you sure you wish to change the name?');";
}
The above should work just fine. An alternate approach is listed below:
Option 2: Use a clientside validation function
If you wanted to do the validation completely client side, you could but it will be far more complicated. What you'd need to do, is register a completely clientside validation function.
In your code behind during Page_PreRender:
protected void Page_PreRender(object sender, EventArgs e)
{
//define the script
string script = #"
function validateAlbumName(oldName, textBoxId) {
//get the textbox and its new name
var newName = document.GetElementById(textBoxId).value;
//compare the values
if (newName === oldName) {
//if the name hasn't changed,
alert('You must change the name of the album');
return false;
}
return confirm ('Are you sure you want to save the playlist ' + newName);
}
";
//register the client script, so that it is available during the first page render
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "SaveAsValidation", script);
//add the on client click event, which will validate the form fields on click the first time.
btnSaveAs.OnClickClick = string.Format("return validateAlbumName('{0}','{1}');", txtAlbumName.Text, txtAlbumName.ClientID);
}
Hope this helps. There are likely some syntax errors in the above as I just threw it together quickly..
The OnClientClick property is a Javascript string, not a URI. Therefore, you should not begin it with javascript:.
To handle the confirm correctly, write OnClientClick = "return confirm('Are you sure?');";
Also, you're misunderstanding the ASP.Net page model.
Your C# code-behind event handler only runs after the user clicks the button and after the OnClientClick callback. You need to write all of that in Javascript and call it in OnClientClick.

Categories