__doPostBack not rendering on postback - asp.net

I'm having a strange problem.
I have to use GetPostBackEventRefence to force a Postback, but it works the first time, after the first postback, the .NET function is not rendered... any ideas?
This is what I'm missing after the postback:
<script language="javascript" type="text/javascript">
<!--
function __doPostBack(eventTarget, eventArgument) {
var theform;
if (window.navigator.appName.toLowerCase().indexOf("microsoft") > -1) {
theform = document.Main;
}
else {
theform = document.forms["Main"];
}
theform.__EVENTTARGET.value = eventTarget.split("$").join(":");
theform.__EVENTARGUMENT.value = eventArgument;
theform.submit();
}
// -->
</script>

Well, following that idea I created a dummy function with the postbackreference, and it works... it still is weird though, because of it rendering correctly the first time
this.Page.RegisterClientScriptBlock("DUMMY", "<script language='javascript'>function dummy() { " + this.Page.GetPostBackEventReference(this) + "; } </script>");

The first thing I would look at is whether you have any asp controls (such as linkbutton, comboboxes,that don't normally generate a submit but requre a postback) being displayed on the page.
The __doPostback function will only be put into the page if ASP thinks that one of your controls requires it.
If you aren't using one of those you can use:
Page.ClientScript.GetPostBackClientHyperlink(controlName, "")
to add the function to your page

Related

Prevent double clicking asp.net button

I realise this question has been asked but none of the answers worked for my project.
I have a button that when clicked calls an API, so there is a 1 second delay.
I have tried several things nothing works.
btnSave.Attributes.Add("onclick", " this.disabled = true; " + ClientScript.GetPostBackEventReference(btnSave, null) + ";");
Even that does nothing.
Prevent Double Click .Please add below code in your aspx page.
<script type="text/javascript" language="javascript">
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);
function BeginRequestHandler(sender, args) { var oControl = args.get_postBackElement(); oControl.disabled = true; }
</script>
This solution is simple and effective. On your button include this code:
OnClientClick="return CheckDouble();"
And wherever you want your JavaScript - e.g. At the bottom of your page:
<script type="text/javascript">
var submit = 0;
function CheckDouble() {
if (++submit > 1) {
alert('This sometimes takes a few seconds - please be patient.');
return false;
}
}
</script>
Most of the above suggestions failed to work for me. The one that did work was the following by tezzo:
Me.btnSave.Attributes.Add("onclick", "this.disabled=true;")
Me.btnSave.UseSubmitBehavior = False
Simpler still, rather than using the above in the code-behind, just use the following:
<asp:Button ID="btnSave" runat="server" Text="Save"
UseSubmitBehavior="false"
OnClientClick="this.disabled='true';"
</asp:button>
UseSubmitBehavior="false" is the key.
You can prevent double-clicking using this code:
Me.btnSave.Attributes.Add("onclick", "this.disabled=true;")
Me.btnSave.UseSubmitBehavior = False
So you can use btnSave_Click to call your API.
Usually I have a lot of Validators in my Page: setting Validator.SetFocusOnError = True I can run this code to reenable save button if a validation failed.
Me.YourControl.Attributes.Add("onfocus", Me.btnSave.ClientID & ".removeAttribute('disabled');")
This is the one I found works in all cases.
<form id="form1" runat="server">
<asp:Button ID="Button1" runat="server" Text="Button1" OnClick="Button1_Clicked" />
<asp:Button ID="Button2" runat="server" Text="Button2" />
</form>
Now here’s the short JavaScript snippet that will disable the button as soon as it is clicked so that when PostBack occurs the button cannot be clicked again.
<script type = "text/javascript">
function DisableButton() {
document.getElementById("<%=Button1.ClientID %>").disabled = true;
}
window.onbeforeunload = DisableButton;
</script>
The above script disables the ASP.Net Button as soon as the page is ready to do a PostBack or the ASP.Net form is submitted.
But in cases you might want to disable all Buttons and Submit Buttons on the page hence for such cases I have created another function which disables all Buttons and Submit buttons whenever there’s a PostBack or form submission
<script type = "text/javascript">
function DisableButtons() {
var inputs = document.getElementsByTagName("INPUT");
for (var i in inputs) {
if (inputs[i].type == "button" || inputs[i].type == "submit") {
inputs[i].disabled = true;
}
}
}
window.onbeforeunload = DisableButtons;
</script>
Prevent Double Click .Please add below code in your aspx page
<script type = "text/javascript">
function DisableButton() {
document.getElementById("<%=Button1.ClientID %>").disabled = true;
}
window.onbeforeunload = DisableButton;
</script>
At first my solution is like this:
<script>
function disableButton(btn) {
setTimeout(function () { btn.disabled = true; }, 20);
return true;
}
</script>
<asp:Button runat="server" ID="btnSave" Text="Save" OnClick="btnSave_Click" OnClientClick="return disableButton(this);" />
Without setTimeout the button will be immediately disabled and then the OnClick event will not be fired. The drawback of this approach is that the Save button will not be accessible anymore if some validation fails or some error happens.
So I don't think disable the button is a good solution, and come up with another solution:
function disableButton(btn) {
if (btn.hasclicked) return false;
btn.hasclicked = 1;
btn.onmouseenter = function () { this.hasclicked = 0; };
return true;
}
But my colleague points out that if the post processing is very slow, before it is finished, the user is still able to perform the double postback by leave-enter-click the button. So I figured out another two solutions:
Run the validation from client before submitting the form. But if your page contains multiple ValidationGroup, it is said that the following Page_ClientValidate() should be called multiple times with a passed-in ValidationGroup parameter: e.g. Page_ClientValidate("group1"):
function disableButton(btn) {
if (Page_ClientValidate) {
Page_ClientValidate();
if (!Page_IsValid) {
btn.setAttribute("btnClicked", "n");
return true;
}
}
if (btn.getAttribute("btnClicked") == "y") {
return false;
} else {
btn.setAttribute("btnClicked", "y");
return true;
}
}
As the ASP.NET has only one form in a page (not ASP.NET MVC), we can also let the onsubmit client event of the form to intercept the double click:
function disableButton(btn) {
$("form").submit(function () {
if (btn.getAttribute("btnClicked") == "y")
return false;
else
btn.setAttribute("btnClicked", "y");
return true;
});}
I'll ask QA to test those two approaches(Post edit: QA has proved that it is very dangerous to use this approach. Please refer to my following comments for details).
Try this way, it's a working solution:
For all browsers including Opera Mobile browser which doesn't support js, means your form will not be blocked in that type of browsers.
Add this in Page_load() method:
BtnID.Attributes.Add("onclick", "if(typeof (Page_ClientValidate) === 'function' && !Page_ClientValidate()){return false;} this.disabled = true;this.value = 'Working...';" + ClientScript.GetPostBackEventReference(BtnID, null) + ";");

Fire DropDownList SelectedIndexChanged event when using JQuery-UI Autocomplete

I'd like to post back to the server when my combobox changes value (ideally with an AJAX call in an update panel - but one thing at a time). I'm using the I'm using the jQuery UI AutoComplete Combobox and, unfortunately, it's interferring with the change event as I'm not changing the drop down list directly.
I'm using the implementation detailed here.
Here are some choice snippets
HTML Body Code
<span class="ui-widget">
<asp:DropDownList ID="cboLang" runat="server" AutoPostBack="True">
<asp:ListItem Value="ActionScript">ActionScript</asp:ListItem>
<asp:ListItem Value="AppleScript">AppleScript</asp:ListItem>
<asp:ListItem Value="Asp">Asp</asp:ListItem>
</asp:DropDownList>
</span>
Autocomplete Javascript
This is the autocomplete js that exexutes whenever a selection has been made. It will always run the function _removeIfInvalid
this._on(this.input, {
autocompleteselect: function (event, ui) {
ui.item.option.selected = true;
this._trigger("select", event, {
item: ui.item.option
});
},
autocompletechange: "_removeIfInvalid"
});
Server Side Code
Protected Sub cboLang_SelectedIndexChanged(sender As Object, e As EventArgs) _
Handles cboLang.SelectedIndexChanged
'DO OTHER STUFF HERE
Dim alert = String.Format("alert('{0}');", "Hi")
ScriptManager.RegisterStartupScript(Me, Me.GetType, "DropDownChange", alert, True)
End Sub
Generated Code
When an ASP.NET renders the page with the attached event, it produces the following code
<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['ctl00'];
if (!theForm) {
theForm = document.ctl00;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
</script>
<select id="cboLang" onchange="javascript:setTimeout('__doPostBack(\'cboLang\',\'\')', 0)"
name="cboLang" style="display: none;">
Question
Where can I go about making changes to ensure that with each update to the autcomplete input, I can trigger a server event?
There are a couple things that are helpful for answering this question. One is to take a look at JQuery-UI's own documentation on this function:
// Initialize the autocomplete with the select callback specified:
$( ".selector" ).autocomplete({ select: function( event, ui ) {}});
// Bind an event listener to the autocompleteselect event:
$( ".selector" ).on( "autocompleteselect", function( event, ui ) {} );
Essentially, what needs to happen, is something needs to signal a callback when the item has been selected (either from the menu or by typing and getting an exact match).
We can do this by modifying the default functionality demonstrated on the autocomplete page:
this._on( this.input, {
autocompleteselect: function( event, ui ) {
ui.item.option.selected = true;
this._trigger( "select", event, {
item: ui.item.option
});
},
autocompletechange: "_removeIfInvalid"
});
This code attaches listeneres on the select and change events and runs the inline defined function and the _removeIfInvalid function whenever those events fire (respectively)
By implementing the following changes we can do a postback when a valid selection has been made:
//attach listeners
this._on(this.input, {
autocompleteselect: "_selectFromMenu",
autocompletechange: "_removeIfInvalid"
});
Will get called anytime an item is selected from the menu:
_selectFromMenu: function (event, ui) {
ui.item.option.selected = true;
this._trigger("select", event, {
item: ui.item.option
});
__doPostBack('', '');
},
Will get called any time the text changes:
_removeIfInvalid: function (event, ui) {
// Selected an item, automatically valid, post back
if (ui.item) {
__doPostBack('', '');
return;
}
// Search for a match (case-insensitive)
var value = this.input.val(),
valueLowerCase = value.toLowerCase(),
valid = false;
this.element.children("option").each(function () {
if ($(this).text().toLowerCase() === valueLowerCase) {
this.selected = valid = true;
return false;
}
});
// Found a match, post back
if (valid) {
__doPostBack('', '');
return;
}
// Remove invalid value...
Here's a jsfiddle with the complete code changes, although __doPostBack is commented out because it is not being handled by anything
A couple further note:
I'm calling __doPostBack, but I'm relying on that method being available because of asp.net event handling generated code.
In order to initialize the combo box, you have to call $("#combobox").combobox();. Make sure that whatever is preforming that operation is still getting called on the return from the post back, otherwise the functionality will not come back. This is one thing to work past if you're using the code asynchronously in an update panel.
Instead of __doPostBack(this.element.attr('name'), '');
write
if (this.element.attr('onchange') != undefined && this.element.attr('onchange').indexOf("__doPostBack") >= 0)
__doPostBack(this.element.attr('name'), '');

ASP.Net Link Button not working in Firefox (Version 8)

I have developed an ASP.NET application to use in Facebook. It has a simple link button which is used to work as expected in older versions of Firefox.
<asp:LinkButton ID="lbtnLogOut" runat="server">Disconnect</asp:LinkButton>
Protected Sub lbtnLogOut_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles lbtnLogOut.Click
Response.Redirect(Request.ApplicationPath & "/login.aspx")
End Sub
After upgrading Firefox to 8, I noticed Link Button is not working i.e the button is not causing Post Back. When I view the source code, the Javascript code for Link Button to cause Post Back is
<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['form1'];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
</script>
I used Firebug to debug the above code but _doPostBack function is not firing when I clicked on Link Button. It is working in all other browsers (IE 9, Google Chrome, Safari) though.
Note: I am using this ASP.Net web application as App inside Facebook. Facebook basically displays this website inside it using iFrame.
There is a similar question here, but it does not provide any solution to me.
Wondering the issue is caused by Facebook iFrame or Firefox? Any help would be appreciated.
It doesn't look like you're assigning an event handler to the LinkButton.
<asp:LinkButton ID="LinkButton1" runat="server" Text="Click" OnClick="LinkButton1_Click" />
The JavaScript you posted is the __doPostBack function, which is not exclusive to the LinkButton. You are correct in the sense that LinkButtons use __doPostBack to trigger postbacks, but the function won't be called unless you assign an event handler to the LinkButton.
For debugging purposes, I would also set CausesValidation to false, just to make sure that validation doesn't interfere with the click event.
Just use this code in your .master file or other appriopiate file just before the end </body> tag:
<script language="javascript" type="text/javascript">
<!--
function __doPostBack(eventTarget, eventArgument) {
var theform;
if (window.navigator.appName.toLowerCase().indexOf("microsoft") > -1) {
theform = document.aspnetForm;
}
else {
theform = document.forms["aspnetForm"];
}
theform.__EVENTTARGET.value = eventTarget.split("$").join(":");
theform.__EVENTARGUMENT.value = eventArgument;
theform.submit();
}
// -->
</script>
Replace 'aspnetForm' with your own.

ASP.NET AJAX UpdatePanel scrolling problem

I'll try and be concise:
I have a dropdownlist with Autopostback set to true
I have an UpdatePanel that contains a Label.
When the downdownlist selection is changed, I want to update the label.
Problem: Focus is lost on the dropdownlist, forcing the user to click on the dropdownlist to reset focus back to the control.
My "solution": In the DropDownList_SelectionChanged event, set focus back to the drop down list:
dropdownlist1.focus()
While this works great in IE, Firefox and Chrome change the scroll position such that the control which was assigned focus is positioned at the bottom on the visible portion of the browser window. This is often a very disorientating side effect.
How can this be avoided so it works in FF as it does in IE?
Try MaintainScrollPositionOnPostback in one of these 3 ways
Programmatically - Page.MaintainScrollPositionOnPostBack = true;
Page declaration - <%# Page MaintainScrollPositionOnPostback="true" %>
In the web.config - <pages maintainScrollPositionOnPostBack="true" />
You may also need to add this javascript after the scriptmanager declaration:
<script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(beginRequest);
function beginRequest()
{
prm._scrollPosition = null;
}
</script>
Velika - Sorry for the delay.
If you are using a master page add :
<asp:ScriptManagerProxy runat="server" ID="smp"></asp:ScriptManagerProxy>
Otherwise just add
<asp:ScriptManager runat="server" id="sm" />
Had the exact same issue and got the answer. Hope this helps :
http://forums.asp.net/p/1622050/4164858.aspx#4164858
<script type="text/javascript">
var xPos, yPos;
var postBackElement;
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(EndRequestHandler);
prm.add_initializeRequest(InitializeRequest);
function EndRequestHandler(sender, args) {
if (postBackElement != null) {
document.getElementById(postBackElement.id).focus();
}
}
function InitializeRequest(sender, args) {
postBackElement = args.get_postBackElement();
}
try this one
<script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(beginRequest);
function beginRequest() {
prm._scrollPosition = window.top;
}
</script>
public static void SetFocusByJavaScript(Page page, string clientID)
{
string uniqueScriptId = String.Concat("focusScript", clientID);
string scriptBody = String.Format("setTimeout(\"$get('{0}').focus();\", 100);", clientID);
ScriptManager.RegisterStartupScript(page, page.GetType(), uniqueScriptId, scriptBody, true);
}
This is how I have been getting around this issue. The example requires jquery, but you could rewrite if needed. Basically just delays the focus script.

How to detect/track postback in javascript?

How to detect/track/check postback in javascript(e.g in asp.net Page.isPostBack())?
Any suggestion?
ASPX:
<input type="hidden" id="_ispostback" value="<%=Page.IsPostBack.ToString()%>" />
Client-side Script:
function isPostBack() { //function to check if page is a postback-ed one
return document.getElementById('_ispostback').value == 'True';
}
PS: I have not tested it but I've done somthing similar before and it works.
In some cases, you may want to check for postback without any server-side code. For example, in SharePoint, you cannot have code blocks in SharePoint Designer pages, so you can't use any solution that requires <%=something %>. Here is an alternative that involves no server-side code:
<script type="text/javascript">
function isPostBack()
{
return document.referrer.indexOf(document.location.href) > -1;
}
if (isPostBack()){
document.write('<span style="color:red;">Your search returned no results.</span><br/>');
}
</script>
One caveat (or feature, depending on how you look at it), this will detect not just postbacks, but any instance where the page links to itself.
If you want to check whether the current page will be a postback if the user clicks on a submit button, you can check for the presence of ViewState:
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="xxxxx" />
You can use something like document.getElementById("__VIEWSTATE") or the jQuery equivalent.
However, if you want to see whether the current page was generated in response to a postback, then you need to insert that data into the page on the server side first.
For example:
function isPostBack() {
return <%= Page.IsPostBack %>;
}
As JavaScript shouldn't be written with server-side code, and injecting new elements into the page seems like overkill, it seems to me that the simplest solution is to add [datat-*] attributes to the <head> element:
In Page_Load:
Page.Header.Attributes["data-is-postback"] IsPostBack ? "true" : "false";
This can then be accessed as:
jQuery:
$('head').data('isPostback');
Vanilla JS:
document.head.getAttribute('data-is-postback') === 'true';
Of course, if you treat the [data-is-postback] attribute as a boolean attribute, you could alternatively use:
In Page_Load:
if (IsPostBack)
{
Page.Header.Attributes.Add("data-is-postback", "");
}
else
{
Page.Header.Attributes.Remove("data-is-postback");
}
jQuery:
$('head').is('[data-is-postback]');
Vanilla JS:
document.head.hasAttribute('data-is-postback')
I have a solution that worked for me.
// Postback catch
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function (s, e) {
alert("post back");
});
See following:
<script type="text/javascript">
function invokeMeMaster() {
var chkPostBack = '<%= Page.IsPostBack ? "true" : "false" %>';
if (chkPostBack == 'false') {
alert('Only the first time');
}
}
window.onload = function() { invokeMeMaster(); };
</script>
You can only keep track of the postback if you are using AJAX requests or have a hidden field of some sort that the javascript reads on page load. Otherwise the page is regenerated and all POST data is lost; as you would expect and hope.
on Page_Load on your server-side :
The following uses an overload of RegisterClientScriptBlock() that will surround our string with the needed script tags
Server-Side
if (Page.IsPostBack){
ClientScript.RegisterClientScriptBlock(GetType(),
"IsPostBack", "var isPostBack = true;", true);
}
Then in your script which runs for the onLoad, check for the existence of that variable.
if (isPostBack){
//do something here
}
This should work for ASP.Net pages without relying on a backend supplied variable/control:
function isPostBack(frmID) {
var eventtarget = "";
var eventargument = "";
if (!!frmID) {
if (document.forms.length == 0) return false;
sForm = document.forms[0];
}
else {
sForm = document.getElementById(frmID);
if (!sForm) return false;
}
if (sForm.__EVENTTARGET) eventtarget = sForm.__EVENTTARGET.value;
else return false;
if (sForm.__EVENTARGUMENT) eventargument = sForm.__EVENTARGUMENT.value;
else return false;
if (eventtarget != "" || eventargument != "") return true;
else return false;
}
This is a simple JS way to determine the status of IsPostBack that I just got working in the Body of my ASPX page; needed to cause a PostBack during PageLoad for a project.
<script type="text/javascript">
if ('False' === '<%= Page.IsPostBack.ToString()%>')
{
__doPostBack();
}
</script>
Here is solution using jQuery:
$("a[href^='javascript:__doPostBack']").click(function () {
alert('ok');
});

Resources