jquery form validation: validation script specified externally - asp.net

i have a jquery form validation in the master page and it works fine and i got that working from this article: http://www.dotnetcurry.com/ShowArticle.aspx?ID=310
my question is: if i place the .js to external and add a reference to my page then its not working... it says object expected
here is how i have done:
in my content page (i am using master page, asp.net )
add in my content page:
<script src="myform_validation.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
ValidateMe(this);
});
</script>
below is in the external .js file:
function ValidateMe() {
$("#aspnetForm").validate({
rules:
{
<%=TextBox1.UniqueID %>:
{
maxlength:1,
//minlength: 12,
required: true
},
<%=TextBox2.UniqueID %>:
{
minlength: 12,
required: true
},
<%=TextBox3.UniqueID %>:
{
minlength: 12,
required: true
}//,
//
},
messages:
{
<%=TextBox1.UniqueID %>:
{
required: "Enter your firstname",
minlength: jQuery.format("Enter at least {0} characters")
},
<%=TextBox2.UniqueID %>:
{
required: "Please enter a valid email address",
minlength: "Please enter a valid email address"
} ,
<%=TextBox3.UniqueID %>:
{
required: "Enter your firstname",
minlength: jQuery.format("Enter at least {0} characters")
}
} ,
success: function(label) {
// set as text for IE
label.html(" ").addClass("checked");
}
});
} ;

I suspect its because your server tags (<%=TextBox1.UniqueID%>) are not being processed by the server. By default IIS does not process .js files.

For starters try to always use the
same identified for jQuery.
Sometimes you use jQuery and
sometimes $, I would recommend
to use $ all the way but just
because its shorter and well known
(and im lazy ;) ).
You are passing this into the
external ValidateMe function, even
though it has no parameters. Are you
sure you extracted the function
properly?
And always make sure all js files
are referenced before you start
using functions within them.

Why are you attempting to put the javascript into an external file? The script is specific to controls on the page, so leave it there. Otherwise you are adding latency to the page by requiring an extra file download.

Related

How do I force a VB.NET script to run before the page itself in ASP.NET WebForms?

I have a script which is included in my page:
<script runat="server" language="VB" src="../AdditionalField/AdditionalFieldSave.aspx"></script>
edit: wrong script, I meant this one:
<!-- #include file="../AdditionalField/AdditionalFieldDisplayHTML.aspx" -->
yes, you can #include in WebForms, apparently!
Inside this script I am adding some values to a list:
If myAdditionalFieldTempReader("Mandatory") Then
MandatoryAdditionalFields.Add("Notes" & additionalFieldFoundCount)
End If
And then back in the page I am retrieving the values from the list:
jQuery("#YouthEdit").validate({
rules: {
BirthDate: {
required: true,
date: true
},
FirstName: {
required: true,
},
LastName: {
required: true,
}
<%
For Each mf As String In MandatoryAdditionalFields
Response.Write("," & mf & ": {required: true}")
Next
%>
},
messages: {
BirthDate: "Enter a birth date",
FirstName: "Enter a First Name",
LastName: "Enter a Last Name"
},
submitHandler: function(form) {
//form.submit();
document.YouthEdit.submit();
}
});
My problem is that when I retrieve the values from the list, the list is still empty; it hasn't been populated yet. How can I force the script to run before the page itself so the values are present when I need them?
edit: OK, I tried this:
<input id="mandatoryAdditionalFieldsHidden" type="hidden" value="" runat="server" />
on the include page and this:
mandatoryAdditionalFieldsHidden.Value = String.Join(",", MandatoryAdditionalFields)
in a function called from Page_Init on the main page and
var mandatoryAdditionalFields = jQuery("#mandatoryAdditionalFieldsHidden").val().split(',');
for (field in mandatoryAdditionalFields)
rules.push([field, 'required: true']);
in the main page JavaScript. And now I get an error saying I can't call split on undefined... why would the hidden field have an undefined value when I set it in the Page_Init?
You should write your jquery code in this way, so it's executed only once the page has been loaded:
$( document ).ready(function() {
// Put your code here.
});

Angular/Valdr - Add custom classes to valdr-form-group

Im pretty new to Angular. I'm using Valdr for validating my forms in Angular.
I want to add some custom classes with my own css on a form-group when there is an error.
In the documentation of Valdr I found this part about CSS to control visibility. It says that I need to inject valdrClasses and override the values. But on every try I get an error.
I tried adding it as a module/provider but nothing works.
My code without valdrClasses:
angular.module('validators', ['valdr'])
.config(function (valdrProvider, valdrMessageProvider) {
valdrProvider.addConstraints({
'User': {
'name': {
'required': {
'message': 'Name is required.'
}
},
'email': {
'required': {
'message': 'Email is required.'
},
'email': {
'message': 'Must be a valid e-mail address.'
}
}
}
});
valdrMessageProvider.setTemplate('<div class="help-block">{{ violation.message }}</div>');
});
Can someone help me in the right direction? Because I have no clue how to inject and customize the css classes.
Inject the valdr service into for example a controller or in the run block and use the function setClasses.
For example if you want to only override invalid:
app.run(function(valdr) {
valdr.setClasses({
invalid: 'my-invalid-class'
});
});
Demo: http://plnkr.co/edit/otLvNqXjRiJ4CGl8gDlu?p=preview
Note that it might depend on which version of Valdr you are using.

Using jquery.validate.js to Validate WebForms when using in multiple Usercontrols

So I have a Default Search page that calls 2 UserControls
<uc1:BasicSearch ID="BasicSearch" runat="server" />
<uc1:AdvancedSearch ID="AdvancedSearch" runat="server" />
Both of my usercontrols have multiple date Fields that I wish to validate but I'm having a few issues
Since I'm using .net, the Controls get renamed, I got around this but using <%=specificDateTextbox.UniqueID%>, however, this ONLY works in the page, once I try to move all the Script to a .JS page it stops working.
For some reason, the validation never fires on the AdvancedSearch control when both are loaded. If I comment out the BasicSearch usercontrol, the AdvancedSearch validation fires as it should.
This obviously leads me to believe there's a naming conflict or perhaps I can only use a sinlge validation script on a a page?
The code im using
BasicSearch.ascx
<asp:TextBox ID="specificDateTextbox" runat="server" CssClass="form-control" placeholder="YYYY-MM-DD"></asp:TextBox>
The Script
<script>
$(function () {
$("#form1").validate({
rules: {
<%=specificDateTextbox.UniqueID%>: {
dateISO:true,
},
<%=RangeStartDateTextbox.UniqueID%>: {
dateISO:true,
},
<%=RangeEndDateTextbox.UniqueID%>: {
dateISO:true
}
},
messages:
{
<%=specificDateTextbox.UniqueID%>: "* Please use a proper Date Format (YYYY-MM-DD)",
<%=RangeStartDateTextbox.UniqueID%>: "* Please use a proper Date Format (YYYY-MM-DD)",
<%=RangeEndDateTextbox.UniqueID%>: "* Please use a proper Date Format (YYYY-MM-DD)"
},
highlight: function (element) {
$(element).closest('.form-horizontal').addClass('has-error');
},
unhighlight: function (element) {
$(element).closest('.form-horizontal').removeClass('has-error');
},
errorElement: 'span',
errorClass: 'help-block',
errorPlacement: function (error, element) {
if (element.parent('.input-group').length) {
error.insertAfter(element.parent());
} else {
error.insertAfter(element);
}
}
});
});
</script>
AdvancedSearch.ascx
The Script
<script>
$(function () {
$("#form1").validate({
rules: {
<%=AdvSpecificDateTextbox.UniqueID%>: {
dateISO:true
}
},
messages:
{
<%=AdvSpecificDateTextbox.UniqueID%>: "* Please use a proper Date Format (YYYY-MM-DD)"
},
highlight: function (element) {
$(element).closest('.form-horizontal').addClass('has-error');
},
unhighlight: function (element) {
$(element).closest('.form-horizontal').removeClass('has-error');
},
errorElement: 'span',
errorClass: 'help-block',
errorPlacement: function (error, element) {
if (element.parent('.input-group').length) {
error.insertAfter(element.parent());
} else {
error.insertAfter(element);
}
}
});
});
</script>
Edit
The two rendered controls look like the below
<input name="ctl00$MainContent$BasicSearch$specificDateTextbox" type="text" id="MainContent_BasicSearch_specificDateTextbox" class="form-control " placeholder="YYYY-MM-DD" />
<input name="ctl00$MainContent$AdvancedSearch$AdvSpecificDateTextbox" type="text" id="MainContent_AdvancedSearch_AdvSpecificDateTextbox" class="form-control " placeholder="YYYY-MM-DD" />
Any help would be greatly appreciated.
For the record, I was able to make the validator work with usercontrols by using the fully rendered control name and chaining the rules together in a .js for the page that calls the user controls.
see below
search.aspx
<%# Register TagPrefix="uc1" TagName="BasicSearch" Src="~/_usercontrols/BasicSearch.ascx" %>
<%# Register TagPrefix="uc1" TagName="AdvancedSearch" Src="~/_usercontrols/AdvancedSearch.ascx" %>
<uc1:BasicSearch ID="BasicSearch" runat="server" />
<uc1:AdvancedSearch ID="AdvancedSearch" runat="server" />
<script src="<%= ResolveUrl("~/scripts/search/_actions.js")%>"></script>
_actions.js
$(function () {
$("#form1").validate({
rules: {
ctl00$MainContent$BasicSearch$specificDateTextbox: {
dateISO: true
},
ctl00$MainContent$BasicSearch$RangeStartDateTextbox: {
dateISO: true
},
ctl00$MainContent$BasicSearch$RangeEndDateTextbox: {
dateISO: true
},
ctl00$MainContent$AdvancedSearch$AdvSpecificDateTextbox: {
dateISO: true
},
ctl00$MainContent$AdvancedSearch$AdvRangeStartDateTextbox: {
dateISO: true
},
ctl00$MainContent$AdvancedSearch$AdvRangeStartEndTextbox: {
dateISO: true
}
},
messages:
{
ctl00$MainContent$BasicSearch$specificDateTextbox: "* Please use a proper Date Format (YYYY-MM-DD)",
ctl00$MainContent$BasicSearch$RangeStartDateTextbox: "* Please use a proper Date Format (YYYY-MM-DD)",
ctl00$MainContent$BasicSearch$RangeEndDateTextbox: "* Please use a proper Date Format (YYYY-MM-DD)",
ctl00$MainContent$AdvancedSearch$AdvSpecificDateTextbox: "* Please use a proper Date Format (YYYY-MM-DD)",
ctl00$MainContent$AdvancedSearch$AdvRangeStartDateTextbox: "* Please use a proper Date Format (YYYY-MM-DD)",
ctl00$MainContent$AdvancedSearch$AdvRangeStartEndTextbox: "* Please use a proper Date Format (YYYY-MM-DD)"
},
highlight: function (element) {
$(element).closest('.form-horizontal').addClass('has-error');
},
unhighlight: function (element) {
$(element).closest('.form-horizontal').removeClass('has-error');
},
errorElement: 'span',
errorClass: 'help-block',
errorPlacement: function (error, element) {
if (element.parent('.input-group').length) {
error.insertAfter(element.parent());
} else {
error.insertAfter(element);
}
}
});
});
I just thought that I would throw in my .02 here. Client Id's do not work when in script files ( but you already knew that) because ASP.NET renders the controls (and the ID's) on the page when servicing the request for the page. I have found 2 ways around this and have been able to add code to my script files.
If you are using .NET 4.0 or higher you can use ClientIDMode="Static" on the element which will cause the rendered control to maintain the ID that you assigned it in the markup. You can use this per control, at the page level, and application level in the web.config. This makes it much easier to find it with jQuery in your script files. This would be the preferred way to do it.
If you are using an older version of .NET where ClientIDMode is not available you can use an "ends with" selector with jQuery like this $('input[id$="myServerId"]') to look for your item with its ID property being at the end of the rendered id from ASP.NET.
I realize this is pretty old and most people aren't even using usercontrols much anymore, but I've had to do it here after moving some code in an older application from a page to a usercontrol in order to reuse it somewhere else, and I've had to deal with this. So just in case someone else has to deal with this, here is what I ended up doing:
function convertUserControlValidationRules($container, rules, msgs) {
var association = {},
newRules = {},
newMsgs = {};
for (var key in rules) {
var name = "";
if (association.hasOwnProperty(key))
name = association[key];
else {
name = $container.find("#" + key).attr("name");
association[key] = name;
}
newRules[name] = rules[key];
if (msgs.hasOwnProperty(key))
newMsgs[name] = msgs[key];
}
return { rules: newRules, messages: newMsgs };
}
Where $container is the form's jQuery object, and rules/msgs are the original rules/messages. Obviously, you will need to use this with a ClientIDMode="Static" declaration in your usercontrol.
A small example of usage here, would be:
var ucRules = convertUserControlValidationRules($form, { txtDate: { required: true }}, { txtDate: { required: "Please enter the date!" }});
$form.validate({ rules: ucRules.rules, messages: ucRules.message });
instead of
$form.validate({
rules: { txtDate: { required: true }},
messages: { txtDate: { required: "Please enter the date!" }}
});
very minimal code to change, mucho time saved! Hope that can help somebody!

jQuery UI with asp.net Master Page

I am updating one of my sites from asp.net with jQuery UI to use master pages.
Here is a snippet of my original code, which works w/out master pages, but not with:
$('#myCancelEventDialog').dialog({
autoOpen: false,
width: 500,
buttons: {
"Cancel This Event": function () { __doPostBack('btnCancel', ''); },
"Do Nothing": function () { $(this).dialog("close"); }
}
});
However, I see what is going on, with the master page chaging the names of the functions, and this code below fixes it for this instance.
$('#myCancelEventDialog').dialog({
autoOpen: false,
width: 500,
buttons: {
"Cancel This Event": function () { __doPostBack('ctl00$ContentPlaceHolder$btnCancel', ''); },
"Do Nothing": function () { $(this).dialog("close"); }
}
});
Notice I have put the 'ctl00$ContentPlaceHolder$' prefix on the btnCancel so that the appropriate callback function is fixed.
From other threads I have read on stackoverflow, there is a better solution than patching up the code one place at a time as I have done above, but haven't quite got it right yet.
What is the general-purpose way to get jQuery UI postback functions to find the right callback function when you are using master pages like in my example above?
A quick fix could be to do the following
$('#myCancelEventDialog').dialog({
autoOpen: false,
width: 500,
buttons: {
"Cancel This Event": function () { __doPostBack("'" + $('[id$=btnvalue]')[0].id + "'", ''); },
"Do Nothing": function () { $(this).dialog("close"); }
}
});
This uses the jQuery endswith selector since the master page now means your control id have prefixes but the ending is the same. This works as long as you dont have duplicate id's dotted around which is what the asp.net team aimed to stop by prefixing nested control id's.
The downside of this is that jQuery has to do more work to find the element as it cannot use the native getElementById.
Another fix would be to upgrade to asp.net 4.0 where you can turn of the prefixing of controls using the clientidmode
You will want to use the ClientID of the control you are after:
__doPostBack('<%= btnCancel.ClientID %>', '');
However, if you use this technique, you will have to enclose your script block inside a div that is exposed to the ASP.Net runtime via the runat attribute.
<div runat="server">
<script type="text/javascript" language="javascript">
//Your Script Here
</script>
</div>
It might be helpful for developers;
http://deepasp.wordpress.com/2013/05/31/jquery-dialog-in-asp-net-master-page/

jquery validation stops page submit when non required field is empty

I'm using jquery to validate an asp.net form (content within a master page). The required fields validation all works great, but I have a field that is not required, but if it does have text then it needs to be in the proper format. Jquery validates incorrect text just fine, but when the text is empty it stops the form from submitting (no error message though). Anyone have an idea why this could be happening or what to do about it?
// Add validation rule for email
if ($("input[id$='TextBoxEmail']").length) {
$("input[id$='TextBoxEmail']").rules('add', {
required: false,
email: true,
messages: {
email: 'Please enter a valid email.'
}
});
}
I have just set up a similar test and cannot replicate the issue (see code below):
<script type="text/javascript">
$(document).ready(function () {
$("#test").validate();
if ($("input[id$='txtText']").length) {
$("input[id$='txtText']").rules('add', {
required: false,
email: true,
messages: {
email: 'Please enter a valid email.'
}
});
}
});
</script>
<form id="test">
<input type="text" id="txtText" />
<input type="submit" />
</form>
I am using jQuery 1.5.1 and the latest jquery.validate.min.js
I can only suggest that you make the jQuery selector more specific as id$='TextBoxEmail' means ends with 'TextBoxEmail'. This may be an issue if you have conflicting fields names?
We discovered that the workaround for this is to manually remove the validation based on our criteria.
// Add validation rule for first name (default Person type is Individual so the validation is needed as default)
if ($("input[id$='TextBoxFirstName']").length) {
$("input[id$='TextBoxFirstName']").rules('add', {
required: true,
messages: {
required: 'First Name is required for individuals.'
}
});
}
// Add event for checking if first name validation is needed
$('select[id$=DropDownListPersonType]').change(function () {
if ($('select[id$=DropDownListPersonType] option:selected').text() == 'Individual') {
// Add validation rule
$("input[id$='TextBoxFirstName']").rules('add', {
required: true,
messages: {
email: 'First Name is required for individuals.'
}
});
}
else {
// remove rule
$("input[id$='TextBoxFirstName']").rules("remove");
}
});

Resources