my iframe content aspx page contain 3 asp element: textbox, requriedfieldValidator realated to the textbox and button ,
in javascript onbeforeunload I want to call the button click event that have prevent leave the page if the textbox is empty.
but the folowing code dosent work:
<script type="text/javascript">
window.onbeforeunload = function (e) {
document.getElementById("Button1").click();
}
</script>
<asp:textbox runat='server' id="TextBox1" AutoPostBack="true"/>
<asp:Button ID="Button1" runat="server" Text="Button" onclick="TextBox1_Click" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ErrorMessage="RequiredFieldValidator" ControlToValidate="TextBox1"></asp:RequiredFieldValidator>
onbeforeunload event handler is special. You can't unconditionally prevent the user from leaving the page.
https://developer.mozilla.org/en-US/docs/Web/API/Window.onbeforeunload
You should return non-void value from this handler - preferably string - the user will be prompted if he/she really want's to leave the page. Most of the browsers will present the returned string in the popup.
<script type="text/javascript">
window.onbeforeunload = function (e) {
return "The textbox is empty. Are you sure you wan't to leave the page?";
}
</script>
The reason for such unusual behavior is security. User has to be informed that the navigation to another page is interrupted. Otherwise he/she may think that the navigation succeeded.
Imagine that you silently cancel the navigation inside this handler and you change the content of the page to look like Internet banking application. There is a vary small chance that the user actually wanted to visit the banking application. But it may happen. This opens the gate to hijacking user's credentials. So it's not possible in web browser.
Basically inside onbeforeunload event handler all the actions, that would normally stop the navigation to another page, take no effect - they are ignored and this is intentional.
Related
I'm working on an ASP.NET application and I ran into an issue that I am unable to resolve. I have a parent form, called Form1.aspx which contains a Telerik RadGrid. On page load, this grid is completely empty. The user has the ability to add data, by clicking add, in this case a Rad Window opens: here's my code:
<td >
<input id="btnAdd" runat="server" onclick="showQuestion4()"
type="button" value="Add" />
</td>
I have my RadWindowManager like this:
<telerik:RadWindowManager ID="RequestsRadWindowManager" runat="server" >
<Windows>
<telerik:RadWindow ID="ClientQuestion4" runat="server" Behaviors="Close,Move"
EnableEmbeddedSkins="false" Height="300px" Modal="true" OnClientClose="OnClientClose"
ReloadOnShow="true" Skin="WebBlue" Width="550px">
</telerik:RadWindow>
</Windows>
</telerik:RadWindowManager>
And My JS function to actually open the window:
function showQuestion4() {
return window.radopen("mdClientQ4.aspx?mode=add", "ClientQuestion4", "return false;");
return false;
}
My child form opens correctly, and allows user to enter and SAVE data. Once user clicks SAVE, I do an insert and then call this:
RadAjaxManager1.ResponseScripts.Add("cancelAndClose();")
Which corresponds to this JS code:
function cancelAndClose() {
var oWnd = GetRadWindow();
oWnd.close();
}
function GetRadWindow() {
var oWindow = null;
if (window.radWindow) oWindow = window.radWindow;
elseif(window.frameElement.radWindow)oWindow=window.frameElement.radWindow;
return oWindow;
}
So this code gets called, my child form Closes successfully, and now the focus returns to my Parent form which has been open in the background.
What's happening here is, I have a Full Page Post back on the parent form, and my main goal is to PREVENT IT.
My RadGrid is currently in Update Panel, with mode="conditional". The trigger for this Update Panel is a dropdown, which enabled the ADD button , which in turns allows the user to open the child form and enter data.
I have been trying to disable this postback for hours to no avail, I have no idea what it is I'm doing wrong.
I set return false; in my showQuestion4() Javascript function, but this still gets bypasses, and the parent page has full page load.
My goal for this, is to close the child form, and NOT have the POST BACK occur in my parent form, rather I want to simply reload the UpdatePanel with RadGrid which would display the information the user entered in the Child form.
Any help or tips will be greatly appreciated. I'd be more than happy to show more code if necessary.
EDIT:
Per Nikkis comment below, I removed runat="server" from btnAdd however, my parent form still goes through postback
Posting as an answer, since it looks like you worked it out from our comment conversation.
Check the UpdatePanel, and be sure any code called on client close is firing as you mean it to fire.
I apologize if this has been answered somewhere but I could not find my particular problem's answer.
I have a asp object:
<asp:CheckBox ID="chkRemove" runat="server" Checked='<%#Convert.ToBoolean(Eval("CommonWord")) %>' OnCheckedChanged
= "OnCheckedChanged_CommonWord" AutoPostBack="true" />
Basically I want to show a message box asking if its ok to remove, if no or cancel is selected, don't do a postback (or don't run any server side code), and if yes then run that function "OnCheckedChanged_CommonWord".
I tried doing a javascript Confirm() call which pops up but if I press yes, the C# server side code does not run ("OnCheckedChanged_CommonWord") the "no" or "cancel" works perfectly as it doesn't do a postback.
P.s. Please no AJAX due to server restrictions for me.
The Checkbox control actually lacks any type of OnClientCheckChanged event that can be used to manage if a PostBack should occur or not (like OnClientClick, etc.) based on a client-side event.
But you should be able to accomplish this using an onclick attribute with a function to manage the default PostBack by calling it manually :
<asp:CheckBox ID="chkRemove" runat="server"
Checked='<%#Convert.ToBoolean(Eval("CommonWord")) %>'
OnCheckedChanged="OnCheckedChanged_CommonWord"
AutoPostBack="true"
onclick='return OnClientCheckChanged("Are you sure you want to do this?",this);' />
<script>
function OnClientCheckChanged(prompt,source) {
if (confirm(prompt)){
__doPostBack("'" + source.id + "'", '');
return true;
}
else {
return false;
}
}
</script>
When the CheckBox is actually clicked, it will trigger your confirm() prompt and based on the result, it will either trigger an explicit PostBack (via the nasty __doPostBack() call or it won't do anything.
I'm not a huge fan of the __doPostBack() call, but it seems like an appropriate solution here.
I am opening a Child Modal Dialog window from my parent web page. The JavaScript code for opening the Dialog is as follows:-
function openmodalWin() {
window.showModalDialog("ClockPopUP.aspx", "Clock", "dialogWidth:550px;dialogHeight:350px,");
}
The Asp Code is as Follows:-
<asp:Button ID="Button1" runat="server" Text="Lunch" CausesValidation="false" CssClass="bigbuttons" style="background:url(../App_Themes/Images/green-box.gif)" Font-Bold="True" ForeColor="White" Font-Size="Large" OnClientClick="openmodalWin(); return false;"
In my "ClockPopUp.aspx" I had used only one jQuery stop watch plugin which is just for showing purpose and no use except it. My requirement is that I want that as the user will close the ModalDialog, on the parent page we can capture the time when the Pop up will be closed, or the ShowmodalDialog will return datetime at window.close().
Please try to solve this issue as I'm not so good in JavaScript.
jQuery UI has this functionality without the need to access another aspx page.
However, window.showModalDialog returns a value, so you'd need to alter your aspx to return something meaningful i.e.
window.returnValue = "whatever";
window.close();
Then you can call it using
var returnValue = window.showModalDialog(...)
Please See the following code example.
HTML:
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:FileUpload ID="FileUpload1" runat="server" />
<!-- upload button and Save button -->
<asp:Button ID="Upload" runat="server" Text="Upload" />
<asp:Button ID="Save" runat="server" Text="Save" />
Cancel
JavaScript:
//form is not changed by default
var form_Change = 0;
window.onbeforeunload = function(e) {
if (form_Change==1){
// if the form is changed, show a confirm box
return 'Are you sure you want to navigate away from this page?';
}
}
$('input[type=text]').live('keyup',function(){
form_Change =1;
});
Normally,
A user typed in the textbox without saving it. Then he is trying to redirect to other page or reload the page, the bowser brings him a confirm box.
But,
I firstly type into the textbox, and then click the "Upload Button" which is used to upload files but doesn't save (doesn't affect the change of) the form (and keep the unsaved text in the textbox as it is after postback). The bowser brings me the unwanted confirm box.
I try to fix it and add something like,
var button_inside_form =0;
$('Upload').live('click',function(){
button_inside_form =1;
});
//and update form change logic in onbeforeunload
But, after the page post back. It reload JavaScripts, form_Change is reset to 0. so the system doesn't know whether the form is changed.
So how do I check the form is changed after I click "Upload", and don't bring back confirm box when I click "Upload".
Answer myself.
I use a cookies. that is turn var form_change as a cookies in JavaScript.
and then in server code, Not IsPostBack I add this to reset the cookies.
ClientScript.RegisterClientScriptBlock(Me.GetType, "IsPostBack", "var isPostBack = true;", True)
to check
if (typeof isPostBack != 'undefined') {
resetFormChange();}
use this to prevent the confirm box on submit buttons
$('form').submit(function() {
window.onbeforeunload = null;
});
More thinking.
The cookies is required, if the form submit will remain it in the same page.
form.submit will works fine, but need to make sure "UseSubmitBehaviors" need to be set on "Cancel" button. And or if cause the page stay, better to put them in a updatepanel.
I have several small divs which are utilizing jQuery draggable. These divs are placed in an UpdatePanel, and on dragstop I use the _doPostBack() JavaScript function, where I extract necessary information from the page's form.
My problem is that when I call this function, the whole page is re-loaded, but I only want the update panel to be re-loaded.
Here is a complete solution
Entire form tag of the asp.net page
<form id="form1" runat="server">
<asp:LinkButton ID="LinkButton1" runat="server" /> <%-- included to force __doPostBack javascript function to be rendered --%>
<input type="button" id="Button45" name="Button45" onclick="javascript:__doPostBack('ButtonA','')" value="clicking this will run ButtonA.Click Event Handler" /><br /><br />
<input type="button" id="Button46" name="Button46" onclick="javascript:__doPostBack('ButtonB','')" value="clicking this will run ButtonB.Click Event Handler" /><br /><br />
<asp:Button runat="server" ID="ButtonA" ClientIDMode="Static" Text="ButtonA" /><br /><br />
<asp:Button runat="server" ID="ButtonB" ClientIDMode="Static" Text="ButtonB" />
</form>
Entire Contents of the Page's Code-Behind Class
Private Sub ButtonA_Click(sender As Object, e As System.EventArgs) Handles ButtonA.Click
Response.Write("You ran the ButtonA click event")
End Sub
Private Sub ButtonB_Click(sender As Object, e As System.EventArgs) Handles ButtonB.Click
Response.Write("You ran the ButtonB click event")
End Sub
The LinkButton is included to ensure that the __doPostBack javascript function is rendered to the client. Simply having Button controls will not cause this __doPostBack function to be rendered. This function will be rendered by virtue of having a variety of controls on most ASP.NET pages, so an empty link button is typically not needed
What's going on?
Two input controls are rendered to the client:
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
__EVENTTARGET receives argument 1 of __doPostBack
__EVENTARGUMENT receives argument 2 of __doPostBack
The __doPostBack function is rendered out like this:
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
As you can see, it assigns the values to the hidden inputs.
When the form submits / postback occurs:
If you provided the UniqueID of the Server-Control Button whose button-click-handler you want to run (javascript:__doPostBack('ButtonB',''), then the button click handler for that button will be run.
What if I don't want to run a click handler, but want to do something else instead?
You can pass whatever you want as arguments to __doPostBack
You can then analyze the hidden input values and run specific code accordingly:
If Request.Form("__EVENTTARGET") = "DoSomethingElse" Then
Response.Write("Do Something else")
End If
Other Notes
What if I don't know the ID of the control whose click handler I want to run?
If it is not acceptable to set ClientIDMode="Static", then you can do something like this: __doPostBack('<%= myclientid.UniqueID %>', '').
Or: __doPostBack('<%= MYBUTTON.UniqueID %>','')
This will inject the unique id of the control into the javascript, should you wish it
Per Phairoh: Use this in the Page/Component just in case the panel name changes
<script type="text/javascript">
<!--
//must be global to be called by ExternalInterface
function JSFunction() {
__doPostBack('<%= myUpdatePanel.ClientID %>', '');
}
-->
</script>
Using __doPostBack directly is sooooo the 2000s. Anybody coding WebForms in 2018 uses GetPostBackEventReference
(More seriously though, adding this as an answer for completeness. Using the __doPostBack directly is bad practice (single underscore prefix typically indicates a private member and double indicates a more universal private member), though it probably won't change or become obsolete at this point. We have a fully supported mechanism in ClientScriptManager.GetPostBackEventReference.)
Assuming your btnRefresh is inside our UpdatePanel and causes a postback, you can use GetPostBackEventReference like this (inspiration):
function RefreshGrid() {
<%= ClientScript.GetPostBackEventReference(btnRefresh, String.Empty) %>;
}
While Phairoh's solution seems theoretically sound, I have also found another solution to this problem. By passing the UpdatePanels id as a paramater (event target) for the doPostBack function the update panel will post back but not the entire page.
__doPostBack('myUpdatePanelId','')
*note: second parameter is for addition event args
hope this helps someone!
EDIT: so it seems this same piece of advice was given above as i was typing :)
If anyone's having trouble with this (as I was), you can get the postback code for a button by adding the UseSubmitBehavior="false" attribute to it. If you examine the rendered source of the button, you'll see the exact javascript you need to execute. In my case it was using the name of the button rather than the id.
Have you tried passing the Update panel's client id to the __doPostBack function? My team has done this to refresh an update panel and as far as I know it worked.
__doPostBack(UpdatePanelClientID, '**Some String**');
First, don't use update panels. They are the second most evil thing that Microsoft has ever created for the web developer.
Second, if you must use update panels, try setting the UpdateMode property to Conditional. Then add a trigger to an Asp:Hidden control that you add to the page. Assign the change event as the trigger. In your dragstop event, change the value of the hidden control.
This is untested, but the theory seems sound... If this does not work, you could try the same thing with an asp:button, just set the display:none style on it and use the click event instead of the change event.
You can't call _doPostBack() because it forces submition of the form. Why don't you disable the PostBack on the UpdatePanel?