I have a LinkButton that has to postback to perform some logic.
Once it is finished, instead of loading the page back up in the browser, I want to leave it alone and pop open a new window.
So far, the best idea I've had is to put the LinkButton in an UpdatePanel, and have it render some JavaScript out when it reloads, yet I think that is totally hacky. Also, if I recall right, JavaScript within a update panel won't run anyways.
Any other ideas?
Use LinkButton.PostBackUrl to set a different page to POST to, and some client script to get a new window (and the old target restored so that future postbacks work normally). The 2nd page can use PreviousPage to get access to any needed state from the original page.
<script runat="server">
void lnk_Click(object sender, EventArgs e) {
// Do work
}
</script>
<script type="text/javascript">
var oldTarget, oldAction;
function newWindowClick(target) {
var form = document.forms[0];
oldTarget = form.target;
oldAction = form.action;
form.target = target;
window.setTimeout(
"document.forms[0].target=oldTarget;"
+ "document.forms[0].action=oldAction;",
200
);
}
</script>
<asp:LinkButton runat="server" PostBackUrl="Details.aspx" Text="Click Me"
OnClick="lnk_Click"
OnClientClick="newWindowClick('details');" />
Here is the code:
protected void Button1_Click(object sender, EventArgs e)
{
// Do some server side work
string script = "window.open('http://www.yahoo.com','Yahoo')";
if (!ClientScript.IsClientScriptBlockRegistered("NewWindow"))
{
ClientScript.RegisterClientScriptBlock(this.GetType(),"NewWindow",script, true);
}
}
One thing you could try is to have your LinkButton OnClick event do its processing, then register a Page.ClientScript.RegisterStartupScript with the popup code, which will put some Javascript into the tag to fire off after the page loads. This should launch your new window after the processing completes.
EDIT: Reading your comment, I believe you can still use this approach, have your results stored in a session variable, and then have the popup page pull the results from there.
Related
I have created a simple payment form where contains fields that accept amount, the drop-in UI and the submit button.
<form id="form1" runat="server">
<div>
<label>Amount:</label>
<asp:TextBox ID="txtAmount" runat="server" />
</div>
<div id="dropin-container"></div>
<asp:Button ID="btnSubmit" runat="server" OnClick="btnSubmit_Click" Text="Submit" />
<script src="https://js.braintreegateway.com/v2/braintree.js"></script>
<script>
braintree.setup("<%= this.ClientToken %>", "dropin", { container: "dropin-container" });
</script>
and the code behind
protected string ClientToken = String.Empty;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
GenerateClientToken();
}
}
protected void GenerateClientToken()
{
var gateway = new BraintreeGateway
{
Environment = Braintree.Environment.SANDBOX,
MerchantId = "merchant-id",
PublicKey = "public-key",
PrivateKey = "private-key"
};
this.ClientToken = gateway.ClientToken.generate();
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
var gateway = new BraintreeGateway
{
Environment = Braintree.Environment.SANDBOX,
MerchantId = "merchant-id",
PublicKey = "public-key",
PrivateKey = "private-key"
};
var request = new TransactionRequest
{
Amount = Convert.ToDecimal(this.txtAmount.Text),
PaymentMethodNonce = Request.Form["payment_method_nonce"]
};
Result<Transaction> result = gateway.Transaction.Sale(request);
}
After I load the page in the browser, I can see the form that accept amount and also the drop-in ui form which accept credit card and/or PayPal.
The issue is when I click Submit button, the method btnSubmit_Click doesn't get called. The page looks like it post back correctly but I cannot see any line of code within the btnSubmit_Click is executed.
I follow the instruction from this page:
https://www.braintreepayments.com/features/drop-in
But I really can't think of anything that I miss.
Anyone can help me with this issue would be very appreciated. Thank you so much.
Knott
I work at Braintree and can help you with this question.
Some background on what braintree.js is doing when you load the Drop-in on your page: it listens for form submissions, and when it detects one it will interrupt the form submit, communicate with Braintree to generate a nonce, and then run your callback if defined. What’s happening is that your .NET postback event is broadcasting a submit action – the same type of action that braintree.js interrupts in the first place.
As a workaround, you can try adding the following to your Page_Load code:
ClientScript.GetPostBackEventReference(this, string.Empty);
ClientScript.RegisterClientScriptBlock(this.GetType(), "PayEvent","<script>function PayEvent() {document.getElementById('__EVENTTARGET').value = '"+ btnSubmit.ClientID +"'; }</script>" );
btnSubmit.Attributes.Add("onClick", "PayEvent()");
Where btnSubmit is the ID of your button.
This should circumvent the submit interruption and allow your form to be submitted properly. In addition, this problem does not occur with our custom integration as an alternative.
Let us know if you have any further questions.
You just needed to put your transaction request code in a method and then call that sub on a post back rather than page load.
This way the auto submit won't interrupt with things.
Protected void Page_Load(object sender, EventArgs e) {
if (!Page.IsPostBack) {
GetClientToken();
} else {
Pay();
}
}
protected void Pay() {
PaymentMethodNonce = Request.Form["payment_method_nonce"]
//Build request string etc.
}
Brian,
Your solution above was supplied to me by PayPal support, but unfortunately, it doesn't solve the problem.
To be honest, it is this 'listening' (read: unreliable, 'clever code') to form submissions which is causing all the problems when one tries to integrate it in a Web Forms/UpdatePanel page - it really isn't designed for WebForms/UpdatePanels and requires all kinds of really messy code to make it work and synchronise properly. It is almost as if it was never designed for anything other than MVC or Java!
What would be a far better solution would be if we could attach a JavaScript call in OnClientClick of a button which synchronously calls BrainTree/PayPal via a JavaScript module hosted on PayPal which returns the nonce so that we can then do something with it. As it stands now, the Braintree/PayPal code intercepts a submit button (all buttons in WebForms are 'submits' by default, so this causes problems) and fires off a call asynchronously to get a nonce and at the same time, calls the button OnClick in the C# code. The net result is that the C# code runs before the Braintree/PayPal call returns and you can never synchronise the two.
Following is the scenario I am facing, I have a aspx page in which I have added my ascx user control, I also have a <a href control which call a js function to open a aspx popup.
when I open the popup, I need to send the data present in the ascx control to my popup. can you please guide me what method can I use to achieve this other than using session, as the data can be updated in many different places hence maintaining in session will be difficult.
Thanks
try with these syntaxe ( RegisterStartupScript + window.open)
ScriptManager.RegisterStartupScript(Page, Page.GetType(), "newWindow", "window.open('Test.aspx?ID=" + _cId + "','_blank','status=1,toolbar=0,menubar=0,location=1,scrollbars=1,resizable=1,width=30,height=30);", false);
You said that you are using a js function to open the aspx popup.
then it is simple.
1. Read the Data from the controls of the User control by using javascript
var variable1 = document.getElementByID("ControlId").value;
var variable2 = document.getElementByID("ControlId").value;
2. Pass this data as query string to the next page
window.open("http://www.w3schools.com?id=" + variable1 + "&name=" + variable2);
You can read this data from querystring from the next page
If you cant sent data as querystring , can try some other ways
1. Try to post the form to the other page using target="_blank".
we can dynamically change the form action if needed.
OR
2. Make use of the window.opener object from the popup to read the data from controls the opener page.
var variable1 = window.opener.getElementById("ControlId").value
Create a hidden variable in your ascx.
<asp:HiddenField runat="server" ID="hdnId" />
On page load of ascx set the value to be sent to the hidden variable
protected void Page_Load(object sender, EventArgs e){
hdnId.Value = <value to be sent to pop-up>;
}
Register a ajax manager in the code behind.
protected override void OnInit(EventArgs e)
{
RadAjaxManager.GetCurrent(this.Page).ClientEvents.OnRequestStart = "ajaxMngr_RequestStart;";
base.OnInit(e);
}
In the ajaxMngr_RequestStart() JS
function ajaxMngr_SA_RequestStart(sender, args) {
var oPatId = "<%=hdnSendPatId.Value %>";
//add code to open the pop-up, add oPatId as part of the URL
}
}
I use Telerik, which makes helps a lot in managing pop-ups. Let me know, if this helps.
Cheers!
I have a popup in my page which I am trying to show on dropdownlist selected index changed event.
Here is register statement
ClientScript.RegisterClientScriptBlock(GetType(),"id", "ShowApplicationPopUp()",true);
Here is my javascript function
function ShowApplicationPopUp() {
$('#NewCustomerMask').show("slow");
$('#NewCustomerApplicationPopUp').show("slow");
}
Both of my divs are initially hidden by using display:none; statement.
The problem is when my dropdownlist is changed the popup is not seen at all.I tried putting an alert statement to check if the function is called , and the alert statement is fired.Any ideas as to what I am doing wrong.
Any suggestions are welcome.
Thanks.
When you use RegisterClientScriptBlock the Javascript code is inserted early in the page, so it will run before the elements are loaded.
Use RegisterStartupScript instead, which places the code at the end of the form.
I too could not get this code to work but thanks to the above I now have working code. Note, I have a linkbutton inside an Ajax Update Panel.
in my code behind aspx.cs page is:
protected void OpenButton_Click(object s, EventArgs e)
{
// open new window
string httpLink = "../newWindow.aspx";
ScriptManager.RegisterStartupScript(this, GetType(), "script", "openWindow('" + httpLink + "');", true);
}
in my apsx page is first the link to jQuery source, then second the JavaScript for the openWindow function:
<script src="../js/jquery-1.10.1.js" type="text/javascript"></script>
<script type="text/javascript">
function openWindow(url) {
var w = window.open(url, '', 'width=1000,height=1000,toolbar=0,status=0,location=0,menubar=0,directories=0,resizable=1,scrollbars=1');
w.focus();
}
</script>
and the link that makes it all happen:
<asp:LinkButton Text="Open New Window" ID="LnkBtn" OnClick="OpenButton_Click" runat="server" EnableViewState="False" BorderStyle="None"></asp:LinkButton>
Im not a jQuery expert and must attribute some of this to the following blog:
https://blog.yaplex.com/asp-net/open-new-window-from-code-behind-in-asp-net/
I have some processing that can take up to 5+ seconds the first time the page is loaded on the server. This is an external constraint that's beyond my control and since it's happening in a WebPart that can be added to any page on servers that are outside of my control, I can't do this processing at a larger scope such as the application.
I'd like the page to show progress while a partial postback happens in an updatepanel instead of the user waiting for the page to load before seeing anything at all. The code behind that postback will do the busy work.
I've tried using an ajax timer which works well except when there's an exception thrown in the code behind the postback.
In summary I would like to know how to perform a partial postback once and only once as soon as the page loads on the client.
I figured this out. To partial postback to the server via an UpdatePanel without using hidden controls, do this with jQuery:
<script type="text/javascript">
$(document).ready(function () {
__doPostBack('<%=UpdatePanel1.ClientID %>');
});
</script>
This will perform a partial postback to the server against the UpdatePanel with the ID UpdatePanel1 as soon as the HTML DOM is ready. You can then use the ASP.NET page life cycle to hook into whatever event is appropriate for you. I hooked into the load event of the update panel:
protected void UpdatePanel1_Load(object sender, EventArgs e)
{
if (Page.IsPostBack && Session["InitializedKey"] == null)
{
Session["InitializedKey"] = true;
// do your initialization stuff here
}
}
The code above will only run if the page is posting back and the session variable is set. Now you have to clear the session variable when the user refreshes the page since the intent here is to run this code on the first postback and only the first postback. So clear the session variable in the Page_Load:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
Session[initializedKey] = null;
}
And if you want to show a progress indicator while the page is in partial postback, do this javascript:
<script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(BeginRequestHandler);
prm.add_endRequest(EndRequestHandler);
function BeginRequestHandler(sender, args) {
if (args._postBackElement.id == '<%=UpdatePanel1.ClientID %>') {
$get('Progress').className = 'Progress';
}
}
function EndRequestHandler(sender, args) {
if (sender._postBackSettings.sourceElement.id == '<%=UpdatePanel1.ClientID %>') {
$get('Progress').className = 'Hidden';
}
}
</script>
This requires a div tag with the id 'Progress' and whatever you want to show for progress within that div. You also need some css to set the display and visible styles on the div tag in classes named Hidden and Progress. Don't forget to perform error handling on partial postbacks!
I am using an ASP.NET ModalPopupExtender on a page and would like to prevent the dialog from hiding when the user presses the ok button in certain conditions. But I can't seem to find a way.
What I am looking for is something like this
ajax:ModalPopupExtender
...
OnOkScript="return confirm('You sure?')"
...
if confirm is false, then the modal dialog doesn't disappear.
From my understanding in your specific situation you would not wire up the button, and just wire up a script to handle the conditional, then you can close it via JS.
The following JavaScript function will allow you to achieve this:
function conditionalHide(clientID)
{
if (confirm('You sure?'))
{
$find(clientID).hide();
}
}
You can wire this up to your asp:Button control in the Page_Load event of your page
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
btnOK.OnClientClick = string.Format("conditionalHide('{0}'); return false;",
panPopup_ModalPopupExtender.ClientID);
}
}
Some notes:
panPopup_ModalPopupExtender is your ModalPopupExtender
The return false; prevents a postback from occurring when the user clicks the button
You could hard-code the ClientID of the ModalPopupExtender, but this introduces an (additional) maintainance headache. The approach shown is the best one that I've found to alleviate this overhead