ASP/C# - UpdatePanel and Button OnClick Event Not Triggered - javascript

I've been trying to find the solution but it would be great if someone can take a look.
In my aspx page and C# codebehind I have the following:
aspx:
<asp:UpdatePanel runat="server" ID="UpdatePanel8" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnAddTableRow" EventName="Click" />
</Triggers>
<ContentTemplate>
<div id="divDynamicFields" runat="server"></div>
</ContentTemplate>
</asp:UpdatePanel>
<div hidden>
<asp:Button ID="btnAddTableRow" runat="server" OnClick="AddTableRow" />
</div>
<script type="text/javascript">
function addTableRow(tableId) {
$('#<%=btnAddTableRow.ClientID%>').click();
}
</script>
C#:
protected void AddTableRow(object sender, EventArgs e)
{
(...)
}
The event is triggered if I don't use UpdatePanel, but when executed with UpdatePanel, there is PostBack but the C# method is not called. I've tried to understand it for some time with no avail. Any ideas? Thank you.

After a good night sleep and a fresh mind, I finally found out what is failing. The JS function addTableRow(tableId) is actually called by buttons that are dynamically created in Page_Load (the number of these buttons are not fixed, hence associating them with this JS function which clicks the hidden button that triggers the event method from codebehind). Problem is, I was generating these buttons in the following way:
Button addRowButton = new Button();
addRowButton.Text = "This is my dynamically generated button";
addRowButton.Attributes.Add("onclick", "addTableRow('" + idControl + "')");
But things started working when I've changed to:
HtmlGenericControl addRowButton = new HtmlGenericControl("input");
addRowButton.Attributes.Add("type", "button");
addRowButton.Attributes.Add("onclick", "addTableRow('" + idControl + "');");
addRowButton.Attributes.Add("value", "This is my dynamically generated button");
It's actually kind of strange, since the button created with Button() still invoked JS function addTableRows and caused PostBack but didn't invoke the code behind method. Perhaps it had to do with the page life cycle and the generated IDs for the dynamic buttons that are generated in different ways depending on creating them as Button or HtmlGenericControl, but in any ways it's working now.

Related

asp.net c# __doPostBack button in UpdatePanel is working on second click

Situation:
I'm using multiview in my aspx.
in 2 views I have UpdatePanels and literals inside. my UpdatePanels are triggered by a timer (same timer). by c# I'm creating same postback button into these literals.
in my view1 I have 1 updatepanel and when I click the button it should activate view2. in view2 I have 2 different updatepanels. in first one I have this same button.
in this postback button I'm doing something and activating view2. My problem is the button in view1 is working on only second click. in view2, same button is working on first click. from my point of view, the only difference is view. all other details are perfectly same.
if I remove updatepanel from view1, button is working properly. so I'm assuming that problem is about UpdatePanel. in view2, same button is in updatepanel and it works properly. so I'm assuming that problem is view.
c# my button creation:
<td><input type='image' src='images/zoom1.png' id='btn' value='Match' onclick='javascript:__doPostBack(\"Match1\",\"" + dr1.GetValue(0).ToString() + "\");' ></td>
my button action:
private void Match1_Click(object sender, System.EventArgs e)
{
job1
job2
job3
MultiView1.ActiveViewIndex = 2;
}
my page_load:
if (IsPostBack)
{
if (Request.Form["__EVENTTARGET"] != null && Request.Form["__EVENTTARGET"] == "Match1")
{
Match1_Click(null, null);
}
}
my updatepanels are like:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Panel ID="Panel1" runat="server">
<div>
<asp:Literal ID="Literal1" runat="server"></asp:Literal>
</div>
</asp:Panel>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick"/>
</Triggers>
</asp:UpdatePanel>
When I try to do step over and move one by one with f10, I realized something strange. when I click the button at first, it triggers the action, I press f10 and it moves 1 line down then 4 lines up, 5 line down 3 lines up etc... and it doesn't end properly. so action is not ending as expected. when I click the button second time, I can move with f10 properly and everything works as expected.

<asp:Button> event not firing when within element affected by jQuery

I am creating an ASP.NET with C# calendar application. When a user clicks on a day, I am using a jQuery Popup Overlay which will allow the user to add an 'appointment' and click a button to process the entered information in the codebehind.
The Popup overlay basically hides an HTML element and makes it visible when another element is clicked (great examples by following link above).
The Code:
<asp:Button ID="ButtonA" runat="server" OnClick="Button_Click" Text="Button A" />
<asp:Label ID="Label" runat="server" Text="Foo"></asp:Label>
<div id='slide'>
<div id="content">
Content of the 'popup panel'
<asp:Button ID="ButtonB" runat="server" OnClick="Button_Click" Text="Button B" />
</div>
</div>
CodeBehind:
public void Button_Click(Object sender, EventArgs e)
{
Label.Text = "Bar";
}
Javascript:
$(document).ready(function () {
$('#slide').popup({
//options
});
});
I tried adding the AutoPostBack="true" parameter to the buttons, but it doesn't make a difference (should be automatic regardless, correct?). I also tried adding the runat="server" parameter to the div elements, but that made the issue worse.
I am afraid that I don't understand the nature of the issue enough to provide more information than this - Sorry!
It's likely that the jQuery plugin is overriding the behaviour of the button. You could use the onclose callback from the URL you provided to have a function like so:
function() {
__doPostBack("ctl00$MainContent$ButtonB","");
}
Failing that, you could have another button outside the popup div which you do a click() event on manually during the onclose event of the popup, but that seems like a bit of a hack!

Data from entity framework displayed in javascript/Jquery dialog

I have a problem, and looking for a solution for 2 days
Target : Create/edit client... in HTML build a dialog with and asp fields with clientIDMode static
<div id="divDialog" runat="server" clientidmode="Static" style="display: none;">
<div class="DialogFields">
<asp:Label ID="Label1" runat="server" Text="Firstname"></asp:Label>
<br />
<asp:TextBox ID="tbxFirstName" runat="server" ClientIDMode="Static"></asp:TextBox>
</div>
...
In script
$("#btnShowDialog").click(function () {
openDialog();
});
function openDialog() {
$("#divDialog").dialog('open');
$("#divDialog").parent().appendTo($("form:first"));
}
When I click the button btnShowDialog it works fine... But
Beneath it I have a gridview within it a edit button (asp:Linkbutton) with a event to the codebehind it looks like:
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="Edit" OnCommand="Edit_Click" CommandArgument='<%#Eval("RelationID") %>'
runat="server"><img src="../images/Edit-item.png" alt="Edit" /></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
In codebehind take the parameter from commandargument and fire LoadInfo (specific data to all the fields in de dialog).
LoadInfo(e.CommandArgument != null ? int.Parse(e.CommandArgument.ToString()) : -1);
but no way I get the dialog open.
I tried
ClientScript.RegisterStartupScript(this.GetType(), "Popup", "openDialog();", true);
and
ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "script", "openDialog();", true);
after this LoadInfo, push btnShowDialog button and it opens the dialog and all data perfect in place.
Also tried the other way around as Directly to Jquery function, get all data loaded and open the dialog. 2 problems, loading in codebehind was not even started before the dialog opens. and I only can get a static function in the codebehind.
A lot of ground to cover for me, but can any body help me out (even for a part).
...Thanx
If I understand your question correctly, you are trying to fire some client scripts (openDialog) from the server side, but they wont fire?
Try placing your page in an update panel, lets assume that we name the update panel "MyUpdatePanel". And then refer to the update panel like this:
ScriptManager.RegisterStartupScript(MyUpdatePanel, MyUpdatePanel.GetType(), "MyUpdatePanelScript", "openDialog();", true);

Populate a TextBox from a DropDownList selection ASP.NET/Javascript

I have a DDL and ASP.NET Textbox. I would like to populate the text box with the option I choose from the DDL. I need this to be instant and not use postbacks so it would seem JavaScript would be the obvious choice here. I have done quite a bit of searching but everything I have found seems to be for standard HTML (Selects and Inputs) and these do not appear to work with ASP objects:
<asp:DropDownList runat="server" ID="DDLSalesPerson" DataValueField="keyid" DataTextField="FullName" />
<asp:TextBox runat="server" id="txtSalesPerson" />
My DDL is populated from SQL in the code-behind page.
Can somebody assist with the appropriate code I should use? Thanks.
ASP.Net controls render as standard HTML elements on the browser. In script, you can get a reference to them by using the ClientID property of the ASP.Net control.
Put this in a script block in your aspx:
var ddl = document.getElementById('<%=DDLSalesPerson.ClientID %>');
var textBox = document.getElementById('<%= txtSalesPerson.ClientID%>');
Now you have references to the DOM objects for the select and input elements that the ASP.Net controls rendered and you can use the techniques you've already learned on the HTML elements.
Additional info
You need to add an onchange attribute to your DropDownList control as such:
<asp:DropDownList runat="server" ID="DDLSalesPerson" DataValueField="keyid" onchange="ddlChange();" DataTextField="FullName" />
and then put this script block in your aspx
<script type="text/javascript">
function ddlChange()
{
var ddl = document.getElementById('<%=DDLSalesPerson.ClientID %>');
var textBox = document.getElementById('<%= txtSalesPerson.ClientID%>');
textBox.value = ddl.options[ddl.selectedIndex].text;
}
</script>
As you change the dropdown list, you'll see the textbox update. Tested in IE and Chrome.
Since you've pointed out that you're a JavaScript beginner, may i suggest you use an updatepanel control. An updatepanel allows you to execute server code without refreshing the page. Simply place the dropdownList and the textbox in the same updatepanel or in two separate updatepanels and write the code for the textbox to update based on the dropdownlist selection. Make sure to set the dropdownlist to do autopostback.
The asp markup is as follows:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:DropDownList ID="ddlList" runat="server"
AutoPostBack="True">
<asp:ListItem>-select-</asp:ListItem>
<asp:ListItem>option 1</asp:ListItem>
<asp:ListItem>option 2</asp:ListItem>
</asp:DropDownList>
<asp:TextBox ID="txtTextBox" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
The codebehind in vb is as follows:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If ddlList.Text <> "-select-" then
txtTextBox.Text = ddlList.text
End If
End Sub
If you're new to JavaScript, use the jQuery library (simply provide references to the CDN-hosted jQUery files at google.com) and then you can use the following code:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<script language="javascript" type="text/javascript">
$("#DDLSalesPerson").change(function () {
$("#txtSalesPerson").val($(this).val());
});
</script>

How can I defer loading UpdatePanel content until after the page renders?

Old hand at ASP.NET, new to the UpdatePanel. I have a reporting page which executes a fairly length SQL query... takes about 10 seconds right now. What I would like to do is have my page fully render, with some placeholder text (Loading...) and then have the UpdatePanel kick off the actual time-consuming reporting process and render the report when it's done.
So... my theory is to use RegisterStartupScript() to kick this off and drop the string from GetPostBackEventReference() to trigger the UpdatePanel update. Some problems crop up:
1) Can I actually use GetPostBackEventReference w/ the UpdatePanel or do I need to trigger it some other way? Use this method on a button inside the Update Panel?
2) What event gets triggered when the postback reference is the UpdatePanel? It's not clear to me. I've got to call my databinding code somewhere! Again, maybe I need to use a button inside?
I had to do something very similar recently, here's how i did it (right or wrong):
The trick is a "Hidden Async Postback Trigger".
<asp:UpdatePanel ID="upFacebookImage" runat="server">
<ContentTemplate>
<!-- Your updatepanel content -->
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="hiddenAsyncTrigger" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<asp:Button ID="hiddenAsyncTrigger" runat="server" Text="AsyncUpdate" style="display:none;" />
Then from JavaScript, whenever you want to trigger the async postback, you do this:
__doPostBack('<%= hiddenAsyncTrigger.ClientID %>', 'OnClick');
In my example, i needed to trigger an async postback from a particular JS event. But you could attach it to doc ready.
I seem to remember trying #Marko Ivanovski's way, but for some reason it didn't work. I think you need to specify a "postback-able" control (ie a button) to trigger the postback.
HTH.
Updating this with my solution, I pieced together mostly from the first answer above.
I need my page to load, then then start loading content for my update panel. The panel calls some webservices and we don't want the whole page to crash in the event that the remote server doesn't respond. We don't want the wait either.
My HTML:
<asp:UpdatePanel ID="udpCheckout" runat="server" UpdateMode="Always">
<ContentTemplate>
<asp:Image ID="imgSpinner" runat="server" Visible="true" ImageUrl="~/images/ajax-loader.gif" />
<br />
<asp:Label ID="lblWait" runat="server" Visible="true" Text="Please wait..."></asp:Label>
<asp:Button ID="hiddenAsyncTrigger" runat="server" Text="AsyncUpdate" style="display:none;" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="hiddenAsyncTrigger" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
My Code behind snippets:
In page_load:
ScriptManager.RegisterStartupScript(Me.Page, Me.Page.GetType, "LoadUpdate", GetPostBackEventReference(hiddenAsyncTrigger, String.Empty), True)
And the button handler:
Sub LoadUpdatePanels(ByVal o As Object, ByVal e As EventArgs) Handles hiddenAsyncTrigger.Click
System.Threading.Thread.Sleep(5000) 'wait 5 seconds so I can see the page change
imgSpinner.Visible = False
lblWait.Text = "Content is now loaded."
'udpCheckout.Update()
End Sub
This was my test to see if I could get it working. Now to replace all of this with the real code!
Try something like this (not tested).
Set the UpdateMode of the UpdatePanel to Conditional.
Add this to your <head> section:
<script type="text/javascript">
window.onload = __doPostBack('UpdatePanel1', ''); // Replace UpdatePanel1 with the ID of your UpdatePanel
</script>
Simplifying RPM1984's very helpful earlier answer (thanks ;)) and showing some tweaks & a little more of the surrounding detail that I found necessary:
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="upFacebookImage" runat="server">
<ContentTemplate>
<asp:PlaceHolder runat="server" ID="PlaceHolderMediaPrompts" />
<asp:Button ID="hiddenAsyncTrigger" runat="server" Text="AsyncUpdate" OnClick="WasPage_Load" style="display:none;" />
</ContentTemplate>
</asp:UpdatePanel>
Note:
The hidden button's vital OnClick= parameter, this is what specifies the server function to call!
No trigger clause or triggers in the Update-panel, I am using the child controls which are automatically triggers - specifically the button Click event.
And to trigger it from client-side Javascript you can use:
document.getElementById("hiddenAsyncTrigger").click‌​();
However, I found it necessary to prevent this being called on subsequent page loads (as it caused unnecessary page load looping & consequent flicker). See the neat little IsPostBack() check below :)
e.g. To invoke this after page load (as per the original question), I just added a call to invoke the above line of code as the onload-parameter to the main Body-tag thus:
<body onload="DoPostLoad();">
...
<script type="text/javascript">
function DoPostLoad()
{
if ( IsPostBack() != true ) // ***This is NEW and ESSENTIAL! ***
document.getElementById("hiddenAsyncTrigger").click();
}
function IsPostBack() { // Ref. https://stackoverflow.com/questions/26978112/execute-javascript-only-on-page-load-not-postback-sharepoint
var ret = '<%= Page.IsPostBack%>' == 'True';
return ret;
}
. . .
</script>
</body>

Categories