Related
So I am trying to change the confirm boxes in my application to something a bit more stylish.
The jquery-confirm.js add on was very appealing but I am really struggling to get it to work the way I want.
I have a simple link button on the page.
<asp:LinkButton ID="lnkDelete" CssClass="btn btn-danger" runat="server" OnClientClick="return ShowConfirm();" CommandArgument='<%#Eval("StatusId")%>' OnClick="DeleteStatus">
On their site this is the recommended implementation, but it doesn't return a value or stop postback.
$.confirm({
title: 'Encountered an error!',
content: 'Something went downhill, this may be serious',
type: 'red',
typeAnimated: true,
buttons: {
tryAgain: {
text: 'Try again',
btnClass: 'btn-red',
action: function(){
}
},
close: function () {
}
}
});
I understand that I can move my onclick function into this, however it then will not be reusable. I just want to stop postback when the user hits cancel. That way I can call it from anywhere and it will just work.
I tried a few things to no avail here are a few examples.
None of these stop the postback, but thought I should include what I have tried.
function ShowConfirm() {
var Confirmed = $.confirm({
title: 'Please Confirm!',
content: 'Are you sue that you want to delete this record?',
type: 'red',
typeAnimated: true,
buttons: {
tryAgain: {
text: 'Delete',
btnClass: 'btn-red',
action: function () {
this.preventDefault();
}
},
close: function () {
}
}
});
return Confirmed;
}
Another one
function confirmation() {
var defer = $.Deferred();
$.confirm({
title: 'Please Confirm!',
content: 'Are you sue that you want to delete this record?',
type: 'red',
typeAnimated: true,
buttons: {
tryAgain: {
text: 'Delete',
btnClass: 'btn-red',
action: function () {
//Do something
defer.resolve(true);
}
},
close: function () {
//Do Something
defer.resolve(false);
}
}
});
return defer.promise();
};
function ShowConfirm() {
confirmation().then(function (answer) {
console.log(answer);
ansbool = (String(answer) == "true");
if (ansbool) {
alert("this is obviously " + ansbool);//TRUE
} else {
alert("and then there is " + ansbool);//FALSE
}
});
}
I also tried the last one with sending a return value, but that doesn't work either.
My onclick server side code always executes.
Any Help would be greatly appreciated.
Ok, so the way this works?
In near "every" case, using some jQuery.UI dialog, sweetalert and in 99% of cases?
These jQuery and JavaScript add-ins ALL, and in ALL cases have one huge "similar" aspect:
that is the code does not wait, nor block the calling code.
The technical term for this type of code is what we call asynchronous.
In a nut shell, WHEN you call such code, the prompt dialog or whatever WILL display, but the code does NOT halt. The routine you call will 100% RUN though its code, display the dialog or whatever and THEN 100% finish, exit and return the value.
The reason for such code is to NOT freeze up the browser, not damage the re-plot, and display of information.
As a result, about the only two commands in JavaScript that actually halt code is
"alert()", and confirm().
The above two commands will halt code. Thus, your question:
You have a plane jane button, and say some code to delete or perform a damaging option, then we all wired up code like this:
<asp:Button ID="cmdDelete" runat="server" Text="Server delete prompt"
OnClientClick="return confirm('Really delete this file?');" />
And, as we know, if user hits cancel, then the button code does not run.
However, what about those js add-ins, and fancy dialogs? Well, they do NOT wait.
I don't have your particular js add-in, but since we all use jQuery, then I give an example how to do this with jQuery.UI.
So, we take the above button, and now do this:
<asp:Button ID="cmdTest" runat="server" Text="Server Delete Prompt"
ClientIDMode="Static"
OnClientClick="return mydeleteprompt(this)"/>
Now, in above, we call a routine, and it will "display" our dialog prompt. But remember that rule above: The code FLOWS though, does not halt the calling js code.
So, what we need to do is STILL RETURN false the first time. (and now our cool prompt dialog is displayed.
the way to make this work? Well, in above we pass "this". In this context, "this" is the current button. So, our code now looks like this:
<div id="MyDialog" style="display:none">
<h4><i>my cool dialog text</i></h4>
<h4><i>This delete can't be undone</i></h4>
</div>
</div>
<script>
var mydeleteok = false
function mydeleteprompt(cmdBtn) {
if (mydeleteok) {
return true
}
myDialog = $("#MyDialog")
myDialog.dialog({
title: "Delete the whole server system",
modal: true,
appendTo: "form",
buttons: {
ok: function () {
myDialog.dialog('close')
mydeleteok= true
$(cmdBtn).click()
},
cancel: function () {
myDialog.dialog('close')
}
}
})
return false
}
Note VERY - but super duper close in above. The routine will return false. That means you click on the button, call the js routine, dialog is displayed, AND THEN FALSE is returned.
Now, the dialog is displayed. If you hit ok button, we set our variable = true AND THEN click the button again!!!!
This time, the same routine will run, but we set our "flag" = true, and the code runs, and returns true, and our server side button code will run.
It will look like this:
So, user click on button, code runs, display dialog, returns "false".
Now, if the user hits "ok", then we run this code:
buttons: {
ok: function () {
myDialog.dialog('close')
mydeleteok= true
$(cmdBtn).click()
},
So, what happens is we set our flag = true, and then click the button again!!! This time, the button calls our routine, but this time the routine WILL return true, and now our server side code for that button will run.
So, your HUGE issue and problem? Near 100%, if not all JavaScript code these days runs asynchronously. It does NOT WAIT.
So, there are advanced concepts such as "await" and things like JavaScript "promise", but it still DOES NOT solve this issue.
So, the asp.net button click event, and using onclientclick is a great feature, but it tends to break down a bit when you want to use some type of dialog "add-in", since as I stated, NONE of them wait. So, you have to adopt the above concept, set a flag (that flag code ONLY runs on page load - first time.
In fact, one could make the case that after I use the .click() to run that button, I probably should set that flag = false again. However, since that server side button is causing a post-back, then in most cases, our flag will be re-set to false.
Edit: Example with jquery-confirm.
As noted, I never used that confirm library (there is about 1+ million of them to be found - you should perhaps have provide a link).
Regardless, that dialog works like this:
<asp:Button ID="Button1" runat="server" Text="Button" CssClass="btn"
OnClick="Button1_Click"
OnClientClick="return myconfirm(this)"
/>
<script>
var myconfirmok = false
function myconfirm(btn) {
if (myconfirmok) {
return true
}
$.confirm({
title: 'Confirm!',
content: 'Simple confirm!',
buttons: {
confirm: function () {
myconfirmok = true
$(btn).click()
},
cancel: function () {
console.log("user hit cancel")
}
}
});
return false // routine MUST return false!!!!
}
NOTE very careful in above - we return false on the last line!!!
So, button is clicked , client side code runs, displays dialog, returns false.
Now, user either hits cancel button, or hits confirm. If they hit confirm, we set our flag = true, and then click the button passed again. Now, our routine runs again, and returns true this time, and thus your server side code now runs.
Edit3: - the issue is use of LinkButton
The issue here is that to use jQuery (or even JavaScript) to CLICK a link button?
You have to use this:
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Eval("HotelName") %>' >
</asp:TextBox>
<asp:LinkButton ID="cmdDel" runat="server" ClientIDMode="Static"
CommandArgument='<%# Eval("ID") %>'
onclick="cmdDel_Click"
OnClientClick="return myconfirm(this)"
>delete</asp:LinkButton>
<br />
</ItemTemplate>
</asp:Repeater>
<script>
var myconfirmok = false
function myconfirm(btn) {
if (myconfirmok) {
return true
}
$.confirm({
title: 'Confirm!',
content: 'Simple confirm!',
buttons: {
confirm: function () {
myconfirmok = true
$(btn)[0].click()
},
cancel: function () {
console.log("user hit cancel")
}
}
});
return false // routine MUST return false!!!!
}
</script>
So, you have to address the click even with [0].
Of course, I never use a link button - I useally just drop in a standard button, and there not a whole lot of reason to use a Linkbutton. But, the issue was and is use of jQuery.Click - it needs that [0] for the click event to work.
The code behind for my linkbutton click event is this:
Protected Sub cmdDel_Click(sender As Object, e As EventArgs)
Dim cmdDel As LinkButton = sender
Dim intPKID As Integer = cmdDel.CommandArgument
Debug.Print("code here to delete row with PK id = " & intPKID)
' get current repeater row
Dim OnerepRow As RepeaterItem = cmdDel.NamingContainer
Debug.Print("Repeter index row click = " & OnerepRow.ItemIndex)
' get hotel name texgt box
Dim txtHotel As TextBox = OnerepRow.FindControl("TextBox1")
Debug.Print(txtHotel.Text)
End Sub
And when I run it
<div>
<asp:Repeater ID="ProductView" runat="server" OnItemDataBound="Repeater1_ItemDataBound" >
<ItemTemplate>
<asp:Label ID="lblAddressID" runat="server" Text='<%# Eval("OrderNumer") %>' Visible = "false" />
<asp:LinkButton ID="Delete" CssClass="MordersButton" OnCommand="btnDelete_Click" OnClientClick="return ShowMessage();" runat="server" Text='<%#Eval("Delete") %>'></asp:LinkButton></h5>
</ItemTemplate>
</asp:Repeater>
</div>
<script type="text/javascript">
function ConfirmBox(msgtitle, message, controlToFocus) {
$("#msgDialogAlert").dialog({
autoOpen: false,
modal: true,
title: msgtitle,
closeOnEscape: true,
buttons: [{
text: "Yes",
click: function () {
$(this).dialog("close");
if (controlToFocus != null)
controlToFocus.focus();
}
},
{
text: "No",
click: function () {
$(this).dialog("close");
if (controlToFocus != null)
controlToFocus.focus();
}
}],
close: function () {
$("#operationMsgAlert").html("");
if (controlToFocus != null)
controlToFocus.focus();
},
show: { effect: "clip", duration: 200 }
});
$("#operationMsgAlert").html(message);
$("#msgDialogAlert").dialog("open");
};
function ShowMessage() {
ConfirmBox("This is Title - Please Confirm", "Are you sure you wanted to delete? This cannot be undone!", null);
return false;
}
</script>
protected void btnDelete_Click(object sender, EventArgs e)
{
RepeaterItem item = (sender as LinkButton).Parent as RepeaterItem;
string name = (item.FindControl("Delete") as LinkButton).Text.Trim();
string OrderNumber = (item.FindControl("lblAddressID") as Label).Text.Trim();
{
using (SqlCommand cmd = new SqlCommand("DC_ManageOrders_Update"))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#CategoryType", name);
cmd.Parameters.AddWithValue("#OrderNumber", OrderNumber);
cmd.Connection = cn;
cn.Open();
cmd.ExecuteNonQuery();
cn.Close();
}
}
this.FlavorImage1Bind();
}
If I Click the button Yes after the modal box opened the delete is not happening. Please help how can i achieve this
i want to run the btnDelete_Click code to delete the record, without modal box through normal javascript i can able to delete the record.
If someone able to help me it will be very usefull to me ...
Ok, the problem here?
When you use onClientClick, you "goal" is to return true (server side code runs), or false - server side button event does not run.
So, you can say use a js confirm box. That's because confirm() HALTS the code.
However, jquery.UI, and in FACT MOST web based software does NOT halt code. Most web based controls (bootstrap dialogs, and jQuery.UI) are NOT modal. They are asynchronous in operation. Blocking, or halting code in js is simple RARE allowed these days.
So, most suggested solutions center around say disabling the event code for the button, and then you execute a _doPostBack(). This is not bad, but then you can't have that button conditional run based on return of true/false. So you wind up with a extra button, extra _doPoast back. So most solutions are really quite poor.
So, when this code runs:
OnClientClick="return ShowMessage();
The above code runs async - does NOT wait. So the dialog pops, but the code continues running and the server side button click will fire!! - (and the dialog that was displayed will of course colipase since we have a page post back.
So, we want:
avoid document ready solutions - they are horrid to debug
document ready means we have a VERY difficult time following code flow.
we want a simple function - has to return true/false.
but, jQuery.UI dialogs do not wait, and they don't halt code.
So, to avoid world poverty, 2-3 extra routines, messy _doPostback, and code to disable the button?
Do it this way:
Adopt a code standard that you create a true/false var of the SAME name of the function (with "OK" on the end), and scope the variable to that function.
Also, I assume that the delete button when clicked (without the onclientclick) works as you wish.
<script>
var mypopok = false; // runs on browser load
function mypop() {
if (mypopok) {
return true;
}
mydiv = $('#dlg1');
mydiv.dialog({
autoOpen: false, modal: true, title: 'Yes/no test', width: '250px',
position: { my: 'top', at: 'top+150' },
buttons: {
'ok': function () {
mypopok = true;
mydiv.dialog('close');
$('#Button1').click();
},
'cancel': function () {
mydiv.dialog('close')
}
}
});
// Open the dialog
// if dialog has MORE then just ok, cancel, and say has text
// box, check box in content, then you MUST move back to form
mydiv.parent().appendTo($("form:first"))
mydiv.dialog('open')
return false;
}
</script>
Now, the button click code looks like this:
<asp:Button ID="Button1" runat="server" Height="48px" Text="Button" Width="171px"
ClientIDMode="Static" OnClientClick="return mypop();"/>
So what will occur?
You will click on the button - the code will run and return false!!! - (remember, it does NOT wait or halt). Now the dialog does pops, but button event code will not trigger.
Based on yes or no, we set that bol flag to true or false. If cancel, then we just close the dialog. If "ok", then we set the flag = true and RE-CLICK the SAME button. Now the button click runs again, but we in our routine return true before the pop dialog code runs, and thus now the server side event click runs.
We:
did not have to consider using await (promise)
did not have to add a extra button
did not have document ready and code ALL OVER in the page
did not have to add extra buttons and events.
code is liner - easy to read - all in one spot.
Now I would consider adding the parameters to the Actual OnClientClick,
Say like this:
OnClientClick="return mypop('This is Title - Please Confirm',
'Are you sure you wanted to delete? This cannot be undone!', null);"
And add the parms to the mypop.
You can't really use two routines like you have, since as noted this:
function ShowMessage() {
ConfirmBox("This is Title - Please Confirm", "Are you sure you wanted to delete? This cannot be undone!", null);
return false;
}
Confirmbox does NOT halt or wait - the code will "run right though" and immediate return false.
So use the flag trick I outline, and re-click the SAME button again when user hits ok. That way, you don't wire up 3-4 routines, and you don't need to add extra buttons or use _DoPostBack() in the js code.
I am trying to avoid the confirm box of javascript and tried that jquery.ui dialog box.
When confirm box returns true or false after that only remaining javascipt will execute,but in this jquery.ui dialog that not happening.
This what i tried,
I am having some of the links
function checkit(){
var istrue = showdial("confirm");
if(istrue== true) alert("yes");
else alert("no");
}
function showdial(tStr)
{
$('<div></div>').appendTo('body')
.html('<div><h4>Are you sure..?</h4></div>')
.dialog({
title: tStr,
zIndex: 10000,
autoOpen: true,
modal: true,
buttons:{
Yes: function(){
$(this).dialog("close");
return true;
}
No: function(){
$(this).dialog("close");
return false;
}
}
});
}
Please correct me if i did anything wrong above.
Before clicking that yes or no button it always alerts "no" only, . How can i run a script after that dialog returns an value. And i dont want that setTimeout() function to use.
Asynchronous code can't return values like that. Look at this related question which explains how to resolve this problem using callbacks.
How can we create a confirmation alert in javascript with a save and discard button in it?
If we use the code
confirm('Do you want to save it?');
We will get an alert box with ok cancel.
How can we make the text of ok button as save and the other as discard?
You cannot modify the default javascript method "confirm". But, you can override it, for example, with jQuery UI dialog:
window.confirm = function (message) {
var html = "<div style='margin:20px;'><img style='float:left;margin-right:20px;' src='/img/confirm.gif' alt='Confirm'/><div style='display:table;height:1%;'>" + message + "</div></div>";
$(html).dialog({ closeOnEscape: false,
open: function (event, ui) { $('.ui-dialog-titlebar-close').hide(); },
modal: true,
resizable: false,
width: 400,
title: "Confirmation",
buttons: {
"Save": function () {
//Do what you need
},
"Cancel": function () {
$(this).dialog("close");
}
}
});
}
this is not possible
more answers
Connect some of the tons JS framework. For example jQuery+UI
Overwrite window.confirm method, by makin it as wrapper to your favorite JS UI framework.
PROFIT!!!
Firstly, I'm new at Javascript / Jquery so it might be a stupid question...
I'm using the dialog box that is in the JQuery UI collection. I have a button that when clicked, it either shows a confirm box or an alert box. My code is like below...
function checkfn() {
if (document.getElementById('<%=HomeInstSelected.ClientID%>').value == 'False') {
var dialogResult = false;
$("#dialog-confirm").dialog({
resizable: false,
height: 140,
modal: true,
buttons: {
Continue: function () {
dialogResult = true;
$(this).dialog("close");
},
Cancel: function () {
$(this).dialog("close").slideUp();
}
}
});
// alert just debug code!
alert(dialogResult);
return dialogResult;
}
else {
$("#dialog-HomeInstitutionPrompt").dialog({
height: 140,
modal: true
});
}
}
My problem is in the confirm part, it seems the confirm box is not waiting for me to hit Continue or Cancel - it's just going straight to the alert part and returning dialogResult = false.
Is it possible to halt execution of until after I've run the $('#dialog-confirm') command?
Alternatively, is it possible to return true for the checkfn() function, in the Continue function? That way, I will not need a dialogResult var at all?
I haven't used the .dialog in jQuery UI before, but, in general with jQuery, functions are run asynchronously. What this means is that you need to put the code that you want run in the Continue function.
One possibility is to send a success/cancel function to checkfn that you would call from the Continue and Cancel functions.
function checkfn(success, cancel) {
if (document.getElementById('<%=HomeInstSelected.ClientID%>').value == 'False') {
var dialogResult = false;
$("#dialog-confirm").dialog({
resizable: false,
height: 140,
modal: true,
buttons: {
Continue: function () {
if(success) success();
$(this).dialog("close");
},
Cancel: function () {
if(cancel) cancel();
$(this).dialog("close").slideUp();
}
}
});
}
You can call the function like this:
checkfn(function () {
alert('success!');
}, function () {
alert('failure!');
});
Just put everything you want to do inside "Continue" and "Cancel" button definitions. So, you will not need a dialogResult and alert will hit when it is needed.
if (document.getElementById('<%=HomeInstSelected.ClientID%>').value == 'False') {
var dialogResult = false;
$("#dialog-confirm").dialog({
resizable: false,
height: 140,
modal: true,
buttons: {
Continue: function () {
alert('Dialog result is true. I can do whatever I want here');
$(this).dialog("close");
},
Cancel: function () {
alert('Cancel is clicked. I should go on my life');
$(this).dialog("close").slideUp();
}
}
});
}
else {
$("#dialog-HomeInstitutionPrompt").dialog({
height: 140,
modal: true
});
}
-- You can't return a value for your function, because after initialization of the function, the code goes on. You need to fill Continue button definition.
This is something I struggled with when I started too, The code doesn't run as it reads on the page. When you call the dialog function it executes asynchronously. The continue and cancel functions are bound to the click actions on the buttons, meanwhile the code below the dialog function runs without waiting for the events.
Long story short the result needs to happen in the cancel and continue callbacks.
Problem is you're trying to return a boolean value when you should really pass the resulting functions in instead. Alot of things in jquery and javascript in general work that way. Thankfully the language provides the ability to program in this way.
function checkfn( resultfn(boolval) ) {
if (document.getElementById('<%=HomeInstSelected.ClientID%>').value == 'False') {
var dialogResult = false;
$("#dialog-confirm").dialog({
resizable: false,
height: 140,
modal: true,
buttons: {
Continue: function () {
resultfn.call( this, true );
$(this).dialog("close");
},
Cancel: function () {
resultfn.call( this, false );
$(this).dialog("close").slideUp();
}
}
});
}
Put the if statement in "resultfn"
I had a similar frustrating problem where the jQuery dialog box would submit a form before the user had a chance to choose Yes or No.
Example HTML:
<form id="myForm" method="POST" action="/Where/To/Go">
<input type="submit" value="Submit" onclick="submitForm()"/>
</form>
And jQuery:
function submitForm() {
$('<div title="Submit Form>Are you sure you wish to submit the form?</div>').dialog({
modal: true,
buttons: [
{
text: "Yes",
click: function () {
$('#myForm').submit();
$(this).dialog("close");
}
}, {
text: "No",
click: function () {
$(this).dialog("close");
}
}
]
});
}
To fix the issue I changed the button from a submit type to a button type which stopped it submitting and triggering the jQuery dialog at the same time:
<input type="button" value="Submit" onclick="submitForm()"/>