Force validation on textboxfor before submit - javascript

I have a field that is required:
[Required(ErrorMessage = "Please enter a name.")]
[StringLength(80, ErrorMessage = "Name cannot be longer than 80 characters.")]
[RegularExpression("^[a-zA-Z ]+$", ErrorMessage = "Only letters can be used.")]
public string Name { get; set; }
I am using jqueryval.
My textbox:
#Html.TextBoxFor(x => x.mymodel.Name , new
{
id = "namebx",
style = "width: 100%;",
#class = "form-control loginTextBoxes"
})
#Html.ValidationMessageFor(x => x.experience.Name , "", new { #class = "text-danger" })
I have a control that when pressed scrolls the page to next section:
<div id="namebutton" class="btn btn-success"><i class="fa fa-check-circle-o"></i> Next</div>
I would like that if the validation criteria is not reached the validation warning will show and the scroll will not work until valid:
$("#namebutton").click(function() {
if ($('#namebx').valid()){
$('body').animate({ scrollTop: $('.form-group').find('.parentDiv:hidden:first').offset().top + 500 }, 1000);
$(".parentDiv:hidden:first").show("slow");
alert("true");
}
else {
alert("false");
}
});
At the moment all I get regardless of textbox content is an alert true and the page scrolls. The validation only kicks in when the submit button is clicked.

Related

I am trying to store data in sql server but i run into an error which i dont know how to fix

I am trying to store the users name, email and their message on my contact page. When i run my website and go on the contact page and type all the details inside the contact form and click the send button (send button called submitBtn) i get the error you can see below in the image.
error message:
c# code: this c# code is for the send button.
protected void submitBtn_Click(object sender, EventArgs e)
{
try
{
//Create the conection string and open the conn
SqlConnection conne = new SqlConnection(ConfigurationManager.ConnectionStrings["Fasthosts_MMConnectionString"].ConnectionString);
//Open the connection string
conne.Open();
//Get all the values from the text boxes etc and pass them over to the DB
string insertQuery = "insert into Contact(UserName, Email, Message) " +
"values(#UserName, #Email, #Message)";
SqlCommand com = new SqlCommand(insertQuery, conne);
//Get values from the controls such as the text boxes and pass them over to the DB
com.Parameters.AddWithValue("#UserName", tbUserName.Text);
com.Parameters.AddWithValue("#Message", userMessage.Text);
com.Parameters.AddWithValue("#Email", userEmail.Text);
//This actually executes the query with the given values above.
com.ExecuteNonQuery();
//Dispose the connection string once the data has been passed over the DB
conne.Close();
}
catch (Exception problem)
{
//throw Exception ;
Response.Write("Error Message: " + problem.ToString());
throw;
}
}
html code:
<div id="contactForm" class="contactForm">
<div id="formHeader" class="formHeader">
<h1 id="message">Contact Us :)</h1>
</div>
<div id="formBody" class="formBody">
<form action="homepage.aspx" method="POST" name="contactForm">
<div class="inputContainer">
<label for="userName">
<i class="fa fa-lg fa-fw fa-user"></i>
</label>
<asp:TextBox ID="tbUserName" placeholder="John Smith" runat="server"></asp:TextBox>
<!--<input name="name" id="userName" type="text" placeholder="John Smith">-->
</div>
<div class="inputContainer">
<label for="userEmail">
<i class="fa fa-lg fa-fw fa-envelope"></i>
</label>
<asp:TextBox ID="userEmail" placeholder="jsmith#domain.com" runat="server"></asp:TextBox>
</div>
<div class="inputContainer">
<asp:TextBox ID="userMessage" rows="10" placeholder="Enter your message" runat="server" Height="100px"></asp:TextBox>
</div>
<!--<input id="submitBtn1" class="submitBtn" type="submit" value="Send">-->
<asp:Button ID="submitBtn" Class="submitBtn" runat="server" Text="Send" OnClick="submitBtn_Click" />
</form>
</div>
javascript code :
(function () {
"use strict";
var //GLOBAL VARIABLES
input,
container,
//CSS CLASSES
classSuccess = "success",
classError = "error",
//FORM VALIDATOR
formValidator = {
init: function () {
this.cacheDom();
this.bindEvents();
},
cacheDom: function () {
//MAIN PARENT ELEMENT
this.contactForm = document.getElementById("contactForm");
//MAIN FORM ELEMENTS
this.formHeader = document.querySelector("#formHeader h1");
this.formBody = document.getElementById("formBody");
this.inputContainer = document.getElementsByClassName("inputContainer");
//USER INPUT ELEMENTS
//INPUT FIELDS
this.fields = {
userName: document.getElementById("userName"),
userEmail: document.getElementById("userEmail"),
userMessage: document.getElementById("userMessage")
};
this.submitBtn = document.getElementById("submitBtn");
},
bindEvents: function () {
var i;
//RUN RULES ON SUBMIT BUTTON CLICK
this.submitBtn.onclick = this.runRules.bind(this);
//BIND EVENTS TO EACH INPUT FIELD
for (i in this.fields) {
if (this.fields.hasOwnProperty(i)) {
//VARIABLES
input = this.fields[i];
container = input.parentElement;
//RUN RULES WHEN INPUT HAS FOCUS
input.onfocus = this.runRules.bind(this);
//RESET ERRORS WHEN CONTAINER IS CLICKED
container.onclick = this.resetErrors.bind(this, input);
}
}
},
runRules: function (evnt) {
var target = evnt.target,
type = evnt.type;
//IF EVENT ON SUBMIT BUTTON
if (target === this.submitBtn) {
//PREVENT FORM SUBMITTION
this.preventDefault(evnt);
//IF INPUT HAS FOCUS
} else if (type === "focus") {
//RESET CLASSLIST
this.resetClassList(target.parentElement);
//RESET ERRORS
this.resetErrors(target);
return false;
}
//RESET CLASSLIST
this.resetClassList();
//CHECK FIELDS
this.checkFields();
},
preventDefault: function (evnt) {
//PREVENT DEFUALT
evnt.preventDefault();
},
checkFields: function () {
var i,
validCount = 0,
//EMAIL FILTER
filter = /^([a-zA-Z0-9_\.\-])+\#(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
//CYLCE THROUGH INPUTS
for (i in this.fields) {
if (this.fields.hasOwnProperty(i)) {
input = this.fields[i];
//CHECK IF FIELD IS EMPTY
if (input.value === "") {
//ADD ERROR CLASS
this.addClass(input, classError);
//CHECK IF EMAIL IS VALID
} else if (i === "userEmail" && !filter.test(input.value)) {
//ADD ERROR CLASS
this.addClass(input, classError);
} else {
//FIELD IS VALID
this.addClass(input, classSuccess);
validCount += 1;
}
}
}
//IF ALL FEILDS ARE VALID
if (validCount === 3) {
//SUBMIT FORM
this.submitForm();
}
},
addClass: function (input, clss) {
container = input.parentElement;
//IF INPUT HAS ERROR
if (clss === classError) {
//SHOW ERROR MESSAGE
this.errorMessage(input);
}
//ADD CLASS
input.parentElement.classList.add(clss);
},
errorMessage: function (input) {
var message;
//IF USERNAME HAS ERROR
if (input === this.fields.userName) {
message = "Please enter your name";
//ELSE IF USEREMAIL HAS ERROR
} else if (input === this.fields.userEmail) {
message = "Please enter a valid email";
//ELSE IF USERMESSAGE HAS ERROR
} else if (input === this.fields.userMessage) {
message = "Please enter your feedback";
}
this.renderError(input, message);
},
renderError: function (input, message) {
var html;
//GET INPUT CONTAINER
container = input.parentElement;
//RENDER HTML
html = document.createElement("div");
html.setAttribute("class", "message");
html.innerHTML = message;
//IF MESSAGE ELEMENT DOESN'T EXIST
if (!container.getElementsByClassName("message")[0]) {
//INSERT MESSAGE TO INPUT CONTAINER
container.insertBefore(html, container.firstElementChild);
}
},
resetClassList: function (input) {
var i;
//IF TARGETING SPECIFIC INPUT
if (input) {
//GET INPUT CONTAINER
container = input.parentElement;
//REMOVE CLASSES
container.classList.remove(classError, classSuccess);
//FOCUS ON INPUT FIELD
input.focus();
} else {
for (i in this.fields) {
if (this.fields.hasOwnProperty(i)) {
//REMOVE CLASSES FROM ALL FIELDS
this.fields[i].parentElement.classList.remove(classError, classSuccess);
}
}
}
},
resetErrors: function (input) {
//GET INPUT CONTAINER
container = input.parentElement;
//IF CONTAINER CONTAINS ERROR
if (container.classList.contains(classError)) {
//RESET CLASSES
this.resetClassList(input);
}
},
submitForm: function () {
var waitForAnimation;
//ADD SUCCESS CLASS
this.contactForm.classList.add(classSuccess);
//WAIT FOR ANIMATION TO FINISH
this.changeHeader("Sent Succesfully");
//WAIT FOR ANIMATION TO FINISH
setTimeout(
this.changeHeader.bind(this, "Thank you for your feedback"),
1200
);
},
changeHeader: function (text) {
//CHANGE HEADER TEXT
this.formHeader.innerHTML = text;
}
};
//INITIATE FORM VALIDATOR
formValidator.init();
})();
Write this in first line of page directive in source code
<%# Page EnableEventValidation="false" %>

ASP.NET MVC5 Client-side Validation

I have an amount field in a view that is required if a checkbox is checked.
Once Razor renders the View with Model data, and a user checks a checkbox without a corresponding amount entered. The Validation message appears. If I de-select that checkbox, the validation message does not disappear.
I've tried to use jquery to remove all the rules generated, but if the user were to checkbox again, prior to post back, those validation rules would have been removed (unless I store them... which is getting really ugly.)
Is there an acceptable way to re-validate client-side with the same requirements in the MVC Model?
Model:
[Display(Name = "Include Amount")]
public bool IncludeAmount { get; set; }
[Display(Name = "Amount")]
[RequiredIf("IncludeAmount", TargetValue = true, ErrorMessage = "Amount is required.")]
[MaxDigits(10, 2)]
[RegularExpression(RegularExpressions.Money, ErrorMessage = ErrorMessages.NumericValueInvalidFormat)]
[GreaterThanZero]
public Nullable<decimal> Amount { get; set; }
View:
<td class="dataEntryLabel" colspan="2">
#Html.LabelFor(model => model.IncludeAmount)
</td>
<td class="dataEntryField" colspan="2">
#Html.CheckBoxFor(model => model.IncludeAmount, new { id = "IncludeAmount" })
<span class="dollar-sign">#Html.TextBoxFor(model => model.Amount, "{0:F}", new { id = "Amount", disabled = "disabled" })</span>
#Html.ValidationMessageFor(model => model.Amount)
</td>
JavaScript (Client-side):
function fixUnobtrusiveValidations() {
var form = getForm();
(<any>$).validator.unobtrusive.parse(form);
}
function onClickCheckBoxIncludeAmount(){
fixUnobtrusiveValidations();
}
$('IncludeAmount').click(onClickCheckBoxIncludeAmount);
Try this to disable the client side validation on onclick events
Refer: https://jqueryvalidation.org/validate/#onclick
$("#myform").validate({
onclick: false,
});
OR
$("#yourChkboxID").validate({
onclick: false,
});
This worked:
if (!($('#IncludeAmount').checked)){
toggleValidatorVisibility($('#Amount'), false);
}
function toggleValidatorVisibility(element: any, value) {
var td: any = element.closest('td');
if (value) {
td.find('span.field-validation-error').show();
} else {
td.find('span.field-validation-error').empty();
}
}

C# asp.net mvc Set CheckBoxFor checked-property with Model-Value

In my form i have a chekbox and when i click the checkbox a textbox is enabled.
When i submit the form i got both values(checkbox and textbox)and the site refresh,after the refresh the checkbox is checked but the textbox is disabled but has the last insert value.
If i submit again without making something the textbox returns null and not the last insert value.
I want that the checkbox got the value from my model and change the behavior of the textbox disabled-property und if no new value will be insert,it should return the last insert value.
When i set the model property of false the checkbox is also checked.
Has anyone a idea what i can do ?
View:
#Html.TextBoxFor(m => m.FilterModel.FilterOrgNameValue, new { #class = "form-control", #id = "OrganisatioName", #disabled = "disabled" })
#Html.CheckBoxFor(m => m.FilterModel.FilterOrgNameIsCheckedValue, new { #class = "form-control", #id = "OrgNameChecked", #checked = (Model.FilterModel.FilterOrgNameIsCheckedValue ? "checked" : "unchecked")})
JavaScript:
$("#OrgNameChecked").click(function () {
$('#OrganisatioName').attr("disabled", $(this).is(':unchecked'));
});
Model:
public bool FilterOrgNameIsCheckedValue { get; set; }
Controller (Function which got called by submit):
public ActionResult Index(AdminOrganizationModel m)
{
AdminOrganizationModel model = new AdminOrganizationModel();
if(TempData["model"] != null)
{
m = (AdminOrganizationModel)TempData["model"];
}
if(m.FilterModel == null)
{
m.FilterModel = new AdminOrganizationFilterModel();
}
model = m;
OrganizationBusinessObject organizationBusinessObject = new OrganizationBusinessObject(DbContext);
var organizations = DbContext.GetAllEntitiesQueryable<Organization>();
organizations = FilterOrganizations(organizations, model);
InitializeLicenseList(1);
AdminOrganizationModelBuilder modelBuilder = new AdminOrganizationModelBuilder();
IList<AdminOrganizationModel> organizationsModels = modelBuilder.GetModelCollection(organizations);
model.Organizations = new AjaxGridFactory().CreateAjaxGrid(organizationsModels.AsQueryable(), 1, false, 10) as AjaxGrid<AdminOrganizationModel>;
return View(model);
}
Fields after submit
Simple Solution ;)
I added a simple if statement in the View:
<div class="col-sm-2">
#if (Model.FilterModel.FilterOrgNameIsCheckedValue)
{
#Html.TextBoxFor(m => m.FilterModel.FilterOrgNameValue, new { #class = "form-control", #id = "OrganisatioName"})
}
else
{
#Html.TextBoxFor(m => m.FilterModel.FilterOrgNameValue, new { #class = "form-control", #id = "OrganisatioName", #disabled = "disabled" })
}
</div>
I guess its not the best way but it works =)

Selecting dropdown value shows a Textbox, but doesn't stores a value passed in it

my view contains
<div class="col-md-3 ">
#{
List<SelectListItem> deformitylevel = new List<SelectListItem>();
deformitylevel.Add(new SelectListItem { Value = "hip", Text = "Hip" });
deformitylevel.Add(new SelectListItem { Value = "knee", Text = "Knee" });
deformitylevel.Add(new SelectListItem { Value = "ankle", Text = "Ankle" });
deformitylevel.Add(new SelectListItem { Value = "other", Text = "Other" });
}
#Html.DropDownListFor(model => model.DeformityLevel, deformitylevel, "--Select Level -", new { #class = "form-control", #onchange = "showdeformitytextbox()", id = "deformitydropdown" })
#Html.ValidationMessageFor(model => model.DeformityLevel, "", new { #class = "text-danger" })
</div>
<div class="col-md-3">
#Html.EditorFor(model => model.DeformityLevel, new { htmlattributes = new { #class = "form-control", id = "deformitytextbox" ,style= "display:none"} })
</div>
My function is
function showdeformitytextbox() {
if ($("#deformitydropdown option:selected").text() == 'Other') {
$("#deformitytextbox").show();
}
else {
$("#deformitytextbox").hide();
}
}
When I select "Other" in dropdownlist it stores 'other' in the database instead of storing a value which is entered in #Html.EditorFor.
What I'm forgetting Help!!
As mentioned by others, to make this cleaner, it would be best if you separated the model fields for the drop down and the textbox. Even if you get it to work using the below code, it will lead to more work if you have to return to the page with the other value selected. That said, the following does properly submit the expected value in the textbox. The key concept is to set the dropdown to disabled as you submit.
Assuming your form has an id of submitForm specified as follows:
#using (Html.BeginForm("someActionName", "someControllerName", FormMethod.Post, new { #id="submitForm"}))
Then the following code will ensure that the drop down doesn't submit its value by intercepting the form submission:
$("#submitForm").submit(function () {
if ($("#deformitydropdown option:selected").text() === "Other") {
$("#deformitydropdown").attr("disabled", true);
} else {
$("#deformitydropdown").removeAttr("disabled");
}
});
I would change the names of your current controls and make a hidden form element for DeformityLevel. Then set its value in javascript based on DropdownList and textbox change events.
***Something like this (jq not verified, just for illustration)
<select id="DeformityLevel_DDL">
<option></option>
<option></option>
<option></option>
</select>
<input type="text" id="DeformityLevel_TB" />
<input type="hidden" id="DeformityLevel" name="DeformityLevel" />
<script>
$(document).ready(function () {
$('#DeformityLevel_DDL').change(function () {
if ($(this).val() != 'other') {
$('#DeformityLevel').val(this.val());
}
});
$('#DeformityLevel_TB').on('change', function () {
$('#DeformityLevel').val($(this).val());
});
});
</script>
Well, your function only display the #deformitytextbox input, when the value entered there changes you should also update the model property.
If the form submits automatically on select change you should use preventDefault.
Try now with TextBox, your parameter for htmlAttributes is incorrect. Try:
<div class="col-md-3 ">
#Html.DropDownList("DeformityLevel", deformitylevel, "--Select Level -", new { #class = "form-control", #onchange = "showdeformitytextbox()", id = "deformitydropdown" })
#Html.ValidationMessage("DeformityLevel", "", new { #class = "text-danger" })
</div>
<div class="col-md-3">
#Html.TextBox("DeformityLevel", null, new { #class = "form-control", id = "deformitytextbox", style = "display:none;" })
</div>
<script>
function showdeformitytextbox() {
if ($("#deformitydropdown option:selected").text() == 'Other') {
$("#deformitytextbox").show();
}
else {
$("#deformitytextbox").hide();
}
}
</script>

Dropdownlist onchanged - Trouble persisting ViewModel

I am a ASP.NET developer that is trying to get to grips with MVC.
I'm creating a register page and I have 3 dropdowns.
Now the first dropdown must load first go to load the countries. Based on that I load the provinces and then based on that I load the cities in that province.
The trouble I'm having is that on the first change it keeps my selected value but on the second onchange it seems as everything is lost.
I load the reigster view by just loading countries so long. then the javascript posts it to an action.
cshtml
<label class="col-md-3 col-xs-5 control-label">Country:</label>
<div class="col-md-9 col-xs-7">
#Html.DropDownListFor(x => x.CountryId, (IEnumerable<SelectListItem>)ViewBag.CountryItems, "Please Select", new { #class = "form-control select", #onchange = "CallChangefunc(this.value, null)" })
</div>
</div>
<div class="form-group">
<label class="col-md-3 col-xs-5 control-label">Province:</label>
<div class="col-md-9 col-xs-7">
#Html.DropDownListFor(x => x.ProvinceId, (IEnumerable<SelectListItem>)ViewBag.ProvinceItems, "Please Select", new { #class = "form-control select", #onchange = "CallChangefunc(null, this.value)" })
</div>
</div>
<div class="form-group">
<label class="col-md-3 col-xs-5 control-label">City:</label>
<div class="col-md-9 col-xs-7">
#Html.DropDownListFor(x => x.CityId, (IEnumerable<SelectListItem>)ViewBag.CityItems, "Please Select", new { #class = "form-control select" })
</div>
</div>
The javascript
function CallChangefunc(countryId, provinceId) {
window.location.href = "/Master/SetDropDowns?provinceId=" + provinceId + "&countryId=" + countryId ;
}
First one "Register" loads 1'st then SetDropDowns gets called onchanged.
I load the viewbags(SelectedItemLists) otherwise I get errors on refresh. is there a better way to code the viewbags to not have in two places?
[HttpGet]
public ActionResult Register()
{
IEnumerable<SelectListItem> CountryItems = BusinessAPI.CountryManager.GetAllCountries().Select(ci => new SelectListItem
{
Value = ci.Id.ToString(),
Text = ci.Name
});
ViewBag.CountryItems = CountryItems;
IEnumerable<SelectListItem> ProvinceItems = BusinessAPI.ProvinceManager.GetAllProvincesByCountryId(0).Select(ci => new SelectListItem
{
Value = ci.Id.ToString(),
Text = ci.Name
});
ViewBag.ProvinceItems = ProvinceItems;
IEnumerable<SelectListItem> CityItems = BusinessAPI.CityManager.GetAllCitiesByProvinceId(0).Select(ci => new SelectListItem
{
Value = ci.Id.ToString(),
Text = ci.Name
});
ViewBag.CityItems = CityItems;
return View();
}
public ActionResult SetDropDowns(string provinceId, string countryId)
{
IEnumerable<SelectListItem> CountryItems = BusinessAPI.CountryManager.GetAllCountries().Select(ci => new SelectListItem
{
Value = ci.Id.ToString(),
Text = ci.Name
});
ViewBag.CountryItems = CountryItems;
int countId = 0;
if (countryId == "null")
countryId = string.Empty;
if (TempData["CountryId"] == null)
{
if (!string.IsNullOrEmpty(countryId))
{
countId = Convert.ToInt32(countryId);
TempData["CountryId"] = countId;
}
}
else
countId = Convert.ToInt32(TempData["ProvinceId"]);
IEnumerable<SelectListItem> ProvinceItems = BusinessAPI.ProvinceManager.GetAllProvincesByCountryId(Convert.ToInt32(countId)).Select(ci => new SelectListItem
{
Value = ci.Id.ToString(),
Text = ci.Name
});
ViewBag.ProvinceItems = ProvinceItems;
int provId = 0;
if (provinceId == "null")
provinceId = string.Empty;
if (TempData["ProvinceId"] == null)
{
if (!string.IsNullOrEmpty(provinceId))
{
provId = Convert.ToInt32(provinceId);
TempData["ProvinceId"] = provId;
}
}
else
provId = Convert.ToInt32(TempData["ProvinceId"]);
IEnumerable<SelectListItem> CityItems = BusinessAPI.CityManager.GetAllCitiesByProvinceId(provId).Select(ci => new SelectListItem
{
Value = ci.Id.ToString(),
Text = ci.Name
});
ViewBag.CityItems = CityItems;
return View("Register");
}
The problem is that you don't tell them to be selected, modify your lists that have SelectListItem like the example below, to tell what item from list is Selected.
IEnumerable<SelectListItem> CountryItems = BusinessAPI.CountryManager.GetAllCountries().Select(ci => new SelectListItem
{
Value = ci.Id.ToString(),
Text = ci.Name,
Selected = ci.id.ToString() == countryId // if match the condition is selected
});
Also, to keep both listed selected you can modify your View.
Modify the javascript function to send always the countryId. Doing this the current country will be always selected, even when you change province.
function CallChangefunc(provinceId) {
var countries = document.getElementById("CountryId");
var countryId = countries.options[countries.selectedIndex].value;
window.location.href = "/Master/SetDropDowns?provinceId=" + provinceId + "&countryId=" + countryId ;
}
Notice that on first dropdown CallChangefunc(null), with this we tell that we don't have a province selected, which is true.
<div class="col-md-9 col-xs-7">
#Html.DropDownListFor(x => x.CountryId, (IEnumerable<SelectListItem>)ViewBag.CountryItems, "Please Select", new { #class = "form-control select", #onchange = "CallChangefunc(null)" })
</div>
On second dropdown we send CallChangefunc(this.value), with this we tell what province was selected to take cities and to keep the current value selected after postback. And because the countryId is always send it will remain unchanged.
<div class="col-md-9 col-xs-7">
#Html.DropDownListFor(x => x.ProvinceId, (IEnumerable<SelectListItem>)ViewBag.ProvinceItems, "Please Select", new { #class = "form-control select", #onchange = "CallChangefunc(this.value)" })
</div>

Categories