I have a gridview where I have button for each row. After clicking this button, the Modal PopUp Extender Panel is opened (with PanelName.Show()). The Panel contains a user control, which shows some labels, textboxes,etc. with an additional info binded form SqlDataSource. Until this point it works well. But, when I click another button, the panel is purely shown but the content is not refreshed (based on which button is clicked, some details info should be shown). Basically, the method SqlDataSource_Selecting is called only for the panel popup showing but not anymore.
How can I force panel to be refreshed (reloaded) after each PanelName.Show()??
Thanks in advance.
If I'm understanding your question correctly, I think the problem is that you just need to re-Bind your data bound controls after the user clicks the button to change the Selected item. You can use [ControlName].DataBind() to do that. Does that make sense?
It depends on whether the control(s) you want to refresh are DataBound() or not.
In other words, can you force the control to reload by using a DataBind() method call to force the control to reload itself, with either the same or new data?
Most GUI controls have the DataBind() method, but it's useless if the control is not actually using data to work!
This is why in your case your panel is not "refreshed" with new data because using a DataBind() on the panel does nothing. Using a databind() on the entire GridView is a different story and should work. Maybe place an UPDATEPANEL around the whole lot? If you do you have to be careful your normal edits and other Commands on the rows will continue to work.
However, What you can do is place the modalpopupextender inside your TemplateField, and using a "trick", you can keep your server post backs and still fire the popup panel.
ie
<asp:UpdatePanel ID="upADDMAIN" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Button ID="btnADD" runat="server" Text="NEW LOGIN" BackColor="Blue" Font-Bold="True" ForeColor="#FFFFCC" OnClick="btnADD_Click" />
<asp:Button ID="btnDUM" runat="server" style="display:none" />
<div style="height:20px">
</div>
<ajaxToolkit:ModalPopupExtender ID="mpeADD" runat="server"
targetcontrolid="btnDUM"
popupcontrolid="upADD"
backgroundcssclass="modelbackground">
</ajaxToolkit:ModalPopupExtender>
<asp:UpdatePanel ID="upAdd" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Panel ID="pnlADD" runat="server" Width="700px" HorizontalAlign="Center" CssClass="auto-style10" Height="200px">
..
..
<div id="puFTR" class="auto-style17" style="vertical-align: middle">
<asp:Button id="btnOK" runat="server" Text="OK" style="width: 80px" OnClick="btnOK_Click" />
<asp:Button id="btnCAN" runat="server" Text="CANCEL" style="width: 80px" OnClick="btnCAN_Click" CausesValidation="False" />
</div>
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
</ContentTemplate>
</asp:UpdatePanel>
As you may see, the btnDUM control is a Dummy to get the MPE to work, but it's not actually used as it's hidden by the style="display:none" tag.
However, the btnADD does work because it calls a Click() method on the server side which does the refresh of data on your new row. You may have to use a little jScript to pass the ROWINDEX into the Click() method for it to work with a GridView.
Incidentally, the Click() method in my case "controls" the MPE manually...
protected void btnADD_Click(object sender, EventArgs e)
{
ClearADDform();
mpeADD.Show();
}
protected void ClearADDform()
{
txtLOGIN.Text = string.Empty;
cbISActive.Checked = true;
txtPWD.Text = string.Empty;
ddlAgent.SelectedIndex = -1;
}
In my case, the above code example is outside a GridView, so you'll need to adjust.
But the point is, you can still have Server Side calls using Ajax popups!
Good luck.
Related
In ASP.NET when using validation controls (i.e. RequiredFieldValidator) the client sided framework will execute the JS function Page_ClientValidate. This function will validate all controls on the page (of the given ValidationGroup) and call the JS function ValidatorUpdateDisplay with a parameter of the DOM element of the span tag of the validator control.
ValidatorUpdateDisplay toggles the visibility of the span tag depending on the result of the validation.
In my web application I've overridden the ValidatorUpdateDisplay JS function to provide more functionality on the validation scenario (i.e. red borders around the controls, showing popover on the first failed control and scrolling to it).
Now this works very well until my controls (incl. submit button) are shown the first time after a postback in an UpdatePanel.
<asp:ScriptManager runat="server" />
<asp:UpdatePanel ID="upTest" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Button ID="bShow" runat="server" UseSubmitBehavior="false" Text="SHOW" OnClick="bShow_Click" />
<asp:Panel ID="pContent" runat="server" Visible="false">
<asp:TextBox ID="tbTest" runat="server" />
<asp:RequiredFieldValidator ID="rfvTest" runat="server" ControlToValidate="tbTest" Text="Not valid" />
<asp:Button ID="bTest" runat="server" UseSubmitBehavior="false" Text="TEST" />
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
<script type="text/javascript">
function ValidatorUpdateDisplay(val) {
debugger; // this will not be reached
}
</script>
protected void bShow_Click(object sender, EventArgs e)
{
this.pContent.Visible = true;
}
After initial load press bShow to display pContent.
Now, if you leave tbTest.Text empty and press on bTest it should enter the overridden ValidatorUpdateDisplay function, however it enters the function of the framework and displays "Not valid" from rfvTest.
If you change pContent.Visible to true and press bTest after initial load the desired effect will happen: It will enter the custom ValidatorUpdateDisplay function and not display "Not valid".
If you move the button bTest out of the UpdatePanel the problem persists.
How can I make it work inside an UpdatePanel?
ASP.NET uses a lazy loading approach to insert the ValidatorUpdateDisplay function when it needs it the first time, hence in my example it will load the function after the postback of the UpdatePanel.
This will override my own implementation of the ValidatorUpdateDisplay function, because it's inserting the function at the end of the page.
There is a dirty workaround, I just inserted an empty CustomValidator on initial load that is always valid:
<asp:CustomValidator runat="server" />
I wish there was a cleaner solution.
I want to set the textbox contol located in the panel control via code
I know to retrieve the inputted value in the textbox control:
string myVal = Request.Form["txtResult"];
I want to set the txtResult.text = "some text";
makeup snippet:
<asp:Panel ID="Panel1" runat="server" Style="display: none" Width="233px">
<asp:TextBox ID="txtResult" runat="server" AutoPostBack="True"></asp:TextBox>
<br />
<div align="center">
<asp:Button ID="OkButton" runat="server" Text="OK" />
<asp:Button ID="CancelButton" runat="server" Text="Cancel" />
</div>
</asp:Panel>
txtResult is not available within code, I tried to see if it is available in the page_load, it's not
texReults was a typo, its txtResult, I updated the ID
the intellisense does not recognize any cntr by the name txtResult
its a new web application and the panel visibility=True
maybee this wil help, above the snipet, I use ScriptManager from the AJAX Exstension
I am aware of he Asnchronius affects, partial potback, etc.
It's a managed control, you should be able to set it on the Page_Load event:
protected void Page_Load(object sender, System.EventArgs e)
{
txtResult.Text = "some text";
}
Update: Based on your update, there are a couple of things that you would need to check:
Spelling: Are you sure you're spelling the control name correctly?
Its ID in your code is "txtResults", but you're referencing it as
"txtResult".
Designer: Did you copy the aspx page or bypass VS in some way for this page? If so check the .designer file for the reference to the control: i.e. "Page1.aspx.designer.cs"
Visibility: Is the Panel control's visibility set to true? If not, then it won't render the controls that are contained within it.
Update 2: If you're doing this through scriptmanager, then I highly recommend that you read through this: http://www.wrox.com/WileyCDA/Section/Using-the-ASP-NET-AJAX-ScriptManager.id-305492.html
I have a repeater with a RadioButtonList inside the ItemTemplate, but when the RadioButtonList.OnSelectedIndexChanged event fires it generates a full postback. What have I done wrong in my code below? How can I get the OnSelectedIndexChanged to generate an Async Postback?
<asp:UpdatePanel runat="server" ID="UpdatePanel2">
<ContentTemplate>
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="sqlOptions">
<ItemTemplate>
<asp:UpdatePanel runat="server" ID="pnlA">
<ContentTemplate>
<strong>
<%# Eval("Name") %></strong><br />
<asp:RadioButtonList ID="RadioButtonList1"
DataSourceID="sqlOptionValues" runat="server"
DataTextField="id" DataValueField="Id" AutoPostBack="true"
OnSelectedIndexChanged="LoadPrice"
ValidationGroup="options" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator1"
ForeColor="Red" runat="server"
ControlToValidate="RadioButtonList1"
ErrorMessage="Required Field"
ValidationGroup="options" />
<asp:SqlDataSource ID="sqlOptionValues" runat="server"
ConnectionString="<%$ ConnectionStrings:
ConnectionString6 %>"
SelectCommand='<%# "SELECT DISTINCT OptionValue.Name,
OptionValue.Id FROM CombinationDetail
INNER JOIN OptionValue
ON CombinationDetail.OptionValueId = OptionValue.Id
WHERE (OptionValue.OptionId =" +
Eval("Id") + ")" %>'>
</asp:SqlDataSource>
<br />
</ContentTemplate>
</asp:UpdatePanel>
</ItemTemplate>
</asp:Repeater>
</ContentTemplate>
</asp:UpdatePanel>
Many thanks for any help :)
This is a real-world use case. I have a page with Repeaters, Ajax Accordions inside of other Accordions, Update Panels inside other Update panels, you name it. The page works great, except when I want to update one of the Accordion panels with my RadioButtonList (RBL). Even with the RBL inside an update panel, it causes a postback of the entire page. I tried everything. I finally realized it wasn't me when I noticed my buttons would work just fine. I figure it must be a bug in either the framework or the Ajax Control Toolkit. I did find people reference this link all over the web (http://blog.smarx.com/posts/the-case-of-the-radiobuttonlist-half-trigger.aspx), but this link from 2007 is dead now and probably no longer applicable, so that's no help.
What I ended up doing was going with what works - that submit button. All I did was add an onclick attribute to the RBL to call a hidden button. Now you don't want to set the button to Visible=false because then the button won't appear in the generated markup. Instead, set the button's style to display:none; so that no one will see this hack, because yes, that's what this workaround is - it's a hack, but simple and just as effective as what you'd expect. Don't forget to remove the Autopostback="True" from your RBL.
CAVEAT: Because I'm using a hacked button for the onclick event, it's possible for the user to click in the area of the RBL, but not actually select an item. When this happens, our onclick triggers an AsyncPostBack and the codebehind logic will be processed, so please keep that in mind. To give you an idea of what I mean: all the Page_Load() events will be called, but rbl_Questions_SelectedIndexChanged() won't be if they happen to click in the area of the RBL without actually selecting an item. For my purposes this causes no issues in my logic and has no effect on the user.
Here's the Code:
Somewhere In the .Aspx Page:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:RadioButtonList ID="rbl_Questions" runat="server"
OnSelectedIndexChanged="rbl_Questions_SelectedIndexChanged">
</asp:RadioButtonList>
<asp:Button ID="btn_rbl_Questions" runat="server" style="display:none;"/>
<asp:Label ID="lbl_Result" runat="server" Text="" Visible="false">
</asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
In the Page_Load() event:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
//Instead of using the AutoPostback of the RBL, use this instead.
rbl_Questions.Attributes.Add("onclick",
"document.getElementById('"
+ btn_rbl_Questions.ClientID
+ "').click();");
//Bind your RBL to a DataSource, add items programmatically,
// or add them in the aspx markup.
}
}
In the rbl_Questions_SelectedIndexChanged() event:
protected void rbl_Questions_SelectedIndexChanged(object sender, EventArgs e)
{
//Your code here.
//My code unhid the lbl_Result control and set its text value.
}
Update 05/24/2011
The above "hack" is no longer necessary (I am leaving it above since this was marked as the answer by the author). I have found the best way to do this, thanks to this SO Answer:
Updatepanel gives full postback instead of asyncpostback
The code is much simpler now, just remove what I put in the Page_Load() method and remove the Button I used in the Aspx page and add ClientIDMode="AutoID" and AutoPostBack="True" to the control you want the UpdatePanel to capture.
Somewhere In the .Aspx Page:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:RadioButtonList ID="rbl_Questions" runat="server"
ClientIDMode="AutoID" AutoPostBack="true"
OnSelectedIndexChanged="rbl_Questions_SelectedIndexChanged">
</asp:RadioButtonList>
<asp:Label ID="lbl_Result" runat="server" Text="" Visible="false">
</asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
MS changed how ClientID's are generated in .net 4.0 from "AutoID" to "Predictable" and I guess the ScriptManager or UpdatePanel's weren't updated correctly to use it. I can't find documentation on why that is anywhere or if it was left that way by design.
I seriously don't miss winforms.
Try this:
<asp:UpdatePanel runat="server" UpdateMode="Conditional" ID="pnlA">
You'll also need to setup
<Triggers>
//radio buttons
</Triggers>
Not sure how you'll do that since it's a dynamically built list.
Here is my setup:
I have an asp.net button on a page --
<asp:Button id="btnSelectEmp" runat="server" Text="Select Employee" />
I have a .js file with the following jQuery click event --
$("input[id$='_btnSelectEmp']").click(function ($e) {
$("div[id$='_divEmpSearch']").css("display", "inline");
$e.preventDefault();
});
As you can see, clicking upon the button will set a div visible. Nothing special; not rocket science.
The div is wrapped with an asp.net update panel, and it contains an asp.net user control (.ascx)
<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<div id="divEmpSearch" runat="server" style="display: none;">
<uc:EmpSearch ID="ucEmpSearch" runat="server" />
</div>
// And a bunch of other controls that are updated according to whatever the user selects in the user control above
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ucEmpSearch" />
</Triggers>
</asp:UpdatePanel>
The user control above is also wrapped in an asp.net update panel, because it has to communicate with the server. Among other controls like textboxes and such, the user control has two buttons upon it: 1) an asp.net button that does a postback and 2) an asp.net button that does an asynchronous postback.
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Button ID="btnSearch" runat="server" Text="Search" OnClick="btnSearch_Click" /
<br />
asp:Button ID="btnContinue" runat="server" Text="Select" OnClick="btnContinue_Click" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnSearch" EventName="Click" />
<asp:PostBackTrigger ControlID="btnContinue" />
</Triggers>
</asp:UpdatePanel>
The button in the user control that does a postback is working great. I click it, a postback occurs and my div control is re-hidden. I can then click on the Select Employee button (the one that I supplied the code for at the very first of the question) and the jQuery click event is handled and the div will be reshown.
However, the button in the user control that does an asynchronous postback works also, but after it hides the div, if I then click on the Select Employee button the jQuery click event will not be handled.
What this tells me is that for some reason during an asynchronous postback to the page, something happens to the Select Employee button so that the jQuery click event no longer happens. Why?
Your button is replaced with a new one when your update panel comes back with new content, so this:
$("input[id$='_btnSelectEmp']").click(function ($e) {
Binds to the elements it finds at that time, instead you'll want .delegate() or .live() here to listen for click events from current and future elements, like this:
$("input[id$='_btnSelectEmp']").live("click", function ($e) {
$("div[id$='_divEmpSearch']").css("display", "inline");
$e.preventDefault();
});
Or a bit cheaper using .delegate():
$("#container").delegate("input[id$='_btnSelectEmp']", "click", function ($e) {
$("div[id$='_divEmpSearch']").css("display", "inline");
$e.preventDefault();
});
In this case #container should be a parent of the update panel, one that doesn't get replaced in the postback.
Use the live() function. live() delegates the click event to a parent element, so the element (in this case btnSelectEmp) doesn't need to exist at the time the event is bound.
$("#<%=btnSelectEmp.ClientID%>").live("click" function ($e) {
$("#<%=divEmpSearch.ClientID%>").css("display", "inline");
$e.preventDefault();
});
What is happening is the btnSelectEmp button is getting replaced by the asynchronous call and the new element has not been bound to an event handler.
Also, I've modified the jquery selector here to use the exact client id of the element. This will improve speed, plus I seem to recall certain selectors don't work with event delegation in certain versions of Jquery.
try live('click', function(){...}) instead of click(function(){...})
Wild guess : "_btnSelectEmp" is used more than once?
Wondering if someone here can help.
I have an AJAX tabcontainer which has a number of tabs and each tab contains a user control. When I add a new item from one of the tabs, it is not reflected in the user control in another tab unless a postback occurs. (e.g. the first tab has a listview where I add a new record and the second has a simple form which contains a drop-down which I expect to contain value added from first tab).
How can I make the tabcontainer to refresh its tabs from a usercontrol?
Any help will be most appreciated.
Thanks,
Ali
You could fire an event from your first user control so that the page can handle this event and tell the other usercontrol to databind
Here is a example
<act:TabContainer ID="TabContainer2" runat="server" CssClass="EmployeeProfile" ActiveTabIndex="0">
<act:TabPanel ID="TabPanel1" runat="server" HeaderText="Datos Generales">
<ContentTemplate>
<br />
<uc1:EmployeeGeneralDetails ID="EmployeeGeneralDetails2" runat="server" OnUpdated="EmployeeGeneralDetails2_OnUpdated" />
</ContentTemplate>
</act:TabPanel>
<act:TabPanel ID="TabPanel2" runat="server" HeaderText="Referenias Personales">
<ContentTemplate>
<uc3:EmployeeResumeView ID="EmployeeResumeView2" runat="server" />
</ContentTemplate>
</act:TabPanel>
</act:TabPanel>
protected void EmployeeGeneralDetails2_OnUpdated(object o, EventArgs e)
{
EmployeeResumeView2.DataBind();
}