Ask for client side confirmation when a DevExpress ASPxCheckBox changes - javascript

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);}
}

Related

onbeforeunload and asp:Update Panel in Safari and FireFox

I am working on a asp.net (framework 4) that has a requirement for the user to be notified if they are trying to leave the page without saving changes. Well I found a solution by calling the onbeforeunload function via JavaScript. Works great in IE but not in Firefox, Safari or Chrome.
Now here is where the problem comes in. I’m using AJAX postbacks and if the user is prompted to save the changes before leaving the page, any controls inside of the update panel no longer will postback to the server. For example, if a press the save button that is inside of the update panel, nothing happens.
Here are some code snippets
javascript:
window.onbeforeunload = function (e) {
if (doBeforeUnload() == true) {
var ev = e || window.event;
// For IE and Firefox prior to version 4
if (ev) {
ev.returnValue = "You have modified the data entry fields since the last time it was saved. If you leave this page, " +
"any changes will be lost. To save these changes, click Cancel to return to the page, and then Save the data.";
}
// For Safari
return "You have modified the data entry fields since the last time it was saved. If you leave this page, " +
"any changes will be lost. To save these changes, click Cancel to return to the page, and then Save the data.";
}
}
ASP.NET:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" >
<ContentTemplate>
<%--no controls inside of this panel will postback to server if user clicks the “Stay on Page” button--%>
</ContentTemplate>
</asp:UpdatePanel>
Seems to be plenty of posts on the net but no solutions. Any ides besides not using async postbacks?
I came across this question when I was searching for the similar issue. I was able to solve this by doing the following:
var doOnBeforeUnloadCheck = true; // global to set in link button
window.onbeforeunload = function (e) {
if (doOnBeforeUnloadCheck && doBeforeUnload()) {
// do stuff
}
// Make sure to always re-enable check to ensure the event will still trigger
// where not specified to disable event.
doOnBeforeUnloadCheck = true;
}
In a LinkButton you just make sure to set the global to false before running any other javascript or doing the postback:
<asp:LinkButton ID="yourButton" runat="server"
OnClientClick="doOnBeforeUnloadCheck = false;" OnClick="yourButton_Click" />
I came across this solution with help from the following link:
http://www.jimandkatrin.com/CodeBlog/post/LinkButton-UpdatePanel-onbeforeunload.aspx
I found this question before I found my answer so if anyone else has the same issue this might save them some time. Hope that helps.

Stop ImageButton OnCommand postback using javascript in asp.net 4.0 (Internet Explorer)

It looks like the Internet Explorer demon has struck again, and I cannot seem to figure this one out:
I have an ImageButton using OnCommand to delete a specific entry from my database. I however have implemented it so that the user will first confirm that they want to delete a specific item.
Here is the code for my ImageButton
<asp:ImageButton runat="server" ID="imgDelete" ImageUrl="~/Controls/TaskDetails/Images/delete.png" OnCommand="Tag_DeleteCommand" Visible='<%# CanDelete %>' OnClientClick="javascript:confirmDialog(this, 'Remove Tag','Are you sure you want to remove this tag?', 1); return false;"
CommandArgument='<%# Eval("TagID") %>' />
And here is my ConfirmDialog function
function confirmDialog(sender, title, message, type) {
//type entities
//1 = warning
//2 = error
//3 = success
//4 = Information
var sender = $(sender);
$("#message_dialog_inner_text").html(message);
$("#message_dialog_message_container").dialog({
modal: true,
title: title,
zIndex: 10003,
dialogClass: (type > 0) ? "message_dialog_type_" + type : "",
position: 'center',
buttons: {
"OK": function () {
//the yes option was selected, we now disable the onclientclick event, and fire the click event.
$(this).dialog("close");
if (sender.hasAttr("href")) {
window.location = sender.attr('href');
} else {
sender.removeAttr("onclick");
sender.trigger("click");
}
},
"Cancel": function () { $(this).dialog("close"); }
}
});
return false;
}
This works fine in Chrome, FF, Safari, but IE is just ignoring it and doing the postback. I have even changed my OnClientClick to "return false;" and it seems to have no impact on the button posting back. I have also changed it from an ImageButton to just a Button, to no avail. I am assuming it has something to do with the OnCommand event, but right I am at a loss! I have implemented this througout a pretty huge application, so I would like to manage the scope of the change. If anyone has some input, it would be greatly appreciated!
EDIT
OK, let me also just stress, I don't want it to post back, and even if I just have OnClientClick="return false;" the command button is still posting back (not what you would expect).
Here is the rendered markup from my ImageButton control
<input type="image" name="ctl00$body$pnlContentRight$pnlCurrentTaskDetails$repTags$ctl00$tagItem$imgDelete" id="ctl00_body_pnlContentRight_pnlCurrentTaskDetails_repTags_ctl00_tagItem_imgDelete" src="Controls/TaskDetails/Images/delete.png" onclick="javascript:confirmDialog(this, 'Remove Tag','Are you sure you want to remove this tag?', 1); return false;" style="border-width:0px;">
This isn't a resolution to your specific issue, but it's a workaround you may want to consider (I've used it in a couple of places):
Make your "delete" button a simple image, not a postback button.
Give it an OnClientClick which calls a local javascript function (passing the relevant data - at a minimum, the ID of the item to be deleted).
That local JS function loads the relevant data into a hidden var (so it can be accessed in your code-behind), and opens the jQuery confirm dialog.
That dialog is configured with NO jquery-dialog buttons. Instead, the launched DIV contains two asp:Buttons: ok and cancel. The cancel button simply closes the jQuery dialog. The OK button is a normal postback button with a server-side OnClick function.
Thus, the page is only posted-back if the user clicks the OK button on the confirm dialog. The confirm-dialog-event function knows which item to delete because that item's ID is in the hidden field.
This is probably not the "right" way to implement this behavior (from an ASP.NET purist standpoint). However, as workarounds go, I don't think it's too painfully kuldgey. And in my experience, it seems to work across all browsers (assuming they have JS enabled, of course). HTH.
You're OnClientClick is always returning false, which means that the event will never be executed. Try returning the input from the confirm like this:
OnClientClick="return confirmDialog(...);"
You will need to make sure that there is a way to return true from the confirmDialog function too. It looks like that function always returns false too.
I'm not very familiar with the jQuery UI dialog, but in concept it should work like this:
buttons: {
"OK": function () { return true; }, //perform a postback and execute command
"Cancel": function () { return false; } //abort postback and do nothing
}

ASP.net - Button - Javascript Confirm dialog - execute SOME server-side code?

I have a simple ASP.net page where users can edit information about themselves.
When "Edit" button is clicked, the form goes into edit mode and I display "Save" and "Cancel" buttons, which behave as expected.
What I want to do is this:
When "Save" is clicked, display a Javascript Confirm dialog asking the user if they want to send an email to the other users to inform them of the update just made.
If user says OK, then execute all server-side code to save the data, AND send an email.
If user says Cancel, then execute all server-side code to save the data, WITHOUT sending the email.
So, I need the javascript box to set a flag which can then be read server-side, somehow... then I can do something like:
Sub btnSave_Click(sender, e) Handles btnSave.Click
'Save all the data
If sendEmail Then 'This flag set by reading result of javascript Confirm
'Send the email
End If
End Sub
I know how to add a Confirm box to the button Attributes, and have done so. I'm looking for an answer on how to read the result of that box on server side... in other words, I ALWAYS want the Page postback to happen (from clicking the button), but only SOME of the event-handler code to execute.
Hope that makes sense.
Thanks
Matt
Create a hidden field, and set the value of that field based on the result of the confirmation. You haven't shown the code/HTML for your button or form, but can you fit something like this into it:
<input type="hidden" id="sendEmail" name="sendEmail" value="" />
<input type="submit" value="Save" onclick="promptForEmail();" />
<script>
function promptForEmail() {
var result = Confirm("Send everybody an email?");
// set a flag to be submitted - could be "Y"/"N" or "true"/"false"
// or whatever suits
document.getElementById("sendEmail").value = result ? "Y" : "N";
}
</script>
There are several ways to do it but I am going to use asp:HiddenField. In javascript, after user confirms, let its result to be set in the hidden field. And in server side, you can access it like any other asp.net control.
So
your aspx:
<asp:HiddenField ID="HiddenField1" runat="server" Value="" />
CodeBehind:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
var result = HiddenField1.Value;
}
}
Javascript:
//after confirm call this
function SetValue(val)
{
document.getElementById('HiddenField1').value=val;
}

change text of asp.net button with 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.

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