I am testing with the following code to display data and then remove it after a certain time, using async.
The problem I am having is that I want to display the label and text, then do the async however the async is running before the first part of my code.
Is there a way that I am able to run the code first and then do the async await?
<form id="form1" ondatabound="Page_Load()" runat="server">
<div>
<asp:Label ID="Label1" runat="server" Text="Label" Visible="false"></asp:Label><br /><br />
<asp:Button ID="Button1" class="btn btn-error" OnClick="Button1_Click" runat="server" Text="Button" /><br /><br />
<asp:TextBox ID="TextBox1" ReadOnly="false" Text="" Visible="true" runat="server"></asp:TextBox><br /><br />
<asp:TextBox ID="TextBox2" ReadOnly="false" Text="" Visible="true" runat="server"></asp:TextBox><br />
</div>
</form>
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//TextBox1.Text = "TestEmail";
//TextBox2.Text = "TestPassword";
}
//When Button1 is clicked then show/hide the title label
protected void Button1_Click (object sender, EventArgs e)
{
if (Label1.Visible == false)
{
Label1.Visible = true;
Label1.Text = "Please use this link to login: www.test.com";
TextBox1.Text = "TestingData";
}
else
Label1.Visible = false;
ClearMessages();
}
public async Task SyncTest()
{
await Task.Delay(5000); // 5 second delay
this.ClearMessages();
}
protected void ClearMessages()
{
TextBox1.Text = "";
TextBox2.Text = "";
Label1.Text = "";
}
}
As i mentioned in the comment. As soon as the page is rendered the backend has no connection to the page anymore thus it cannot empty the text. The better way to solve this would be to clean it on clientside by calling the script on clientside with
Page.ClientScript.RegisterStartupScript(GetType(), "cleanText", "cleanText());", true);
this will call the method below which will empty textbox1 after 5 seconds.
function cleanText(){
setTimeout(function() {
var txt1 = document.getElementById('<%= TextBox1.ClientID %>');
txt1.value = "";}, 5000);
}
regarding your concept and question:
...remove [data] after a certain time, using async [, or awaitable Task].
Is there a way that I am able to [render the page] and then do the async await?
to my knowledge, there is no framework support for async await and Task to cross Page Lifecycles, let alone compose mechanisms on a post rendered/unloaded page, so the answer is likely, no.
There is, however, asynchronous support for WebForm Applications with ASP.NET AJAX Extensions. You can achieve your desired behavior (code behind handling of control property changes in an asynchronous manner) with Partial Page Updates.
Related
I have 2 textbox on my page and a Button. When I click on a button, the text from the textbox is emailed. But, then when i refresh the page and no content is there, then also i get an email.
protected void Button1_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(TextBox1.Text) && !string.IsNullOrEmpty(TextBox2.Text))
{
//email logic
TextBox1.Text = "";
TextBox2.Text = "";
}
else
{
//do nothing
}
}
Here, on clicking the button, i get an email but then when i refresh the page, even though there is no data, then also it goes inside the loop and i get an email.
How do i stop this ?
Do the following in your Page_Load event and keep your TextBoxes and Button in an <asp:UpdatePanel>. Then the page will not ask to re-submit each time you refresh the page.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
TextBox1.Text = string.Empty;
TextBox2.Text = string.Empty;
}
}
UPDATE
Keep the controls within an UpdatePanel as follows
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional" >
<ContentTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Send mail" onclick="Button1_Click" />
</ContentTemplate>
</asp:UpdatePanel>
You need to use the the POST > Redirect > GET pattern. Here is explanation link
I have a webs form page and I have a text box which once clicked passes a variable to the code behind and then back into another element of that page and I cannot get it to work.
This is the closest I have got.
<asp:Panel ID="Search" runat="server" Visible="true">
<tr>
<td>
<asp:Label ID="lblSearch" runat="server" Text="Search"></asp:Label>
</td>
<td>
<asp:TextBox ID="search" runat="server" />
</td>
<td>
<asp:RequiredFieldValidator ID="valSearch" runat="server"
ControlToValidate="movieSearch" Text="Please enter text" />
</td>
<td>
<asp:Button ID="btnSubmit" runat="server" Text="Save"
OnClick="btnSubmit_Click" />
</td>
</tr>
</table>
</asp:Panel>
<asp:Panel ID="pnlSearchResult" runat="server" Visible="false">
<script>
var search = '<%=Server.UrlDecode(Request.QueryString["Data"]) %>';
</script>
</asp:Panel>
And the code behind:
protected void btnSubmit_Click(object sender, EventArgs e)
{
if (IsValid)
{
pnlSearch.Visible = false;
pnlSearchResult.Visible = true;
Response.Redirect("search.aspx?Data=" + Server.UrlEncode(search.Text));
}
}
Also this does not change the visibility of the two panels for some reason.
I would appreciate any guidance I am very new to asp and c#.
The panel's visibility is not changing because you're forcing a new GET request to the page with this: -
Response.Redirect("search.aspx?Data=" + Server.UrlEncode(search.Text));
(I'm assuming your page is called 'search.aspx')
There's no need to do this. Remove this line.
Secondly, I see you want to force the textbox's Text value into a Javascript variable. Replace this
var search = '<%=Server.UrlDecode(Request.QueryString["Data"]) %>';
with this
var search = '<%= search.Text %>';
Write below code on page event.
Another more important point is you first panel Id is "Search" not "pnlSearch" on aspx page so please correct it
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString["Data"] != null)
{
Search.Visible = false;
pnlSearchResult.Visible = true;
}
}
I recommend solution without using Response.Redirect.
Code Behind Submit Button click:
protected void btnSubmit_Click(object sender, EventArgs e)
{
if (IsValid)
{
pnlSearch.Visible = false;
pnlSearchResult.Visible = true;
}
}
In Markup:
<asp:Panel ID="pnlSearchResult" runat="server" Visible="false">
<script>
var searchTxt = document.getElementById('search');
if(searchTxt.value != null && searchTxt.value != ''){
//do your stuff
}
</script>
I am trying to create a simple form that uses radio buttons. I set the radio button to AutoPostBack = True, this way if the radio button is true/false, a subpanel is Shown or Hidden. The radio buttons are required fields. I also have a hidden textbox that the value of the selected radio button is inserted and this textbox is what I validate against (empty or not).
Problem 1:
This works until you go to submit and the validation fails. The validation messages show, then when you click on one of the radio buttons with AutoPostBack = True, all the validation disappear. I can resolve this by adding Page.Validate() to the method that runs when the radio button is clicked. But, I do not want the Page.Validate() to run unless the page was already showing validation errors (so it will not re-validate unless the form was already submitted and failed the validation).
As it stands, before the form is submitted and fails validation: when you click on any radio button question, all the other questions requiring validation show the validation error. I am only looking to overcome the AutoPostBack which is clearing all the validation messages that are shown when you had click submit.
Problem 2:
I would like to be able to change the color of the question if it does not pass validation. I added the javascript to override the default .net settings. I got this to work, but only when you click the submit button and not after a RadioButton AutoPostBack.
Currently, When you click submit all the required questions turn red and also display the required validation message. But if you click a radio button to start fixing the validation errors, on the AutoPostBack, the all the questions that were now red in color changes back to the orignal black and the required validation message is still shown. How can I call the Javascript to run again along with the Page.Validation() in the code behind method?
Any help would be greatly appricated! Thanks
Below is an example of the code so far.
ASPX Code:
<asp:Table ID="Table1" runat="server" CellSpacing="0" CellPadding="0">
<asp:TableRow>
<asp:TableCell CssClass="question">
<label>4. Have you had an abnormal result from a prenatal test (e.g. amniocentesis, blood test, ultrasound)?</label>
</asp:TableCell>
<asp:TableCell CssClass="answer">
<ul class="selectGroup">
<li>
<asp:RadioButton ID="Q4_true" runat="server" Checked='<%# Bind("Q4_yes") %>' Text="Yes"
GroupName="4" OnCheckedChanged='RB_QuestionSubPane_YN' AutoPostBack="true" /></li>
<li>
<asp:RadioButton ID="Q4_false" runat="server" Checked='<%# Bind("Q4_no") %>' Text="No"
GroupName="4" OnCheckedChanged='RB_QuestionSubPane_YN' AutoPostBack="true" />
</li>
<asp:TextBox ID="Q4_validationBox" runat="server" CssClass="hiddenField" Enabled="false"
Text=''></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" EnableViewState="true" ControlToValidate="Q4_validationBox"
Display="Dynamic" runat="server" ErrorMessage="RequiredFieldValidator"></asp:RequiredFieldValidator>
</ul>
</asp:TableCell>
</asp:TableRow>
</asp:Table>
Code Behind
protected void RB_QuestionSubPane_YN(object sender, EventArgs e)
{
RadioButton radio_Selected = (RadioButton)sender;
string radio_QuestionID = Convert.ToString(radio_Selected.ID);
(((TextBox)FormView1.FindControl(strQuestionID + "_validationBox")).Text) = radio_Selected.ID.ToString();
Page.Validate();
}
JavaScript
ValidatorUpdateDisplay = function (val) {
var ctl = $('#' + val.controltovalidate);
var eCount = 0;
for (var i = 0; i < Page_Validators.length; i++) {
var v = Page_Validators[i];
if (v.controltovalidate == val.controltovalidate) {
if (!v.isvalid) {
eCount++;
ctl.addClass('validationError');
$('td.question:eq(' + i + ')').addClass('red');
}
};
}
if (eCount > 0) {
ctl.addClass('validationError');
} else {
ctl.removeClass('validationError');
$('td.question:eq(' + i + ')').removeClass('red');
}
if (typeof (val.display) == "string") {
if (val.display == "None") {
return;
}
if (val.display == "Dynamic") {
val.style.display = val.isvalid ? "none" : "inline";
return;
}
}
if ((navigator.userAgent.indexOf("Mac") > -1) &&
(navigator.userAgent.indexOf("MSIE") > -1)) {
val.style.display = "inline";
}
val.style.visibility = val.isvalid ? "hidden" : "visible";
}
It sounds like what you really need is custom validation. That way you can fully customize your validation to meet your needs.
Here is a simple example:
<script language="javascript" type="text/javascript" >
function CustomValidator1_ClientValidate(source,args)
{
//put your javascript logic here
}
//-->
</script>
<body>
<form id="form1" runat="server">
<div>
<asp:RadioButton ID="RadioButton1" runat="server" GroupName="direction" Text="left" />
<asp:RadioButton ID="RadioButton2" runat="server" GroupName="direction" Text="right" />
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
<asp:CustomValidator id="CustomValidator1" runat="server" Display="Dynamic" ErrorMessage="please choose" ClientValidationFunction="CustomValidator1_ClientValidate" OnServerValidate="CustomValidator1_ServerValidate"></asp:CustomValidator>
</div>
</form>
</body>
Server Side
protected void CustomValidator1_ServerValidate(object source, ServerValidateEventArgs args)
{
args.IsValid = RadioButton1.Checked || RadioButton2.Checked;
}
protected void Button1_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
//validate is successful.
}
}
I have a textbox that the user suppose to place numbers on it,
and after he push the button, the number should pass to an array.
and each number and button pushed, should be saved in this array in order (for example : 3 , 4, 5, ....)
The problem is, that each time I push the button, then page_load occurs. I have this code :
protected string[] CurrentArr;
protected void Page_Load(object sender, EventArgs e)
{
if (CurrentArr != null)
{
CurrentArr = (string[])Session["CurrentArr"];
}
else
CurrentArr = new string[length];
which CurrentArr is the array that change over time.
I tried to solved it with AJAX as well :
<asp:ScriptManager runat="server" ID="sm">
</asp:ScriptManager>
<asp:UpdatePanel runat="server" ID="update">
<ContentTemplate>
<input type="text" class="response" id="how_many" name="guess" placeholder="Enter your guess..." />
<asp:Button runat="server" class="button red" id="generate" name="generate" value="Generate!" OnClick="guess_Click" />
<asp:Button runat="server" class="button red" id="win" name="win" value="you won" />
</ContentTemplate>
</asp:UpdatePanel>
but it has no effect over my array (although my page doesnt post back...)
anyone has a solution ?
Thanks!
You are using an UpdatePanel, it is inherently AJAXified. Just add a trigger section to catch the button click:
<asp:UpdatePanel runat="server" ID="update">
<ContentTemplate>
<input type="text" class="response" id="how_many" name="guess" placeholder="Enter your guess..." />
<asp:Button runat="server" class="button red" id="generate" name="generate" value="Generate!" OnClick="guess_Click" />
<asp:Button runat="server" class="button red" id="win" name="win" value="you won" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="generate" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
The problem that you're probably running into is that your array isn't persisting through the postbacks. Try what you and ed were getting at, getting and setting from the session. I prefer not to use old school arrays. Consider a list, they are more versatile. And if you specifically need an array at the end then just use myList.ToArray();
private List<int> CurrentArr = new List<string>();
protected void Page_Load(object sender, EventArgs e)
{
if(Session["CurrentArr"] != null)
{
//if there is something stored in the session variable then grab that as a working array
CurrentArr = (List<string>)Session["CurrentArr"];
}
else
{
//if not, then initialize one
CurrentArr = new List<string>();
Session["CurrentArr"] = CurrentArr;
}
}
protected void guess_Click(object sender, EventArgs e)
{
//get reference to the button clicked like you said in your question
var btnMyButton = sender as Button;
btnMyButton.Enabled = false; //example of using the reference, disable the button that was clicked
//add the value of your text box to the array/list, sort, then update the session
this.CurrentArr.Add(txtYourTextBox.Text);
this.CurrentArr.Sort();
Session["CurrentArr"] = this.CurrentArr;
}
Of course, Load is part of an ASP.Net's Page life cycle.
See Page.IsPostBack to have more control on what methods you want, or don't want to run depending on the request type (is it a postback or not).
In the code above, this is probably what you meant:
if (Session["CurrentArr"] != null)
{
CurrentArr = (string[])Session["CurrentArr"];
}
else
{
CurrentArr = new string[length]; //where is length defined?
Session["CurrentArr"] = CurrentArr;
}
I have a form with some custom validation. There is a button on the form that should take the user to a 'confirm page' to show all the details of an order.
On-Page Validation
<asp:TextBox ID="txtBillingLastName" Name="txtBillingLastName"
runat="server" CssClass="txtbxln required"></asp:TextBox>
<asp:CustomValidator
ID="CustomValidatorBillLN" runat="server"
ControlToValidate="txtBillingLastName"
OnServerValidate="CustomValidatorBillLN_ServerValidate"
ValidateEmptyText="True">
</asp:CustomValidator>
Validator code behind
protected void CustomValidatorBillLN_ServerValidate(object sender, ServerValidateEventArgs args)
{
args.IsValid = isValid(txtBillingLastName);
}
However, if I add PostBackUrl or Response.Redirect to the button onclick method, all the validation controls are ignored.
I could call all the validation methods with the onclick method, but that seems a less than an elegant solution.
I've tried setting CausesValidation=False with no luck.
Any suggestions?
Of course that validation IS ignored if you redirect unconditionally. You should call this.IsValid before you redirect like
protected btRedirect_Click( object sender, EventArgs e )
{
if ( this.IsValid )
Response.Redirect( ... );
}
Check this code
void ValidateBtn_OnClick(object sender, EventArgs e)
{
// Display whether the page passed validation.
if (Page.IsValid)
{
Message.Text = "Page is valid.";
}
else
{
Message.Text = "Page is not valid!";
}
}
void ServerValidation(object source, ServerValidateEventArgs args)
{
try
{
// Test whether the value entered into the text box is even.
int i = int.Parse(args.Value);
args.IsValid = ((i%2) == 0);
}
catch(Exception ex)
{
args.IsValid = false;
}
}
And Html side code
<form id="Form1" runat="server">
<h3>CustomValidator ServerValidate Example</h3>
<asp:Label id="Message"
Text="Enter an even number:"
Font-Name="Verdana"
Font-Size="10pt"
runat="server"/>
<p>
<asp:TextBox id="Text1"
runat="server" />
<asp:CustomValidator id="CustomValidator1"
ControlToValidate="Text1"
ClientValidationFunction="ClientValidate"
OnServerValidate="ServerValidation"
Display="Static"
ErrorMessage="Not an even number!"
ForeColor="green"
Font-Name="verdana"
Font-Size="10pt"
runat="server"/>
<p>
<asp:Button id="Button1"
Text="Validate"
OnClick="ValidateBtn_OnClick"
runat="server"/>
For further information check Custom validator
Hope my answer help you to solve your problem.