Javascript Modal Box OnCommand not working - javascript

<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.

Related

Stopping Postback with jquery-confirm confirm box, can't seem to get return value (webform project)

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

Why does WebForms keep rendering this data- attribute?

WebForms keeps re-rendering a TextBox control with a data- attribute in spite of my code removing it on PostBack-- which I shouldn't have to do in the first place, since the PostBack process clears attributes. I've tried clearing the attributes in OnInit and OnUnload, but they somehow reappear after leaving code-behind. They only ever reset through the TextChanged event.
I'm going crazy trying to figure out if I have a cache setting somewhere in my web.config that would prevent ASP.NET from properly removing this attribute.
For reference, the (as far as I can determine) relevant sections of my code:
.aspx JavaScript:
$("[data-confirm]").each(function () {
var alertText = $(this).attr("<%= _data_confirm %>");
$(alertText).dialog({
modal: true,
draggable: false,
resizable: false,
closeOnEscape: false,
title: "Note",
width: 330,
buttons: {
"Continue with Application": function () {
$(this).dialog("close");
}
}
});
});
.aspx.cs C#:
protected override void OnInit(EventArgs e)
{
if (Page.IsPostBack)
{
ClearIraDistributionConfirmation();
}
iraDistribution.TextChanged += iraDistribution_TextChanged;
}
void iraDistribution_TextChanged(object sender, EventArgs e)
{
if (SessionFormData.ConfirmedIraDistribution == false
&& SessionFormData.IraDistribution.HasValue
&& SessionFormData.IraDistribution.Value > 0)
{
iraDistribution.Attributes[_data_confirm] =
"<div>You must submit a copy of the first page of your 2014 federal tax return to verify the rollover amount.</div>";
iraDistribution.Attributes[_aria_live] = "assertive";
SessionFormData.ConfirmedIraDistribution = true;
}
else if (SessionFormData.ConfirmedIraDistribution)
{
ClearIraDistributionConfirmation();
}
}
private void ClearIraDistributionConfirmation()
{
if (SessionFormData.ConfirmedIraDistribution)
{
iraDistribution.Attributes.Clear();
}
}
I've verified that at the end of the PostBack cycle, iraDistribution has no attributes set. As soon as my .aspx JS hits the very first line of JavaScript -- which is way before the JS I pasted here -- iraDistribution has its data-confirm attribute set.
What am I missing?
The answer to this question is: The Page Life Cycle.
I made the mistake of trying to check for TextBox values in OnInit when they weren't yet available. OnUnload didn't work either because the values had already been rendered to output at that point.
I've fixed this bug by reordering the code above and moving it into the OnLoadComplete event. My code now looks like (well -- not quite like this, but it's abbreviated to remove code that interacts with the Session, functions I defined to improve readability, etc.):
protected override void OnLoadComplete(EventArgs e)
{
base.OnLoadComplete(e);
if (SessionFormData.ConfirmedIraDistribution)
{
iraDistribution.Attributes.Clear();
}
else if (SessionFormData.ConfirmedIraDistribution == false
&& SessionFormData.IraDistribution.HasValue
&& SessionFormData.IraDistribution.Value > 0)
{
iraDistribution.Attributes[_data_confirm] =
"<div>You must submit a copy of the first page of your 2014 federal tax return to verify the rollover amount.</div>";
iraDistribution.Attributes[_aria_live] = "assertive";
SessionFormData.ConfirmedIraDistribution = true;
}
}
The moral of this story: The Page Life Cycle will eat your lunch.

Prevent Postback with custom jQuery confirm implementation on asp:LinkButton

I have a LinkButton that executes on the server and changes the page. Historically, I've had a confirm message box that executes OnClientClick to ensure the user would like to navigate away.
So far it looks like this:
ASP.NET:
<asp:LinkButton runat="server" ID="ChangePage" Text="Change page"
OnClientClick="confirm('are you sure you want to change page?');"
OnClick="Navigate" >
Change Page
</asp:LinkButton>
HTML Output:
<a id="MainContent_ChangePage"
onclick="confirm('are you sure you want to change page?');"
href="javascript:__doPostBack('ctl00$MainContent$ChangePage','')" >
Change page
</a>
This all works fine like this. The trouble is that I'm trying to replace all confirm boxes with a prettier jQuery-UI implementation like this:
window.confirm = function (message, obj) {
$('<div/>')
.attr({ title: 'Webpage Confirm'})
.html(message)
.dialog({
resizable: false,
modal: true,
width: 500,
buttons: {
"OK": function () {
__doPostBack(obj, '');
$(this).dialog('close');
return true;
},
"Cancel": function () {
$(this).dialog('close');
return false;
}
}
});
};
I believe this has to do with the fact that the confirm dialog operates synchronously, while jQuery dialogs occur asynchronously. However, I thought setting modal: true would cause it to wait for a response.
How can I override window.confirm to get consistent behavior?
Add this to OK action:
var href = $(obj).attr("href");
window.location.replace(href);
window.navigator.location(href);
return true;
And remove __postback line
it works with me

How to close SP.UI.ModalDialog from button click in sharepoint?

I want to show Confirmation Dialog when user saves any document from EDITForm.aspx. So I have written following JavaScript code.
function PreSaveAction() {
var _html = document.createElement();
_html.innerHTML = " <input type=\"button\" value=\"Submit\" onclick ='javascript:SubmitDlg();' /> <input type=\"button\" value=\"Cancel\" onclick =\"javascript:CloseDlg();\" /> </td> </tr> </tbody> </table>";
var options = {
title: "Confirm",
width: 400,
height: 200,
showClose: false,
allowMaximize: false,
autoSize: false,
html: _html
};
SP.UI.ModalDialog.showModalDialog(options);
}
function SubmitDlg() {
SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.OK);
}
function CloseDlg() {
SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.Cancel);
}
Now I have following queries.
SubmitDlg and CloseDlg is not fired when clicking on Submit or
Cancel.
Is this right way to Submit form (SubmitDlg method ) and Cancel dialog (CloseDlg method) from modal dialog ?
Also this modal dialog-box should be only appeared if no validation errors while saving record, means if any field-value is required and we have not put any value then it should display in-built red colored messages.
Thanks
in the options for the modal dialog you need to pass a reference to your call back function like this:
var opt = SP.UI.$create_DialogOptions();
opt.width = 500;
opt.height = 200;
opt.url = url;
opt.dialogReturnValueCallback = MyDialogClosed;
SP.UI.ModalDialog.showModalDialog(opt);
Then in your callback function you can check the status:
function MyDialogClosed(result, value) {
if (result == SP.UI.DialogResult.Cancel) {
//Cancel. Do whatever
}
else { //SP.UI.DialogResult.OK
//User clicked OK. You can pickup whatever was sent back in 'value' }
}
If you need to send stuff back from your dialog you can use this:
function okClicked()
{
SP.UI.ModalDialog.commonModalDialogClose(1, someobject);
}
To make this work you'd need to hook-up a function to the OK button in your server side code using something like this:
protected override void OnLoad(EventArgs e)
{
if (Master is DialogMaster)
{
var dm = Master as DialogMaster;
if(dm != null) dm.OkButton.Attributes.Add(#"onclick", #"return okClicked();");
}
base.OnLoad(e);
}
add class "CloseSPPopUp" to the btn u want to click to close
Add This Script to Page which has "CloseSPPopUp" btn
$('.CloseSPPopUp').click(function(){
window.top.CloseSPUIPopoup();
});
$('.CloseSPPopUp').click(function(){
window.top.CloseSPUIPopoup();
});
Now on Main Page where u are calling popup
function CloseSPUIPopoup{
$(".ms-dlgContent").hide();
}
Reason:
ms-dlgContent class is in Parent Page & CloseSPPopUp is in Iframe which is created at runtime

How to execute an javaScript after jquery.ui dialog button function returns.?

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.

Categories

Resources