I have a user control that has a GridView and when a user clicks on a row in this GridView the function OnSelectedIndexChanged is called, I'd like a modal to pop up after this occurs. I used the ScriptManager to invoke the script $('#seasonInfoModal').modal() which works in opening modals. The problem is it doesn't work when opening a modal which is defined within the same user control. The modal opens when it is inside the page.aspx , but doesn't open when inside the control .ascx. I have everything hooked up properly and have omitted some details. Here's what the overall code looks like
main page.aspx
<%# Page Title="" Language="C#" ... %>
<%# Register Src="~/Controls/MyControl.ascx" TagPrefix="ACT" TagName="GeneralADM" %>
<ACT:GeneralADM runat="server"" />
MyControl.ascx
<%# Language="C#" AutoWireUP="true" Codebehind="" Inherits="" %>
<div runat="server">
<!-- Seasonal Info-->
<div runat="server" id="seasonInfoModal" class="modal fade" role="dialog" draggable="true">
</div>
<!-- End seasonal info-->
<!-- Start of Season Edit Modal -->
<div id="seasonEditInfo" class="modal fade" role="dialog" draggable="false">
</div>
<!-- End of Season Edit Modal -->
<asp:GridView>
</asp:GridView>
</div>
In the code behind I try to open the modal like this
MyControl.ascx.cs
protected void OnSelectedIndexChanged(object sender, GridViewEventArgs e){
ScriptManager.RegisterStartupScript(this,
this.GetType(),
"seasonInfoModal",
"$('#seasonInfoModal').modal();",
true);
}
issue
#seasonInfoModal doesn't popup instead a new modal is made with nothing inside it and the screen fades to dark on click. When I pull the #seasonInfoModal out of the control into the page where I am inserting the control itself, the modal actually pops up.
question
How can I open the modal #seasonInfoModal when it is inside the control from that control's codebehind specifically from inside OnSelectedIndexChanged function?
The problem may be caused by the ID mangling performed by ASP.NET. Since the modal div is a server control (as specified by runat="server"), its ID in the rendered HTML is not seasonInfoModal but something like MyControl1_seasonInfoModal. As a result, the Javascript selector $('#seasonInfoModal') cannot find it.
You can change the startup script code, and pass the value of seasonInfoModal.ClientID to the jQuery selector, to account for the ID mangling:
protected void OnSelectedIndexChanged(object sender, GridViewEventArgs e){
ScriptManager.RegisterStartupScript(this,
this.GetType(),
"seasonInfoModal",
string.Format("$('#{0}').modal();", seasonInfoModal.ClientID),
true);
}
Other alternatives to avoid ID mangling would be:
To remove the runat="server" attribute if you don't need to access the div control in code-behind
To add clientidmode="static" to the div.
To use a class name (with the corresponding jQuery class selector) instead of an ID for the modal div.
These 3 solutions, however, would not behave correctly if several instances of the user control are present in the form. The modal of the first instance would always be used, and in cases 1 and 2, several controls of the form would have the same ID.
Related
I hope this is a simple one for someone to answer.
If i have a button that allows a user to edit something on the page, they can click on
Edit this page
This then opens a modal on the page with the following DIV
<div id="editpage" class="modal" tabindex="-1" role="dialog">
This is the content in my modal
</div>
The issue I am having is that when I add a runat="server" to the modal's div tag, so that I can determine if the user can even see/inspect the page source if they are not a moderator,, that the modal no longer pops up when i click on my edit button.
Is there anything I can do so that I can still control if the modal is rendered from code-behind based on logic there, and still have the edit to modal click function still work without turning it into a server control.
Found the answer which was to wrap the modal div in another div or placeholder tag and then control that from the server side controls. This meant that the modal's div did not have it's ID modified due to the server side assignment and therefore I am now able to remove this markup entirely if the user is not a moderator.
<asp:Panel ID="editpage_panel" runat="server" Visible="false">
-- modal here
</asp:Panel>
I have a problem understanding where I am losing the ability to catch the PostBack trigger or simply the handler method of serverclick in this setup and placing breakpoints only shows the PostBack occurs on rendering (Page_Load) but not after submit button is clicked. Allow me to elaborate on the scenario and keep in mind I have limited ability to change the way it is done and must figure out a way to make it work with minor changes using ASP.net / C# / WebForms / Bootstrap 4.5 per the client.
Dashboard.aspx [main page] has a simple (top nav showing the logo and logged in user's name with a signout drop down, sidebar menu which upon individual click will load into a display area) and the display area is an asp:PlaceHolder element:
<asp:PlaceHolder runat="server" ClientIDMode="Static" ID="TheScreen">
When the [main page] is loaded, it makes an API call and processes a collection of objects received and generates adding a series of UserControl Control1 objects (this can be zero items or n items) let's call this [default state] of the landing so we can refer to it later.
Each of the Control1 (which have unique IDs) have 3 buttons to perform 3 different actions.
<a class="btn btn-primary btn-sm" id="action1" runat="server" onserverclick="Command_Click">Do First Action</a>
<a class="btn btn-primary btn-sm" id="action2" runat="server" onserverclick="Command_Click">Do Second Action</a>
<a class="btn btn-primary btn-sm" id="action3" runat="server" onserverclick="Command_Click">Do Third Action</a>
Command_Click simply bubbles up an event handler to be processed by Dashboard.aspx
public void Command_Click(object sender, EventArgs e)
{
CommandClicked?.Invoke(sender, e);
}
action1 is handled on the fly with a confirmation modal which contains a simple button that runs onserverclick and reloads the [default state] having deleted that item using an API call.
<button type="button" class="btn" id="do-action1" runat="server" onserverclick="finish-action1">Do It</button>
This all works as expected.
action2 is handled by [main page] where it clears the PlaceHolder's controls and then dynamically creates and loads another UserControl which displays long form details of that object.
UControl2 theObject = (UControl2)Page.LoadControl("~/path/to/Control2.ascx");
TheScreen.Controls.Clear();
TheScreen.Controls.Add(theObject);
This all works as expected also.
action3 button is the one that is giving me the problem and just like action2 it is handled on [main page] where it clears the PlaceHolder's controls and then dynamically creates and loads another UserControl which provide a simple form with one button on it.
UControl3 otherObject = (UControl3)Page.LoadControl("~/path/to/Control3.ascx");
TheScreen.Controls.Clear();
TheScreen.Controls.Add(otherObject);
The form is very simple, contains a <select> elements whose <option> are populated using an asp:Repeater based on an API call that provides the DataSource for it. It also has a simple <input> textbox field and lastly a submit <button>.
<select id="..." name="..." required="required">
<option disabled selected value="">select payment account</option>
<asp:Repeater ID="..." ClientIDMode="Static" runat="server" ItemType="model.namespace">
<ItemTemplate>
<option value="<%#: Eval("...") %>">
<%#: Eval("...") + " " + Eval("...") %>
</option>
</ItemTemplate>
</asp:Repeater>
</select>
<input id="..." name="..." type="text" required="required" runat="server" />
<button id="finish-action3" class="btn" runat="server" onserverclick="do-action3">Do It</button>
What I don't get is why finish-action3 is not performing the actions of the handler method do-action3, it simply refreshes back to the [main page] with the initial state that we started from with the initial Control1s being rendered and nothing else, no PostBack either.
I have searched extensively and found nothing addressing this specific scenario and what I have found, everyone keeps suggesting using asp:Button but that makes no difference for me in the behavior.
As written above, clicking finish-action3 button which is part of Control3 will not cause the basic HTML5 validation and does not trigger the do-action3 handler method and simply refreshes back to the [main page] where we started.
If I add do-action3 to the onsubmit attribute OR add type=submit, I get the validation but once it passes validation, the same behavior, nothing but load the [main page].
Changing the element to an asp:Button made absolutely no difference. The validation is triggered without anything special (like using onsubmit attribute or having a type=submit but once it is validated the same behavior, never calls do-action3 nor does it even trigger a Page_Load/PostBack on control3 just back to the [main page].
I suspect I am overlooking some event or is not bubbling and is getting lost in the process but I can't think what it is and where and why. Why doesn't the form that is last on the screen loaded by Control3 "submitted" by that button click not generating a PostBack or running the onserverclick handler method and simply refreshing to the main default state page, what am I missing here?
Any help would be appreciated as I have been banging my head against the wall trying to figure out what I am missing. I never encountered this in MVC or Core and it is making me crazy.
Let's simplify. Basically, what you are saying is that the following does not work because the btnFinishAction3_Click method of the dynamically-added Control3 user control is not firing:
Default.aspx (main page):
<asp:PlaceHolder runat="server" ID="plhPlaceHolder1"></asp:PlaceHolder>
<asp:Button runat="server" ID="btnAction3"
Text="Do Third Action"
OnClick="btnAction3_Click"/>
Default.aspx.cs:
protected void btnAction3_Click(object sender, EventArgs e)
{
AddControl3();
}
private void AddControl3()
{
Control3 objControl3 = (Control3)Page.LoadControl("~/Control3.ascx");
plhPlaceHolder1.Controls.Clear();
plhPlaceHolder1.Controls.Add(objControl3);
}
Control3.ascx:
<asp:Label runat="server" ID="lblMessage"></asp:Label>
<asp:Button runat="server" ID="btnFinishAction3"
Text="Finish Action 3"
OnClick="btnFinishAction3_Click"/>
Control3.ascx.cs:
protected void btnFinishAction3_Click(object sender, EventArgs e)
{
lblMessage.Text = "Finished Action 3.";
}
This is normal behavior. After postback the dynamically added user control does not exist and the event is "ignored". In ASP.NET Web Forms, every dynamic control must be re-added to the page after every postback. So, you need something like the following:
Default.aspx (main page):
<asp:PlaceHolder runat="server" ID="plhPlaceHolder1"></asp:PlaceHolder>
<asp:HiddenField runat="server" ID="hifControl3Loaded"/>
<asp:Button runat="server" ID="btnAction3"
Text="Do Third Action"
OnClick="btnAction3_Click"/>
Default.aspx.cs:
protected void Page_Load(object sender, EventArgs e)
{
if (hifControl3Loaded.Value == "1")
{
AddControl3();
}
}
protected void btnAction3_Click(object sender, EventArgs e)
{
AddControl3();
hifControl3Loaded.Value = "1";
}
private void AddControl3()
{
Control3 objControl3 = (Control3)Page.LoadControl("~/Control3.ascx");
plhPlaceHolder1.Controls.Clear();
plhPlaceHolder1.Controls.Add(objControl3);
}
In other words, you need to add Control3 to the main page at every postback on Page_Load once the user has decided to add it by clicking the btnAction3 button in the first place.
I am facing a problem with jquery modal Dialog box. I want the modal box to show only when my data is successful saved to database. I am using c# and asp.net, and on backend i am using Sql server 2008 R2. Currently my data is successfully entering and i am showing "the data is successfully saved on a label" after clicking on a button , but i want to show a modal box only when i click the button and my data is saved .
I have created this script
$("#Btndiag").click(function () { $("#myModal").modal(); });
and on content page body i have written this
<asp:Button ID="Btndiag" runat="server" Text="show dialog" onclick="Btndiag_Click1" />
<div class="modal hide fade" id="myModal">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h3>Settings</h3>
</div>
<div class="modal-body">
<p>Here settings can be configured...</p>
</div>
<div class="modal-footer">
Close
Save changes
</div>
</div>
To achieve what you want, you have to process the data in the back end, and then have the ASP.NET Framework execute a script for you.
To accomplish this, you use ClientScriptManager.RegisterClientScriptBlock during full page postbacks, or ScriptManager.RegisterClientScriptBlock if the controls are inside of an UpdatePanel.
C# code:
protected void Btndiag_Click1(object sender, EventArgs e)
{
// process database
// verify results
if (success)
{
ClientScriptManager.RegisterClientScriptBlock(this, "Btndiag_Click1", "$('#myModal').modal();", true);
}
}
Remember that if the button and the modal div are inside of an UpdatePanel, replace ClientScriptManager.RegisterClientScriptBlock with ScriptManager.RegisterClientScriptBlock.
Finally, just as a last informational note...your script ($("#Btndiag").click(...)) will not work because ASP.NET changes element Ids when rendered as HTML.
You'd have to work it in the following manner:
$("#<%= Btndiag.ClientID %>").click(function () { $("#myModal").modal(); });
Please note that you do not need to do anything with the button's click event. You want the framework to automatically run your scrip after the postback.
I have an ASP.NET C# website and I am attempting to retrieve the inner html from a HTML in my page when a button is clicked.
My Problem: I use the function FindControl() but it returns null when it should find the element. Why is this happening, what am I doing wrong?
My HTML page:
<%# Page Title="test" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="test.aspx.cs" Inherits="test" %>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="ActualContent">
<div class="regMainContainer mainContainer container">
<!-- Attempting to get the below div -->
<!-- Knowtice it does not have runat="server",
I would prefer not to do that if I dont need to -->
<div id="courseDiv" class="courseContainer">
</div>
</div>
</asp:content>
My Code that executes when a button is clicked(inside test.aspx.cs file:
HtmlGenericControl d = (HtmlGenericControl)FindControl("courseDiv");
FindControl can only find controls that has runat="server" attributes. The good news is that you can easily change you div to a panel, and add data that way.
the bad news is that this still won't let you access the innerhtml of the div, .net sees it as just a container for other controls.
The best way to do this would be some form of ajax, since your client side script would be able to read that contents and pass it to a server side method
You won't be able to use FindControl for something that's not marked with runat="server". This is because any of the elements not marked with runat="server" get parsed as one giant text literal at runtime. You can add runat="server" to any arbitrary html element, though.
I am trying to get a modal popup to work, it needs to be triggered in the Code behind.
<asp:Button ID="btnModalPopUp" runat="server" Text="Button" Style="display: none" />
<asp:Panel ID="pnlModalPopup" runat="server" CssClass="modalPopup" Style="display: none"
Width="233px">
<div id="Div1" runat="server" cssclass="title">
Modal text here.
<asp:TextBox ID="txtEditComments" runat="server"></asp:TextBox>
</div>
</asp:Panel>
<cc1:ModalPopupExtender ID="modalMessage" runat="server" TargetControlID="btnModalPopUp"
PopupControlID="pnlModalPopup" BackgroundCssClass="modalBackground" DropShadow="true"/>
Code behind:
protected void Page_Load(object sender, EventArgs e)
{
modalMessage.Show();
}
Even though it hits the "modalMessage.Show();" code it doesn't show the modal panel.
Two solutions:
The first solution:
Remove Style="display:none" from the pnlModalPopup.
The first solution is will cause the popup to "flash" on the screen when the page first loads, and then quickly disappear.
The second solution:
protected void Page_Load(object sender, EventArgs e)
{
pnlModalPopup.Style["display"] = "block";
modalMessage.Show();
}
Recommendation:
I would recommend using the second solution, that way the modal popup doesn't flicker and then disappear.
Edit: I just tested your code:
I just tested your code in a simple page that contained only the code that you provided...It worked like expected.
Check the following:
Is your modal popup is defined in an UpdatePanel that is conditionally updated?
Check to make sure that the modal popup isn't defined in a Panel that has it's visibility set to false.
If that doesn't work, then check if the modal popup is actually in the source code of the rendered web page.
Listen to Chris's comment as it is needed:
display:none is cosmetically needed,
otherwise the popup will display when
the page is loading, then will quickly
disappear while the ModalPopupExtender
kicks in and hides it.
We had to make ours show like this:
pnlModalPopup.Visible = true;
modalMessage.Show();