I have looked around for a way of implementing this. Here is a pseudocode representation of what I have:
bool hasData = ItemHasData(itemid);
Confirm = "false"; // hidden variable
if (hasData)
{
//Code to call confirm(message) returns "true" or "false"
if (Confirm == "true")
{
//Delete item
}
else if (Confirm == "false")
{
return;
}
}
The code to call confirm uses a asp:Literal control and sets it equal to the confirm. I can get the popup but only after the function exits. And it does nothing with the conditions after that.
The general consensus seems to be that calling the javascript at that specific line is impossible (makes sense due to the server side/client side gap), but how can I achieve this? I tried using the ConfirmButtonExtender from the ASP.NET AJAX Toolkit but I couldn't interact with the confirmbuttonextender object from the code behind when the object is set to runat="server".
edit:
Sorry, I did miss those tidbits. Thanks Icarus.
The control itself is the GridView (the pseudo version is actually from the gvData_RowCommand function)'s rowcommand. The first check looks to see if the CommandName is DeleteItem and if so goes into this.
The gvData's columns are set based off a list of headers (and the dataset) passed as the table it is working against is for multiple items with different required information. The gvData's data is there, I just need to get a Yes/No (or in reality it'll end up being Ok/Cancel) dialog to verify they want to delete the item when there is data.
One method I end up using in some situations is to have a Panel that displays the Confirm / Cancel buttons. This avoids the need to handle JavaScript events and uses ASP.NET entirely.
<asp:Panel ID="pDeleteConfirm" runat="server"
CssClass="AlertDialog"
Visible="False">
<p>Do you wish to delete the selected record?<br />
<asp:Button ID="btDeleteYes" runat="server" OnClick="btDelete_Click" Text="Delete" />
<asp:Button ID="btDeleteNo" runat="server" OnClick="btDelete_Click" Text="Cancel" />
</p>
</asp:Panel>
<asp:GridView ID="gvData" runat="server"
AutoGenerateColumns="False"
CssClass="GridView"
DataKeyNames="ID"
DataSourceID="sqlData"
EmptyDataText="There is no data entered in the system."
OnRowDeleting="gvData_RowDeleting">
......
</asp:GridView>
I use the OnRowDeleting event to show the Panel
protected void gvData_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
// Show confirmation dialog
pDeleteConfirm.Visible = true;
// Select the row to delete
gvData.SelectedIndex = e.RowIndex;
// Cancel the delete so the user can use the confirm box
e.Cancel = true;
}
Handle the button Click events
protected void btDelete_Click(object sender, EventArgs e)
{
Button bt = (Button)sender;
switch (bt.ID)
{
case "btDeleteYes": // they confirmed a delete
sqlData.Delete();
break;
case "btDeleteNo": // they clicked cancel
// Do nothing
break;
default:
throw new Exception("Unknow button click in btDelete_Click");
}
// clear selection and hide the confirm box
gvData.SelectedIndex = -1;
pDeleteConfirm.Visible = false;
}
This isn't JavaScript but you can add in some UpdatePanels to do AJAX work on it.
Just one method to do it through ASP.NET rather than JavaScript handling.
The job of your code-behind is to render HTML out to the browser. It does this, and then the socket is closed and your server side code is no longer executing.
You'll have to implement this logic using a Javascript function on the client side.
Are you attempting to warn the user if there's data loaded before they take a certain action? Or perhaps before they try to leave the page? You'll have to popup the alert using script when that action happens on the page.
Related
I have identified a problem with __doPostBack and found a work around. I am seeking an explanation for the cause and/or a better solution than my work around.
Scenario:
I have a dropdown populated with the values; "-Select-", "One" & "Two". If the user selects "One" than client side script is executed. If the user selects "Two" than server side script is executed.
Problem:
The client script initiates the postback by calling __doPostBack. However, no post back actually occurs unless there is also a LinkButton, Calendar or WizardStep control on the page. I actually went through all of the standard tools in the Visual Studio Toolbox and tested them all. It has to be one of those three.
Work Around:
Add a link button surrounded by a span with display set to none.
<span style="display:none;">
<asp:LinkButton ID="LinkButton1" runat="server">LinkButton</asp:LinkButton>
</span>
Question: Can somebody provide an explanation for this behavior or provide a better fix than my "Work Around"?
Source - Javascript (I placed it between the head tags)
<script language="javascript" type="text/javascript">
function DropDownList1_change(elementRef) {
var selectedIndex = elementRef.selectedIndex;
if (selectedIndex > 0) {
var selectedValue = elementRef.options[selectedIndex].value;
if (selectedValue == "One") {
alert("Because you selected 'One', special javascript code will be executed");
// Special javascript code goes here
return;
}
else if (selectedValue == "Two") {
// Special server code gets executed on server DropDownList1_SelectedIndexChanged
__doPostBack('DropDownList1', '');
}
}
}
</script>
Source - ASPX Controls
<asp:DropDownList ID="DropDownList1" runat="server" onchange="DropDownList1_change(this)" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
<asp:ListItem>-Select-</asp:ListItem>
<asp:ListItem>One</asp:ListItem>
<asp:ListItem>Two</asp:ListItem>
</asp:DropDownList>
<br />
<!-- For some unknown reason __doPostBack only works if there is a LinkButton, Calendar or WizardStep control on the page -->
<span style="display:none;">
<asp:LinkButton ID="LinkButton1" runat="server">LinkButton</asp:LinkButton>
</span>
Time of last Post Back: <asp:Label ID="Label1" runat="server"></asp:Label><br />
Time of OnSelectedIndexChanged: <asp:Label ID="Label2" runat="server"></asp:Label>
Source - Code Behind
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = DateTime.Now.ToLongTimeString();
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
Label2.Text = DateTime.Now.ToLongTimeString();
}
Additional Resource - I found the following article after posting this question. Its a very old Microsoft article and the only Microsoft article I found that mentions the specific limitation of DropDowns, return values & postbacks. I haven't digged deep into their solution and not sure time will allow me to. Mainly posting it in case my solution fails down the road or doesn't work for someone else.
Intuitively you might think adding a confirm dialog box for a
DropDownList is identical to adding such a dialog box for a Button Web
control. That is, simply set the DropDownList's client-side onchange
attribute to something like: return confirm(...);. using:
DropDownListID.Attributes("onchange") = "return confirm(...);"
Unfortunately, this won't work as desired because an AutoPostBack
DropDownList's onchange attribute will be set to a bit of JavaScript
that causes a postback, namely a call to the client-side __doPostBack
function. When setting the onchange attribute programmatically
yourself, the end result is that the rendered client-side onchange
event handler has both your code and the call to __doPostBack:
The article is long so search for "Confirmation with AutoPostBack DropDownLists"
https://msdn.microsoft.com/en-us/library/aa479302.aspx
There are 2 solutions.
Solution 1:
A better work around than adding a link button surrounded by hidden span tags is to add the following to the page load event. This ensures that the function __doPostBack is available.
protected void Page_Load(object sender, EventArgs e)
{
Page.ClientScript.GetPostBackEventReference(this, string.Empty);
}
The function __doPostBack is generated only if a control in the form needs it to perform postbacks. This includes controls like the LinkButton and other controls for which AutoPostBack is set to true. In fact, only the Button and ImageButton controls can perform postbacks without __doPostBack (see this article). For example, we can see in the HTML output that a LinkButton is rendered this way:
<a id="lnk" href="javascript:__doPostBack('lnk','')">My link</a>
Solution 2: The following approach achieves the same thing without using __doPostBack.
In the present case, you could set AutoPostBack="true" for the DropDownList:
<asp:DropDownList AutoPostBack="true" onchange="if (!confirmPostBack(this)) return false;" ... >
The onchange event handler would return false when you want to prevent the postback. The Javascript function could be something like this:
function confirmPostBack(ddl)
{
if (condition) {
...
return true;
}
else {
...
return false;
}
}
Important: The onchange event handler should not return anything to allow the postback to occur. You can use this syntax:
onchange="if (!confirmPostBack(this)) return false;"
For reasons probably explained in the article mentioned in the question, the following syntax does not work. Returning true still prevents the postback.
onchange="return confirmPostBack(this);" // Does not work!
currently I am facing a problem with pop up msgs.
The messages should prompt out first time click on a NEXT button.
when we go to the next pages and back to the previous pages, and click on the same NEXT button, the pop up msgs should not appear.
how can i fix this?
This is button code
<asp:Button ID="Button1" runat="server" onclick="Button1_Click1" Text="Next" Width="100px" />
This is the function() for my clickedOnce
<script type="text/javascript">
window.document.onload = function()
{
var clickedOnce = false;
Button1.Button1_Click1 = function ()
{
if(!confirm('Please make sure the employee particulars and reporting line details are correct before save. \nClick OK to save and continue if all details are correct.\nClick Cancel and contact HR Admin if details appear is not up to date.'))return false;
clickedOnce = true;
}
}
</script>
Thank you. your kindness and help much appreciated.
Well, since you only want to run it once, could you give the user a cookie that lasts until the browsing session is over when they fist click the button? If they have the cookie, then you could skip over the line of code that you only want to run once.
Your code doesn't work at all. The main issue is how you try to catch click event.
<asp:Button ID="Button1" runat="server" onclick="Button1_Click1" Text="Next" />
It means that Button1_Click1 function runs at server. No client-side event occurs. To do something on client side you have to add onclientclick="someFunction()" to your button declaration.
OK, you add this. Now go to javascript.
function someFunction(){
var clickOnce = getCookie('clickOnce');
//Look #Darkrifts comment (link) how to do it.
//Just in case I reproduce the link http://www.w3schools.com/js/js_cookies.asp
if(!clickOnce || confirm('blah blah')){
document.cookie = 'clickOnce=1';
//no need to return anything
}
//if a visitor doesn't click "ok" then the popup appear again
}
It is also possible to set Session["clickOnce"] = true; on server side and use it from Page_Load server side handler but it may not work if a visitor return to the page using browser Back button.
protected void Button1_Click1(object sender, EventArgs e){
Session["clickOnce"] = true;
//more code
}
protected void Page_Load(object sender, EventArgs e){
if(Session["clickOnce"] != true)
Button1.OnClientClick = "someFunction()";
else
Button1.OnClientClick = "";
//more code
}
This can be achieved in multiple ways. You need to select the most efficient approach for your need. First of all you need to understand the ASP.Net page life cycle, persisting information between pages and ViewState.
In a nutshell...
Whenever your page reloads all elements (including JavaScript variables, be it global or local variables) in your page get's initialised. And then a feature in ASP.Net comes into play. I.e. ViewState. If this is set to true in page level or for each control it'll persist information of the controls in the page (depends on how you set this). But, this is page specific.
And, you could persist information between pages using following approaches
Query string
Session variables
Cache
Form posts
Cookies
Data store (e.g. text, xml or any other database/ data store)
Before you use any of the above mentioned approaches you must think about your requirement. #Alex Kudryashev came up with a good example while I was writing this answer. Let me know if you need example with a different approach or any clarifications.
I have asp.net page.
I don't have button "Save" on it (not my requirement).
I need to save page data before I leave this page.
I've tried to do it with events like Page_Unload but it doen't work...
Cause Save method uses data from elements on page like txtBox1.Text I can't use .ashx handler to make some ajax save (Or I don't know how to use page elements in handler as they are protected).
So is there any solution except serealizing form and pass it to handler?
You can use the onbeforeunload event.
It should fire before unload.
It allows you to ask back if the user really wants to leave. Check simillar example here.
<script language="JavaScript">
window.onbeforeunload = confirmExit;
function confirmExit()
{
return "You have attempted to leave this page. If you have made any changes to the fields without clicking the Save button, your changes will be lost. Are you sure you want to exit this page?";
}
</script>
In return you can save you required values.
Alternatively, you can send out an Ajax request when user leaves.
I know its late to answer , but its not late at all for people who is still working on same problem :
you just have to surround your execution function area with update panel like below
<asp:UpdatePanel runat="server" ID="blahblahId">
<ContentTemplate>
<asp:Button CssClass="hidden" runat="server" ID="btnAddInfo" OnClick="execBforeUnload"/>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnAddInfo"/>
</Triggers>
</asp:UpdatePanel>
and your javascript code will be
var unloadEvent = function (e)
{
alert("hi");
__doPostBack("<%=btnAddInfo.ClientID%>", "");
};
window.addEventListener("beforeunload", unloadEvent);
Finally your C# method will be as follows:
public void execBforeUnload(object sender ,EventArgs e)
{
Session[lblNumber.Text] = null;
Application[lblNumber.Text] = null;
}
I am developping an asp.net webform application. In a page, I have a dropdown containing some values ("a","b","c",...). When I select a value in this dropdown, a server side event is raised and I write the selected value in my DB.
This is the code :
<asp:DropDownList ID="myDdl" runat="server" OnSelectedIndexChanged="server_handler" AutoPostBack="True"/>
protected void server_handler(object sender, EventArgs e)
{
myUpdateMethod(this.myDdl.selectedValue);
}
This is working perfectly, but now I would like to ask a confirmation on my client side when a value is selected, does we really want to update the value in my db.
If we selected yes in my confirm dialog in js, we pursue and call the server like before, if not we stop the postback. But this is what I am not able to do, I can't stop the postback, this is what i've tried :
<asp:DropDownList ID="myDdl" runat="server" OnSelectedIndexChanged="server_handler" AutoPostBack="True" onchange="confirmornot(event)"/>
function confirmornot(event)
{
var str = confirm("do you want to continue?")
if (!str)// the user select no and this is where I am trying to stop to calling the server handler function. Basically there, I want here nothing to happen
{
//solution 1
event.preventDefault();
//solution 2
event.stopPropagation() or event.stopImmediatePropagation()
//solution 3
return false or return true
}
None of these solutions worked, the server side function is called whatever I put, I think that is because of my autpostback="true" on my drodown, but if I remove
this, then I will be in the opposite problem, and my server side function will never be called.
Thanks in advance for your help
You may try this:
Make ClientIDMode="Static" to asp net dropdown so that you will have static id "myDdl" and also set autopostback to false
In confirmornot method instead of return statement, try
__doPostBack('myDdl');
i Have a hacky solution for you
HTMl
Add a hidden field
<asp:HiddenField runat="server" ID="hdntocheck" />
DDL Markup
<asp:DropDownList ID="myDdl" runat="server" OnSelectedIndexChanged="server_handler" AutoPostBack="True" onchange="confirmornot()"/>
Js
function confirmornot() {
if (!confirm("do you want to continue?"))
{
hdntocheck.value = "false";
}
else {
hdntocheck.value = "true";
}
}
In Cs
protected void server_handler(object sender, EventArgs e)
{
if( hdntocheck.value =="true")
{
myUpdateMethod(this.myDdl.selectedValue);
}
}
I've spent almost 3 hours for the following case:
I want to trigger an AsyncPostBack from JavaScript but to be able to send same parameter also because I need it on the server side.
I've tried a lot of situations but I am unable to find a clear example.
I have an update panel and when I am pressing a specific image button inside it, some popup is displayed. (the popup is hidden initially, and when the request is done, the display:none is removed=> it appears fine)
function BeginRequestHandler(sender, args) {
}
function EndRequestHandler(sender, args) {
document.getElementById('popup').style.display = '';
document.getElementById('overlay').style.display = '';
}
Well, the issue is that I need to make a js function to do the asyncPostBack because this js function will be called from a flash control when doing click on some portion of that control, so I want to simulate my click on the image. (because doing click this popup is displayed as you see above)
The issue is that I am not able to find anywhere such an example. This js function will receive a parameter so when I do the postback I want to be able to get that parameter on the server side. (this parameters seems to be the main problem =- how I send it to the server when I am doing postback?).
Sorry if I was not very clear, but can you give me some documentation for this or example?
Thanks a lot!
UPDATE:
Please note that the first case I've already done, using an ImageButton in my UpdatePanel:
<asp:ImageButton ID="lnkDetails" runat="server" ImageUrl='<%# DataBinder.Eval(Container.DataItem, "Logo") %>'
AlternateText='<%# DataBinder.Eval(Container.DataItem, "Name") %>' OnCommand="lnkDetails_Command"
CommandArgument='<%# DataBinder.Eval(Container.DataItem, "TenantID") %>' Text="Click">
</asp:ImageButton></li>
What I only need is to "simulate" this click, using a javascript to make the async post back (because when I will call from flash, flash control will call my js method for postback)
To initiate an async postback from javascript:
__doPostBack(target,args)
target is the UniqueID of the UpdatePanel you want to target. Usually it works fine to just pass an empty string (will refresh all auto-updating panels).
The 2nd parameter is arguments that you can use for whatever you want.
Both will be available to you on the server:
Request.Form["__EVENTTARGET"]
Request.Form["__EVENTARGUMENT"]
This should work quite well:
<asp:ImageButton ID="ImageButton1" runat="server" OnClientClick='return doSomething(<%#Eval("SomeValue")%>);' />
EDIT: Try wrapping your JavaScript function with this:
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(function () {
doSomething = function(argument){
__doPostBack("<%=ImageButton1.ClientID%>", argument);
return true; //don't know if you need this
}
});
EDIT: Check your ScriptManager and make sure that EnablePartialRendering is set to true.
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" ... />
In the code-behind:
protected override void RaisePostBackEvent(IPostBackEventHandler source, string eventArgument)
{
//call the RaisePostBack event
base.RaisePostBackEvent(source, eventArgument);
if (source == ImageButton1)
{
string arg = eventArgument;
}
}