How to maintiain AngularJS functions after asp UpdatePanel partial postback? - c#

In my Web Forms project, I've got a an <asp:UpdatePanel> and within the panel's <ContentTemplate> I'm using a couple of radio button groups derived from the UI Bootstrap example.
When the page performs a partial post-back in the UpdatePanel, I lose the Angular functionality and my Angular directives no longer control the radio button groups and their current selected buttons.
Granted, I've seen examples of how to call Javascript functions after a partial postbacks such as endRequestHandler and pageLoad but I'm not particularly sure how to craft this in such a way to work with Angular. The angular module is declared at the top of the page like
<html lang="en" ng-app="NewHireFormsManagement">
Here is a short and sweet version of the code I have now...
ASP.NET
<!-- Pull hidden data to set current radio button positions -->
<asp:Label ID="FormStatusCurrentStatusLabel" runat="server" Visible="false" />
<script type="text/javascript">
// Bind client-side events before/after async page-load
function pageLoad(sender, args) {
// Set and Update Form Status
var ITUpdateStatusRadios = function ($scope) {
$scope.radioModel = '<%= this.FormStatusCurrentStatusLabel.Text %>';
};
}
</script>
<asp:UpdatePanel ID="ITadminStatusUpdatePanel" runat="server">
<ContentTemplate>
<div ng-controller="ITUpdateStatusRadios">
<div class="btn-group">
<label class="btn btn-default" ng-model="radioModel" btn-radio="'Attention_Needed'">
<i class='fa fa-times-circle'></i> Attention Needed
</label>
<label class="btn btn-default" ng-model="radioModel" btn-radio="'Pending'">
<i class='fa fa-paper-plane-o'></i> Pending
</label>
<label class="btn btn-default" ng-model="radioModel" btn-radio="'Complete'">
<i class='fa fa-check'></i> Complete
</label>
</div>
<!-- Pull Results from this label on form submit -->
<input type="hidden" runat="server" id="FormStatusNewStatusInput" value="{{radioModel || 'null'}}">
</div>
<asp:Button ID="ITStatusUpdateSubmitButton" runat="server" OnClick="AdminStatusUpdateSubmitButton_Click" CssClass="btn btn-success" Text="Update" />
</ContentTemplate>
</asp:UpdatePanel>
C# Code-Behind
// Page Load
protected void Page_Load(object sender, EventArgs e)
{
...SQL stored procedure query
this.FormStatusCurrentStatusLabel.Text = sqlITFormStatusDataReader["CompletionStatus"].ToString(); // Current Form Completion status
}
// Update Button
protected void AdminStatusUpdateSubmitButton_Click(object sender, EventArgs e)
{
try
{
.. prepair sql connection
updateformsqlCmd.Parameters.AddWithValue("#udAdminCompletionStatus", FormStatusNewStatusInput.Value);
.. call stored procedure and update value
}
catch()
{
}
finally
{
}
}
Basically, the initial radio position is set dynamically based on data read from a database on on Page_Load. When 'Update' button is pressed, another event is called to update the same database table and then the current radio position would ideally be re-set in real time, again on Page_Load. It's just that the JS function is being lost for Angular.
Any ideas?

Related

Why is there no PostBack for a form on a UserControl?

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.

Input submit onclick and onserverclick not working

I'm working on a simple login screen with the below code:
<form id="login">
<div class="formHeader">
<h1>Login</h1>
</div>
<div class="formDiv">
<input type="text" placeholder="Email" name="txtEmail"/>
<div class="inputImage fa fa-user"></div>
</div>
<div class="formDiv">
<input type="password" placeholder="Password" name="txtPassword"/>
<div class="inputImage fa fa-lock"></div>
</div>
<div class="formDiv">
<label id="remember">
<input type="checkbox" name="cbxRemberMe" value="Checked"/>
<div class="checkbox"></div><span>Remember me</span>
</label>
</div>
<div class="formDiv">
<input type="submit" value="LOGIN" onclick="btnLogin_Click" />
</div>
<div class="formFooter"><a class="forgot" href="#">Forgot Password</a></div>
and back-end code
protected void btnLogin_Click(object sender, EventArgs e)
{
}
But the button does not call the backend code at all.
Nothing happens except the URL changes from
"http://localhost:15726/Pages/Login.aspx" to
"http://localhost:15726/Pages/Login.aspx?txtEmail=&txtPassword=&ctl00=LOGIN"
I cannot put a Runat=Server attribute in the form as I have 2 forms on this page (login and register)
any help is appreciated.
What I have tried:
Playing around with Runat=Server, onclick() and OnServerClick() (swapping around and changing them up)
Making input type=submit / input type=button
none of these work.
Have you tried these two approaches?
<asp:Button runat="server" id="btnLogin" Text="LOGIN" OnClick="btnLogin_Click">
or
< button onserverclick="btnLogin_Click" runat="server" id="btnLogin">LOGIN</button>
Edit
This was supposed to be a comment and not answer. Sorry for that.
However, the entire form doesn't seem to be "webform" form compatible. If you want to be able to read the values from the form elements the form should have a runat="server" tag, too.
Firstly, you need to specify whether it is a server control or client control. Specify runat=server to tell that it should be available for the Code-Behind file.
Finally, Use any javascript function with OnClick and any code behind function with OnServerClick
Something like this,
aspx
Plain HTML
<input type="submit" runat="server" value="LOGIN" onclick="return js_btnLogin_Click()" OnServerClick="btnLogin_Click"/>
or with ASPX Control
<asp:Button runat="server" Text="LOGIN" OnClientClick="return js_btnLogin_Click()" OnClick="btnLogin_Click">
javascript
<script type="text/javascript">
function js_btnLogin_Click()
{
//return false, in case if you want to stop posting the form to the server
return true;
}
</script>
Code-Behind
protected void btnLogin_Click(object sender, EventArgs e)
{
}

webforms post in a Sitecore application

Before reading my question I would recommend you to first read this article: http://blog.karbyn.com/articles/creating-a-custom-sitecore-administration-page-with-authentication/
. As in the article, I am working on implementing an admin backend for my sitecore built web application. So far; I have an action method called Page_Load which is responsible for rendering a form to the View - which enables Sitecore content users to query the Database, filtering the entries by DateTime. FormPost is empty and I will explain why shortly.
public partial class AdminUtility : AdminPage
{
protected void Page_Load(object sender, EventArgs e)
{
CheckSecurity(true); //Required!
base.OnInit(e);
}
protected void FormPost(object sender, EventArgs e)
{
}
}
Page_Load renders this form. Because of Sitecore routing I was having difficulty posting the data to a different aspx page. Hence, Is it possible to post the form directly back to the same controller class but this time the method "FormPost" can handle the request.
<form action="FormPost" id="form1" runat="server">
<p> Date From: <input type="text" name="DateFrom" id="DateFrom"> </p>
<p> Date To: <input type="text"name="DateTo" id="DateTo"> </p>
<input type="submit" />
</form>
Instead of using the Form attribute, try to place the onclick directly on the button as shown below using ASP.NET user control:
<div id="form1">
<p> Date From: <asp:TextBox runat="server" ID="DateFrom" /> </p>
<p> Date To: <asp:TextBox runat="server" ID="DateTo" /> </p>
<asp:Button runat="server" ID="SubmitButton" Text="Process" OnClick="FormPost"/>
</div>

Custom postback inside aspx and redirect

I need to perform a postback in order to process a gateway payment by redirect, so i've got an example in order to do inside an html with server side code (runat=server in the inputs):
<form action="https://xxxxxxxx" method="post">
<input runat="server" type="text" id="param1" name="param1" value="asd" />
<input runat="server" size="100" type="text" id="parm2" name="parm2" value="asd" />
<input runat="server" type="text" size="50" id="param3" name="param3" value="asd" />
<input runat="server" type="submit" value="Post!" />
</form>
protected void Page_Load(object sender, EventArgs e)
{
// New instance of library and his magic
LibraryXXX r = new LibraryXXX();
r.Parameter.Add("xxxx", xxxx);
// more logic goes here
}
Clinking the submit button sends the postback and the page loads an html. I want traslate that sample to an aspx webform. The problem is i can't have more than one form label inside an aspx. So, how can i do the same postback inside an aspx?

Create a customized alert box in c# asp.net

I want to create a alert box with asp controls, is it possible?
For example, a simple script alert would be like,
Response.Write("<script>alert('Alert Box');</script>");
On the alert box there are default buttons "Ok" and "Cancel" with the text "Alert Box"
Now all i want to do is call a function written in the respective Demo.aspx.cs page on the click of Ok button of alert.
Or
Is it possible to place a asp:Button control in that alert box to call that function?
Thanks if any of you could help! :)
You can't use asp:Button in JavaScript alert, The best way to make an alert or modal dialog box in asp.net is to create your own and make it hidden or in-active in master page and call it when you need it.
You can get a ready made modal or alert in GetBootstrap
Update:
Here some Idea how to use bootstrap modal.
This is how I use GetBootstrap Modal for asp.net webforms, you can use it if you want.
The following code is use to create a customize alert or modal box with proper asp.net button controls that you can use in back-end. "you can place this in master page to prevent repetitive"
<asp:Panel ID="pnlAlertBox" runat="server" style="position:absolute;top:0;> //You can make is visible or hidden -- you need to customize the style of panel
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="myModalLabel">This is customize alertbox</h4>
</div>
<div class="modal-body">
This is the messages...
</div>
<div class="modal-footer">
<asp:Button ID="btnCancel" runat="server" CssClass="btn btn-default" Text="Cancel" />
<asp:Button ID="btnOk" runat="server" CssClass="btn btn-primary" Text="Ok" />
</div>
</div>
</div>
</asp:Panel>
But of course you need to include the getboostrap .js and .css files in master page to show the design.
Place this in header:
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet">
Place this after form:
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
This is a fixed version of Abrar Jahin's answer. Calling e.preventDefault() prevents the default action being taken, which is to submit the form.
The following displays the alert on click, and then submits the form: -
$("#alert_button").click( function(e)
{
alert('This is a custom alert box', 'Alert Dialog');
});
EDIT:
If you want to call a specific function in your webpage, you have a few options: -
A PageMethod or HttpHandler
in your client-side code, call the ASP.NET-generated __doPostback function, and pass parameters indicating what to do to your server-side code
without redirect page alert code
ScriptManager.RegisterStartupScript(this, this.GetType(), "showalert", "alert('Demo');", true);
with redirect page
ScriptManager.RegisterStartupScript(this, this.GetType(), "err_msg", "alert('Demo');window.location='Demo.aspx';", true);
You can use javascript inside OnClientClick event handler for the button
<asp:Button ID="Button1" runat="server" Text="Delete User"
OnClientClick="return confirm('Are you sure you want to delete this user?');" />

Categories