Update Panel updates once and causes post back on other triggers - c#

I am dynamically building Image buttons and placing them inside an ASP placeholder. When the user clicks on an image(button) it should update the panel with the school's information. The panel updates correctly the first time a button is clicked but when I click another button it causes a post back. On that second, third, etc... it should update the panel without a post back.
When I am building the buttons I am also creating triggers and setting the control ID to the button's ID. I have debugged and verified that these triggers are being created properly.
Button and Trigger Creation
int counter = 0;
foreach (DataRow row in tempTable.Rows)
{
var button = new ImageButton
{
ID = counter.ToString(),
CausesValidation = false
//OnClientClick= "return false;"
};
button.Command += new CommandEventHandler(buildSchoolInfo); //The onclick event that builds the school info
button.CommandName = "ImageButton" + counter.ToString();
button.CommandArgument = "Test" + counter.ToString();
SchoolListPH.Controls.Add(button); //Add image button to placeholder
AsyncPostBackTrigger trigger = new AsyncPostBackTrigger();
trigger.ControlID = button.ID;
//trigger.EventName = "Click";
schoolInfoUP.Triggers.Add(trigger); //Adding the trigger to the Update Panel
counter++;
}
ASPX Code
<div style="border: 1px solid black">
<asp:PlaceHolder ID="SchoolListPH" runat="server"></asp:PlaceHolder>
</div>
<%-- This is the literal that builds with all of the selected schools information --%>
<asp:UpdatePanel ID="schoolInfoUP" runat="server" >
<ContentTemplate>
<asp:Literal ID="litTable" runat="server"></asp:Literal>
</ContentTemplate>
</asp:UpdatePanel>

After searching the internet for wayyyy to long this single line fixed it for me.
ScriptManager.GetCurrent(Page).RegisterAsyncPostBackControl(button);
I placed it just after I added the trigger to the update panel.

Related

AsyncFileUpload does not fire server side UploadComplete

I have an AsyncFileUpload control inside an update panel in a page that is using a master page.
When I select a file, the client side OnClientUploadComplete fires but not the server side. I searched the issue and tried different suggestions, including adding a hidden button outside update panel and "click" it on client script to force an async postback as well as modifying the "form" tag on master page to include encrypt type but nothing seems to be working.
In aspx file I have:
<script type="text/javascript">
function onClientUploadComplete(sender, e) {debugger
var ct = e.get_contentType();
var fn = e.get_fileName();
var l = e.get_length();
var p = e.get_path();
document.getElementById('uploadCompleteInfo').innerHTML = '';
__doPostBack('upnlNews', '');
}
function onClientUploadStart(sender, e) {
document.getElementById('uploadCompleteInfo').innerHTML = 'Please wait while uploading ' + e._fileName;
}
</script>
<asp:UpdatePanel runat="server" ID="upnlNews">
<ContentTemplate>
<ajaxToolkit:AsyncFileUpload runat="server" ID="fuAttchedDocs"
ThrobberID="myThrobber"
UploaderStyle="Traditional"
OnClientUploadComplete="onClientUploadComplete"
onuploadedcomplete="fuAttchedDocs_UploadedComplete"
onuploadedfileerror="fuAttchedDocs_UploadedFileError" />
<asp:Label runat="server" ID="myThrobber" Style="display: none;">
<img align="middle" alt="" src="../assets/images/6.gif" />
</asp:Label>
<div id="uploadCompleteInfo"></div><br />
</ContentTemplate>
</asp:UpdatePanel>
Additional Info
when I put a breakpoint in client side script and check the variables in Chrome Developer Tool, I see the following:
function onClientUploadComplete(sender, e) {debugger
var ct = e.get_contentType(); ==> ct = ""
var fn = e.get_fileName(); ==> fn = "spock.jpg"
var l = e.get_length(); ==> l = "NaN"
var p = e.get_path(); ==> p = "C:\fakepath\spock.jpg"
document.getElementById('uploadCompleteInfo').innerHTML = '';
__doPostBack('upnlNews', '');
}
The fact that file length shows as NaN is a bit fishy!
I found out that the UI designer had added a Search text box and button combo and had contained them in a <form>...</form> tag; so the page two <form> tags, one contained within the other (main page form tag and this one). This broke the code. I realized that when I found that even a regular button would not fire its OnClick event. After I changed the form tags to div everything worked fine.

Get rowindex of gridview on click of a button outside gridview

In my asp.net application (v4.0), I have a grid view. I use a list object to bind data to the grid view.
In the grid view there is a cancel button. On click of the cancel button the application should pop a message to the user asking for confirmation to proceed with cancel. ie. are you sure you want to cancel the record yes/no. When the user selects yes then the particular record should be cancelled.
Now the issue is, when the user selects yes then i need to the get the index of the row for which the cancel button is clicked and i need to remove it from the list object that is used to bind the grid and rebind the gridview .
please let me know how to achieve this.
Thanks for all the reply.. im using custom pop up instead of built in 'confirm' method. The custom pop up will have 'OK' and 'Cancel' button controls. Only on click of 'OK' button i need to get the selected record index. Built in confirm method mentioned in some replies will not suit my scenario. please let me know how to achieve this.
Add a hiddenfield into your page
<asp:HiddenField ID="HiddenField1" runat="server" />
Use the Id(use corresponding column name instead of Id) of the records as the CommandArgument of Cancel button
<asp:Button ID="btncancel" runat="server" CommandArgument='<%#Eval("Id") %>' Text="Cancel" />
Then on clicking the cancel button it calls the gridviews rowcommand function. In that function keep the CommandArgument value in the hidden field as follows
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
HiddenField1.Value = e.CommandArgument.ToString();
}
Then on clicking the OK button, it calls the click event. In that function remove the Item from the List and then bind the list again to the gridview
protected void btnOK_Click(object sender, ButtonClickEventArgs e)
{
string id = HiddenField1.Value;
//use this id to remove the data from the List
// bind the gridview
}
Try this..
You can use javascript function..
<asp:Button ID="Button1" runat="server" onclientclick="Validate(this) />
Declare an HTML hidden field in your page...
<input id="Hidden1" type="hidden" runat="server" clientidmode="static"/>
function Validate(obj) {
var r = confirm("are you sure you want to cancel ?");
if (r == true) {
var id = obj.id.toString();
var index = id.split("_");
var RowNumber = index[2].toString();
document.getElementById('Hidden1').value=RowNumber ;
}
else {
return;
}
}
Here we get id of the button somewhat as ContentPlacedholde_Button1_0..Then we split it to get the index..
Use command name and command argument on cancel button like this:
<asp:Button ID="btncancel" runat="server" CommandArgument='<%#Eval("Id") %>' CommandName="Cancel" Text="Cancel" />
And then on gridviewRowcommand use this:
if (e.CommandName == "Cancel")
{
int count = GridViewName.Rows.Count;
for (int i = 0; i < count; i++)
{
int id = Convert.ToInt32(e.CommandArgument);
}
}
Have you tried adding a CommandArgument value to the cancel button that represents the item, for example an ID? Then onclick, display a popup, if the user selects yes then use the ID to remove the item from your collection, then simply rebind the grid. The item will then be gone.

Creating an asyncpostback from a control inside a repeater

I have a repeater whose ItemTemplate contains a PlaceHolder that I add input controls (ListBox, TextBox, CalendarExtender etc.) to on ItemDataBound:
<asp:UpdatePanel ID="ReportParameterUpdatePanel" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:Repeater ID="ReportParameterEditRepeater" OnItemDataBound="ReportParameterEditRepeater_ItemDataBound" runat="server">
<ItemTemplate>
<asp:PlaceHolder runat="server" ID="ParameterEntryPlaceholder"></asp:PlaceHolder>
</ItemTemplate>
</asp:Repeater>
</ContentTemplate>
</asp:UpdatePanel>
How can I generate an asyncpostback from one of these TextBoxes inside the repeater (on TextChanged)?
The control is created dynamically and I only want to create the postback under certain conditions, so it needs to be done from code behind.
I have tried:
OnItemCommand (but this appears to be just for buttons)
ScriptManager.RegisterAsyncPostBackControl (doesn't seem to do anything on TextChanged)
UpdatePanel.Triggers.Add(new AsyncPostBackTrigger ...) (unable to find the TextBox as it is inside the repeater)
In ReportParameterEditRepeater_ItemDataBound you will need to assign a unique ID to each control, and then bind the text changed event. I then like to store those in session. Then add it to your placeholder.
Below is how I did it in my site for a button click event:
TemplateControls_Headline ctrl = (TemplateControls_Headline)LoadControl("~/Controls/TemplateHeadline.ascx");
ctrl.ID = "MyCtrl_" + CMSSession.Current.AddedTemplateControls.Count;
ctrl.Remove.Click += new EventHandler(RemoveItem_OnClick);
MySession.Current.AddedTemplateControls.Add((Control)ctrl);
PlaceHolder ph = accAddTemplates.FindControl("phAddTemplateControlsArea") as PlaceHolder;
ph.Controls.Add(ctrl);
Then, in your OnInit of the page, you have to re-bind everything from the viewstate since you are creating them dynamically, this is where the unique id you created comes in (this is mainly for postbacks):
protected override void OnInit(EventArgs e)
{
PlaceHolder ph = accAddTemplates.FindControl("phAddTemplateControlsArea") as PlaceHolder;
int counter = 0;
foreach (UserControl ctrl in MySession.Current.AddedTemplateControls)
{
ctrl.ID = "MyCtrl_" + counter;
ctrl.Remove.CommandArgument = counter.ToString();
ctrl.Remove.Click += new EventHandler(RemoveItem_OnClick);
counter++;
ph.Controls.Add(ctrl);
}
base.OnInit(e);
}

Disable page reload in update panel

I have an ASP.NET page with an update panel.
Normally, if I use an update panel, there should be postbacks only but no complete page reloads.
In my case, when I click a button, it always makes an page reload. Although this button is in an update panel.
What I found out: When I put
Response.End();
in the Button_Click Method, there is no reload.
My code on the .aspx:
<asp:UpdatePanel ID="upUserDefault" runat="server">
<Triggers>
<asp:PostBackTrigger ControlID="btnPrintSelectedArticles" />
</Triggers>
<ContentTemplate>
<cc1:MenuButton runat="server" ID="btnPrintSelectedArticles" OnClientClick="return ShowPrintStickersPopUp();" ButtonText="Print" />
</ContentTemplate>
</asp:UpdatePanel>
Code behind:
Page Load:
btnPrintSelectedArticles.MenuButton_Click += btnPrintSelectedArticles_MenuButton_Click;
Method:
void btnPrintSelectedArticles_MenuButton_Click(object sender, EventArgs e)
{
// Disables reload
Response.End();
}
MenuButton is a user control
Any ideas how to disable the reload of the complete page?
Edit:
This is the ShowPrintStickersPopUp JS from the ClienClick. It simply checks a gridview if there are any checkboxes checked
function ShowPrintStickersPopUp() {
var gridView = document.getElementById('<% =gvArticles.ClientID %>');
//get all the control of the type INPUT in the base control.
var inputs = gridView.getElementsByTagName("input");
for (var n = 0; n < inputs.length; ++n) {
if (inputs[n].type == 'checkbox' && inputs[n].checked) {
// If at least 1 checkbox is checked, open popup
window.open('PrintStickersPopUp.aspx', 'Print Stickers', 'width=700,height=550');
return true;
}
}
return false;
}
Your client method looks good. Did you remember to add a ScriptManager object on your page? A lot of issues relating to UpdatePanels are related to not having one added.

ASP.net UpdatePanel dynamically using C# code

I have a custom usercontrol that has some Asp.net code. I would like to write the same code but with C#.
The problem is that i don't know how to put a repeater and some buttons into the ContentTemplate.
The Asp.net Code :
<asp:UpdatePanel runat="server" ID="up">
<ContentTemplate>
<n2:Repeater ID="rpt" runat="server">
<ItemTemplate></ItemTemplate>
</n2:Repeater>
<asp:LinkButton runat="server" ID="btnFirst"
Visible="false" Enabled="false" Text="<<" OnClick="btnFirst_Click" />
</ContentTemplate>
</asp:UpdatePanel>
So how could I write this chunk in C# code? To be precise, how could I insert the repeater and the Linkbutton into the ContentTemplate.
Note : I don't want to use the LoadTemplate to do it.
Edit
I have tried ContentTemplateContainer.Controls.Add():
private UpdatePanel up = new UpdatePanel();
private Repeater rpt = Repeater();;
public Paging{
//Add repeater to updatePanel
up.ContentTemplateContainer.Controls.Add(rpt);
AsyncPostBackTrigger apb3 = new AsyncPostBackTrigger();
apb3.ControlID = "btnFirst";
apb3.EventName = "Click";
//Add Triggers to updatePanel
up.Triggers.Add(apb1);
//Create buttons
btnFirst = new LinkButton();
btnFirst.Visible = false;
btnFirst.Enabled = false;
btnFirst.Text = "<<";
btnFirst.Click += new EventHandler(btnFirst_Click);
//Add buttons to update panel
up.ContentTemplateContainer.Controls.Add(btnFirst);
}
protected void Page_Load(object sender, EventArgs e)
{
rpt.ItemTemplate = LoadTemplate("~/UI/Templates/NewsEvent.ascx");
....
}
I have an error caused by the first line on Page_Load :
Databinding methods such as Eval(), XPath(), and Bind() can only be used in controls contained in a page.
This is NewsEvent.ascx:
<img src='<%# Eval("ImageThumbnail") %>' alt="" />
you cant do this with ITemplate types ... i had a similar problem trying to clone a tabpanel in a tabcontainer control ... i already had a hidden tabpanel and all i wanted to do was create a new tabpanel and basically instantiate the ITemplate from the hidden one in the new one.
The problem is ITemplate ... it's not very dynamic for code behind interactions i would suggest putting that markup on the page as you already have and setting visible = false on the parent then when you need to databind and show the hidden panel.
getting the initial bind to work isn't the problem ... its the postback handling ...
Ajax TabContainerTabPanels Break postbacks

Categories