I've done everything this page told me to do, but it's not working, i've seen people posting about this problem and being told to add a required field validator, i've done that, still not working.
Here's the client side part
<asp:CustomValidator
ID="CustomValidator1"
runat="server"
ControlToValidate="TextBoxUsername"
ErrorMessage="Username already exists"
OnServerValidate="CustomValidator1_ServerValidate"
ValidateEmptyText="True" <!--tried without this line-->
ValidationGroup="form"> <!--tried without this line-->
</asp:CustomValidator>
Here's the C# server side code
protected void CustomValidator1_ServerValidate(object source, ServerValidateEventArgs args){
args.IsValid = false;
}
looks pretty simple, right ? it should keep appearing all the time, right ?
well, it only appears at the beginning and then disappears forever and that's because I have this line in the page_load() method, but i also have it in the button_click() method.
Page.Validate();
First up, remove the validation group, and add in Text:
<asp:CustomValidator
ID="CustomValidator1"
runat="server"
ControlToValidate="TextBoxUsername"
ErrorMessage="Username already exists"
Text="Username already exists"
OnServerValidate="CustomValidator1_ServerValidate"
ValidateEmptyText="True">
</asp:CustomValidator>
ErrorMessage will show in a ValidationSummary control and Text should show where the validator is.
Update the button to cause validation (I believe true is the default anyway, but lets be explicit):
Then check if the page is valid after click, Page.Validate doesn't need to be called as it will be automatically for things that CauseValidation.
protected void Button1_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
// Do Cool Stuff
}
}
Additionally, drop a breakpoint on the click method when checking it as you don't have any client side wiring (e.g. ClientValidationFunction="somejsfunction" on the validator) so you will only hit this code when you get through to server side validation.
Related
I'm new to web programming with .NET.
I am developing a web page with webforms, and I want at a certain moment to programmatically show a modal window, for the user to accept or cancel, according to a question. Exactly what does the "confirm" function of JavaScript.
I tried to get it calling a JavaScript function:
Page.ClientScript.RegisterStartupScript (this.GetType (), "CallMyFunction", "MyFunction()", true);
But I need to do it without reloading the page, and I also need to control if the user has accepted or canceled and I do not know how to do it.
I've also tried getting it using the ModExPopupExtender control from DevExpress.
Can someone tell me a simple way to get what I want?
I can not understand how something so usual in web programming, and that PHP + javascript would not pose any problem can be so complicated.
All start in a one-button event on the code behind:
protected void btn1_Click(object sender, EventArgs e)
{
//I make a series of checks
//If certain conditions I want to show the confirm
//According to the user has chosen ok or cancel will perform a certain action
}
Onclientclick does not help me because before launching the "confirm" I have to do some checks on the server side.
Thank you very much.
You can use OnClientClick which is a property on most web controls.
I like to just bring up a simple confirm() dialog which executes the server code if the user clicks OK and does nothing if the user cancels the action:
<asp:Button runat="server" ID="btnSave" Click="btnSave_Click" Text="Save"
OnClientClick="return confirm('Are you sure you want to do this thing?');" />
You can do other things with it as well, but the key thing to remember is that anything you do in OnClientClick will happen before the page gets posted back to the server.
This is also perfectly valid:
<asp:Button runat="server" ID="btnSave"
OnClientClick="showModalConfirm('some message goes here');" ... />
<script>
function showModalConfirm(msg)
{
$(".modal .message").innerHtml(msg);
$(".modal").Show();
}
</script>
You can set the action that OnClientClick should perform in your codebehind in exactly the same way:
protected void Page_Load(object sender, EventArgs e)
{
btnSave.OnClientClick = "return confirm('Are you sure you want to do this thing?');";
}
You can use below code in c# to call javascript function. Below code will execute afterpostback() javascript function:
ClientScript.RegisterStartupScript(GetType(), Javascript, "javascript:afterpostback();", true);
And you can write code in javascript function to display any div or popup:
<script language="javascript" type="text/javascript">
function afterpostback() {
//Here you can write javascript to display div/modal
}
</script>
One way I've handled this previously was to have 2 buttons on the page. The first would be initially visible and labeled "Submit". The second would be initially hidden and labeled "Confirm". The "Submit" button would postback upon click and perform your server side checks/validation. If those checks failed, an appropriate error message would be displayed. If those checks passed, an appropriate "Please confirm your submission"-type message would be displayed, the "Submit" button would become hidden, and the second "Confirm" button would become visible. When that Confirm button was clicked, it would postback again and fully submit.
EDIT: I forgot to mention, there's a bit more to this that occurred to me after I initially posted. You'll have to protect the fields from being edited in the event the server-side verification is successful as you obviously don't want the user changing values and then clicking the Confirm button. That means disabling all the input controls - which could be a pain if you have a lot. You also have to give them a way to (intentionally) Edit in case the server side verification passes, you display the Confirmation, and they change their minds - so basically you'd need a third "Cancel/Edit"-type button that would put the form back in edit mode and show your initial Submit button.
This is a follow up to an earlier issue which I provided my own answer to but there is a new wrinkle in the process that I'm looking for an answer.
Scenario:
Have a asp.TextBox embedded inside of a asp.FormView control. Prior issue was that I couldn't populate the TextBox from code behind (C#). This was corrected by adding AutoPostBack = "true" to the TextBox.
Issue:
The postback corrected the population of the Text box but now two passes on the control assignment have to be executed in order to see the textbox populated.
Specific Question
How can correct this so it doesn't require a second click of the button to see the textbox populated.
Code Examples:
/*-- This is the fragment of code in the aspx which is related to the issue: --*/
<asp:FormView runat="server" ID="EditImpStndPreamble" DataSourceID="ImpStndPreambDS" OnItemCommand="EditImpStndPreamble_ItemCommand" DefaultMode="Edit" DataKeyNames="ARS_Index">
<InsertItemTemplate>
<asp:Label runat="server" Font-Size="Small" Font-Bold="true" Width="60" Text="Index #"></asp:Label>
<asp:Label Text='<%# Eval("ARSEL_Index") %>' runat="server" ID="ARSEL_IndexLabel1" Width="74" />
<asp:Label runat="server" Width="60" Font-Size="Small" Font-Bold="true" Text="Control #"></asp:Label>
<asp:TextBox Text='<%# Bind("ARSControlNum") %>' runat="server" ID="ARSControlNumTextBox" Width="74" />
<asp:LinkButton runat="server" Text="Insert" CommandName="Insert" ID="InsertButton" CausesValidation="True" /> <asp:LinkButton runat="server" Text="Cancel" CommandName="Cancel" ID="InsertCancelButton" CausesValidation="False" />
</InsertItemTemplate>
</asp:FormView>
// This is the fragmentof code in the C# code behind related to the issue
// This is where we update the control number
Label ctrnum = (Label)EditElementsFV.Row.FindControl("ARSControlNumLabel");
if (ctrnum != null)
ctrnum.Text = Session["CurrentControl"].ToString();
Any insight here would be welcomed. I've tried several things but haven't come up with a means of making this work like I want it to. I'm thinking if I could trigger a second postback of only the TextBox control here that could resolve it. The problem is every method of doing a postback from code behind seems to reset the page which by default has this FormView invisible.
Regards,
Updated 03/24/17 1:06PM Central US:
I took a bit of a break from this issue to work on another segment of the project. I tried several more thing but the last thing I did was track several variables through the debugger and examine the flow of the code as I stepped through the pertinent sections of code.
To the double tap issue I discovered that the first time you click on the Insert Implementation Standards button that the execution was routed through 'Item Template' of the FormView and then it ran through the 'Insert Template' before coming to rest.
Conversely the second click of the button executed as I would have expected and ONLY executed the 'Insert Template of the FormView.
I also observed all the variables that are used in the DataSource related to the FormView being properly populated prior to the execuation of either the Item Template and/or the Insert Template of the FormView.
So, this is even more baffling that I originally ran into it because at first all that I was dealing with was the lack of visibility of two TextBoxes, now however, we have the curiosity of the code executing the Item Template of the FormView prior to walking through the Insert Template.
Ken...
Updated: 03/27/17 9:55AM Central US
I have been working on this and searching for examples of similar issues that I might be able to leverage from and so have now attempted using a FormView.ItemInserting block (Which is bypassed prior to actual execution of the 'insert') and FormView.DataBound blocks. The DataBound was able to trigger but I had to encompass the block in a conditional 'if (IsPostBack)' to avoid trigging a null reference error. This properly routed through the block however the result on the screen draw was the same wit the fields not being populated as intended. Here is the last block as last attempted:
protected void EditElementsFV_DataBound(object sender, EventArgs e)
{
if (IsPostBack)
{
Label ctrnum = (Label)EditImpStndPreamble.Row.FindControl("ARSControlNumLabel");
if (ctrnum != null)
ctrnum.Text = Session["CurrentControl"].ToString();
Label famlbl = (Label)EditImpStndPreamble.Row.FindControl("ColumnTagLabel");
if (famlbl != null)
famlbl.Text = Session["CurrentFamily"].ToString();
}
}
Pressing on but could really use some other eyes on this.
Update: 03/29/17 7:42AM Central US
I wanted to post this update yesterday but got pulled off on a different project for a bit. My latest attempt to resolve this issue I thought for certain that it would work. But it has also failed to load the values into the insert mode of the forum until the button has been selected the second time.
What this does is from the trigger of 'DataBound' in the FormView it directes the flow to a function FillDefaultValue which assigns default values to the two parameters that are in the FormView that control the TextBox displays.
In my mind this 'should have' resolved the issue as the default value would then be the values contained in the Session variables instead of being blank(null).
public void FillDefaultValueInFormView()
{
if (EditElementsFV.CurrentMode == FormViewMode.Insert)
{
EditElementsDS.SelectParameters["ARSControlNum"].DefaultValue = Session["CurrentControl"].ToString();
EditElementsDS.SelectParameters["ColumnTag"].DefaultValue = Session["CurrentColumn"].ToString();
}
}
protected void EditElementsFV_DataBound(object sender, EventArgs e)
{
if (IsPostBack)
{
FillDefaultValueInFormView();
}
}
So the mystery continues...
I ended up using the function FillDefaultValueInFormView() defined in the question to resolve this.
I watch in debut the flow over and over again and realized what was happening was that when I set the FormView's mode to Insert that it was flushing the value assignments that I was placing on the TextBox.
Then I realized that what I needed to do was assign the default value in the DataSource to be what I desired in the TextBox 'prior' to setting the mode of the FormVeiw to Insert. So, I added the call to the function in the early portion of my Button_click event immediately followed by changing mode of the FormView to Insert.
protected void AddImpStadBTN_Click(object sender, EventArgs e)
{
Session["CurrentColumn"] = "IMP";
FillDefaultValueInFormView();
EditElementsFV.ChangeMode(FormViewMode.Insert);
... More code follows to complete this but left off as it doesn't effect the results...
}
After doing this the change to insert mode on the FormView was successfully prepopulated as I had intended for the user. I'll now change them to ReadOnly so the user can't change them, making them programmatically driven fields within the form.
I have a page with a textbox control, a Custom Validator, a button to save entered data and code to handle the custom validation.
I set up a simple code test just to see how the Custom Validators work.
I hope to add more validations that check multiple controls later. The same thing happens if I do add the ControlToValidate attribute for the textbox control.
(I don't think I need a "ControlToValidate" attribute for this. I plan to validate multiple controls later. I can't put all the controls I am validating in that attribute.)
When I run my app, the save takes place and the validation is happeing - the message appears. I don't understand why the save isn't stopped when I enter "3" in the textbox I am checking. If the validation is happening, and if the IsValid = false, why is the save taking place?
Here is the Custom Validator:
<asp:CustomValidator ID="VisitSaveCustomValidator" runat="server" OnServerValidate="VisitSaveCustomValidator_ServerValidate" ValidationGroup="SaveVisit_val"></asp:CustomValidator>
Here is the button:
<asp:Button ID="SaveVisit_btn" runat="server" Visible="false" Text="- Save Visit -" ValidationGroup="SaveVisit_val" OnClick="SaveVisit_btn_Click" />
Here is the code for the Custom Validator:
protected void VisitSaveCustomValidator_ServerValidate(object source, ServerValidateEventArgs args)
{
if (VisitNumber_tbx.Text == "3")
{
args.IsValid = false;
VisitSaveCustomValidator.ErrorMessage = "The Visit Number cannot be 3.";
}
else
{
args.IsValid = true;
}
Please let me know if I need to add more code or more information.
I thought this would be pretty straight-forward. I followed an example in a book and some online. I understand that the page is going back to the server to be validated. But, shouldn't the save be stopped since the IsValid = false?
It seems like the save is happening first, then the validation code executes, which causes the message to appear.
Thanks.
I believe you may have to manually call the validate method.
VisitSaveCustomValidator.Validate();
Then check to see if it was valid.
VisitSaveCustomValidator.IsValid();
This can be put in the button click event.
I have a web form that uses CustomValidators, and I have a few validation routines in my "validators.js" file that I can set as the ClientValidationFunction on each CustomValidator. Routines such as ValidateRequired, ValidateEmail, ValidateUsername etc.
I would like to define a set of globally available CustomValidator functions within my c# code itself, however I'm failing to grasp how to do this.
The ideal solution would be something along these lines:
Validators.cs:
protected void ValidateUsername(object sender, ServerValidateEventArgs e){
// Validation Logic here
}
Default.aspx
<asp:TextBox runat="server" id="txtUsername">
<asp:CustomValidator runat="server" OnServerValidate="ValidateUsername" id="cvldUsername" ControlToValidate="txtUsername" ClientValidationFunction="ValidateUsername"></asp:CustomValidator>
I know I could probably add the event into my default.aspx.cs which then calls my Validation function for a bool response and then return a true/false on IsValid -- But I was wondering if there was a more elegant way to do this.
I feel I may be missing something.
Thanks in advance,
Dave
I've put a CustomValidator on my form. I have not set its ControlToValidate property. In its ServerValidate event I've written the following:
protected void CustomValidator1_ServerValidate(object source,
ServerValidateEventArgs args)
{
args.IsValid = false;
}
I put a breakpoint to this method but it seems to never come to that point. But if I do this on another form it works like a charm.
The ValidationGroup property of both the button and the CustomValidator are the same
I tried deleting this property in both the button and the CustomValidator, still does not work.
It seems as there's something formwide. I just put a CustomValidator on the form and do not touch any of its properties other than just setting its ServerValidate event method.
EDIT: Here's the aspx part:
<asp:CustomValidator ID="CustomValidator2" runat="server"
ErrorMessage="This is a test"
onservervalidate="CustomValidator1_ServerValidate"
ValidationGroup="PA"></asp:CustomValidator>
<asp:Button ID="btnPensionersOK" runat="server" Text="OK" Width="75px"
onclick="Button1_Click" ValidationGroup="PA" />
Try to force the validation in the button-click handler via Page.Validate:
protected void Button1_Click(Object sender, EventArgs e)
{
Page.Validate();
if(Page.IsValid)
{
// servervalidate should have been called
}
}
Edit(from comments):
If you want the customvalidator to validate if nothing was entered/selected in your controls, you need to set ValidateEmptyText to true. You also might want to let the CustomValidator replace the RequiredFieldValidators.
I assume that the validator-order on the aspx decides whether or not a customvalidator's severvalidate is called if a previous Validator already has made Page.IsValid=false. Or ASP.NET is so smart that it assumes the SeverValidate to be costlier than a simple text-is-empty check.
I would also like to put some more help for those who will use CustomValidators and RequiredFieldValidators at the same time. One should take into account that Client side validation takes place first. And the server side validation will occur only after PostBack. I'm sure you got it but just in case this is not quite clear: It means first all the controls that are bound to certain client side working validators must be valid to let Postback to occur. After Page. IsValid is True server side stuff takes place and posts back any changes which includes server side validation messages.
So here are the ways one can make both CustomVCalidators and other built in validators to work at the same time.:
Set both groups of validators to work on Client side. In this case we must ensure that for the custom valitor(s) we spacify the script that will make validation on the client side. Without writing script and just filling in the ServerValidate method the validation will take place in the server.Even if EnableClientScript property is set to True.
Set both groups of validators to work on server side. To do so simply set EnableClientScript to False. But note that this will load the server.