JavaScript Validation For TextBox - javascript

I want validation for textbox and textbox is list type so how to validate using JavaScript?
I need the following validation:
Textbox should not be empty, no duplication
Given below is my code
#model List
#using (Html.BeginForm("CreateCategory", "CategoryAndSubCategory", FormMethod.Post, new { enctype = "multipart/form-data", #id = "category" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.Label("Category Name", htmlAttributes: new { #class = "control-label col-md-2 required" })
#Html.EditorFor(a => a[j].Category, new { #class = "form-control", #placeholder = "Enter Category Name", #style = "text-transform: capitalize" })
#Html.ValidationMessageFor(a => a[j].Category, "", new { #class = "text-danger" })
}

Related

Custom Client Side Validation through JavaScript

I am developing a project in MVC 5. There is are some form input field where I need to put custom client side validation using jquery/javascript. The expected behaviour is for example when someone tries to type alphabets or special characters in the phone input, there should be a validation error displayed below the field or atleast an alert box should get triggered containing the error. I have added the custom validation file in my scripts folder. I can see some basic logs I wrote on the console of the page. I am facing challenges on the js function where we can capture the id of the field and provide custom logic for it. Here is my code. Please suggest what can be done.
#model StudentMVCApp.Models.registration
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm(new
{
#id = "registerFormId",
#class = "form-horizontal",
role = "form"
}))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Register a new student</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.firstname, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.firstname, new { htmlAttributes = new { #class = "form-control", data_val = "true", data_val_required = "Please dont provide empty name!" } })
#Html.ValidationMessageFor(model => model.firstname, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.lastname, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.lastname, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.lastname, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.phone, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.phone, new { htmlAttributes = new { #class = "form-control",#id="phoneid" } })
#Html.ValidationMessageFor(model => model.phone, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.email, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.email, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jqueryval")
#Scripts.Render("~/Unobtrusive")
#Scripts.Render("~/CustomValidation")
}
Here is my Custom JavaScript
console.log("I am working JS");
(function ($) {
console.log("This function is captured");
var phone = $("#phoneid").val();
console.log(phone);
if (phone != null)
console.log(phone);
else if (phone == 100)
alert($(this).val());
else if (phone == "abc")
alert(phone);
else if (phone == abc)
alert(phone)
})(jQuery);
I tried different tutorials and experimented with some js functions. But couldn't get it working using id of the field.
I would recommend using jquery.validation.unobstrusive package scripts on your view:
<script src="~/Scripts/Jquery/jquery-1.9.1.js"></script>
<script src="~/Scripts/Jquery/jquery.validate.js"></script>
<script src="~/Scripts/Jquery/jquery.validate.unobtrusive.js"></script>
and adding your own custom validation on a form element by writing jquery such as:
$("#myinput").rules("add", {
required: true,
minlength: 2,
messages: {
required: "Required input",
minlength: jQuery.validator.format("Field needs to be more than{0}")
}
});
More info can be found at https://jqueryvalidation.org/rules/
You need to attach your code above to an event, input or submit for example.
Now it only runs once, when the page loads
something like
$(function() {
console.log("This function is captured");
const $phone = $('#phoneid');
$phone.on('input',function() {
const val = $(this).val(); // get the value - it is a string
console.log(val);
if (val == 100) console.log('100'); // note the == coerces the numeric string to number
else if (phone == 'abc') console.log('abc');
});
});

Unable to post data to controller's action method using Ajax call

I am trying to Post a Partial View's data to the server to save the input fields result to database and then return back to the same (partial view which is open as a modal dialog) or return to the parent view which called the modal dialog.
But for some reason, I am not getting the Action method's parameter (i.e. weldMaster) in the Controller which is being sent from the ajax method call.
Here is my controller method.
// GET: WeldMasters/Details/5
public ActionResult Details(int? ids, bool isPartials = false)
{
if (ids == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
WeldMaster weldMaster = db.WeldMasters.Find(ids);
ViewBag.Readonly = false;
if (weldMaster == null)
{
return HttpNotFound();
}
if(isPartials)
return PartialView(weldMaster);
else
return View(weldMaster);
}
// POST: WeldMasters/Details/5
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult Details**(WeldMaster weldMaster)**
//{"The parameter conversion from type 'System.String' to type 'IMCC_PAS.Entities.WeldMaster' failed because no type converter can convert between these types."}
{
var success = 0;
if (ModelState.IsValid)
{
success = 1;
db.Entry(weldMaster).State = EntityState.Modified;
db.SaveChanges();
return Json(new { success });
}
return Json(new { success });
}
Here is the ajax code
<script type="text/javascript">
$(document).ready(function () {
$(".saveBtn").click(function (e) {
debugger;
var token = $('input[name="__RequestVerificationToken"]').val();
// If I dont pass the token in the `data` parameter of ajax, then action method of controller is not called at all.
e.preventDefault();
$.ajax({
type: "POST",
url: '#Url.Action("Details", "WeldMasters")',
data: { __RequestVerificationToken: token, weldMaster: $('#__AjaxAntiForgeryForm').serialize() },
success: function (result) {
alert(result);
},
failure: function (response) {
alert(result.responseText);
},
error: function (response) {
alert(result.responseText);
}
});
});
});
</script>
Here is the modal for the partial view
#model IMCC_PAS.Entities.WeldMaster
and here is the form
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.id)
<div class="row">
<div class="col-md-3 col-sm-12">
#Html.LabelFor(model => model.weld_no, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-3 col-sm-12">
#Html.LabelFor(model => model.rep_no, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-3 col-sm-12">
#Html.LabelFor(model => model.length, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-3 col-sm-12">
#Html.LabelFor(model => model.normal_size, htmlAttributes: new { #class = "control-label" })
</div>
</div>
<div class="row">
<div class="col-md-3 col-sm-12">
#Html.EditorFor(model => model.weld_no, ViewBag.Readonly ? (object)new { htmlAttributes = new { #readonly = "readonly", #class = "form-control" } } : new { htmlAttributes = new { #class = "form-control" } })
</div>
<div class="col-md-3 col-sm-12">
#Html.EditorFor(model => model.rep_no, ViewBag.Readonly ? (object)new { htmlAttributes = new { #readonly = "readonly", #class = "form-control" } } : new { htmlAttributes = new { #class = "form-control" } })
</div>
<div class="col-md-3 col-sm-12">
#Html.EditorFor(model => model.length, ViewBag.Readonly ? (object)new { htmlAttributes = new { #readonly = "readonly", #class = "form-control" } } : new { htmlAttributes = new { #class = "form-control" } })
</div>
<div class="col-md-3 col-sm-12">
#Html.EditorFor(model => model.normal_size, ViewBag.Readonly ? (object)new { htmlAttributes = new { #readonly = "readonly", #class = "form-control" } } : new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group modal-footer">
<div class="col-md-12">
<a class="saveBtn" href="javascript:void(0);">Edit</a>
</div>
</div>
</div>
}
EDIT: Here is the parent view which has the selection parameters for showing the weld details. And then Weld details are shown in a div (for readonly purpose) and can be edited in a popup modal dialog on a button click.
<script>
$(document).ready(function () {
... more code for other dropdowns here
//When Wled No is changed, reload Weld Details in its respective Partial view
$("#weldddl").change(function () {
var parameter = { ids: $("#weldddl").val(), isPartials: true };
$.ajax({
url: '/WeldMasters/Details/',
type: 'GET',
data: parameter,
success: function (result) {
var div = $('#weldDetails');
div.html('');
div.html(result);
}
});
});
$(".editWeldBtn").click(function () {
//debugger;
$('#MyModal').empty();
$('#MyModal').append(GetModalDialog());
var link = '#Url.Action("Details", "WeldMasters")';
data = { ids: $("#weldddl").val(), isPartials: true };
LaunchModalDlg(link, data, "View Weld Master Information", "75%");
});
});
</script>
<h4>Index</h4>
<script src="~/Scripts/MyScripts.js"></script>
<p>
#Html.ActionLink("Create New", "Create") |
<a class="editWeldBtn" href="javascript:void(0);">Edit</a>
</p>
<div class="row">
<div class="col-sm-3">
#Html.LabelFor(model => model.Discipline, htmlAttributes: new { #class = "control-label col-md-12" })
<div class="col-md-12">
#Html.DropDownListFor(model => model.Discipline, (SelectList)ViewBag.disciplines, htmlAttributes: new { #class = "form-control", #id = "disciplineddl" })
#Html.ValidationMessageFor(model => model.Discipline, "", new { #class = "text-danger" })
</div>
#Html.LabelFor(model => model.DrawingNo, htmlAttributes: new { #class = "control-label col-md-12" })
<div class="col-md-12">
#Html.DropDownListFor(model => model.DrawingNo, (SelectList)ViewBag.drawings, htmlAttributes: new { #class = "form-control", #id = "drawingddl" })
#Html.ValidationMessageFor(model => model.DrawingNo, "", new { #class = "text-danger" })
</div>
#Html.LabelFor(model => model.ComponentNo, htmlAttributes: new { #class = "control-label col-md-12" })
<div class="col-md-12">
#Html.DropDownListFor(model => model.ComponentNo, (SelectList)ViewBag.components, htmlAttributes: new { #class = "form-control", #id = "componentddl" })
#Html.ValidationMessageFor(model => model.ComponentNo, "", new { #class = "text-danger" })
</div>
#Html.LabelFor(model => model.WeldNo, htmlAttributes: new { #class = "control-label col-md-12" })
<div class="col-md-12">
#Html.DropDownListFor(model => model.WeldNo, (SelectList)ViewBag.components, htmlAttributes: new { #class = "form-control", #id = "weldddl" })
#Html.ValidationMessageFor(model => model.WeldNo, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-sm-9" id="weldDetails"> <!--This is for showing the partial view for showing weld details-->
</div>
<div id="MyModal"></div> <!--This is for pop up modal dialog-->
</div>
If you are serializing the full form then you don't need to send explicitly anti forgery token.
use this:
data: $('#__AjaxAntiForgeryForm').serialize(),

How to pass data from a form to my controller, and then back to my client-side javascript?

I have a form in my webpage that asks for first and last name. When the user submits this form I would like the data to be passed to a function in my controller, where it is used to find the corresponding user in our Active Directory. I want to then return the matching Email address to a Javascript function, when then displays that information on my page. Is this the "correct" way to go about doing this, and if yes, how would I structure a function in my controller to accept form input, and return data to my client side javascript?
What I have so far in my controller:
public SearchResult[] searchAD(String fname, String lname)
{
Func<System.DirectoryServices.ActiveDirectory.Domain> domain = System.DirectoryServices.ActiveDirectory.Domain.GetCurrentDomain;
System.DirectoryServices.DirectoryEntry root = new DirectoryEntry("LDAP://"+domain);
DirectorySearcher searcher = new DirectorySearcher();
searcher.SearchRoot = root;
searcher.SearchScope = SearchScope.Subtree;
searcher.Filter = string.Format("(&(objectCategory=person)(objectClass=user)(givenName={0})(sn={1}))", fname, lname);
SearchResult[] results = new SearchResult['a'];
searcher.FindAll().CopyTo(results, 0);
return results;
}
And my form:
#using (Html.BeginForm("searchAD", "AD", FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(m => m.firstName, "First Name", htmlAttributes: new { #class = "control-label" })
<div>
#Html.EditorFor(model => model.firstName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.firstName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.lastName, "Last Name", htmlAttributes: new { #class = "control-label" })
<div>
#Html.EditorFor(model => model.lastName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.lastName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div>
<input type="submit" value="Search" class="btn" />
</div>
</div>
}
You can Store value in TempData and get it on view
public ActionResult searchAD(String fname, String lname)
{
Func<System.DirectoryServices.ActiveDirectory.Domain> domain = System.DirectoryServices.ActiveDirectory.Domain.GetCurrentDomain;
System.DirectoryServices.DirectoryEntry root = new DirectoryEntry("LDAP://"+domain);
DirectorySearcher searcher = new DirectorySearcher();
searcher.SearchRoot = root;
searcher.SearchScope = SearchScope.Subtree;
searcher.Filter = string.Format("(&(objectCategory=person)(objectClass=user)(givenName={0})(sn={1}))", fname, lname);
SearchResult[] results = new SearchResult['a'];
searcher.FindAll().CopyTo(results, 0);
TempData["Result"]=results;
return View("ViewName");
}
In View (Jquery)
$(function(){
if ('#TempData["Result"]' != '')
{
// call your function here and pass TempData Value
}
});
Above is not perfect solution for your posted issue because tempdata or viewbag are not meant for that.If you need to post data again back from control to view then its always make use of #Ajax.BeginForm
#using (Ajax.BeginForm("ActionName", "Controller", new AjaxOptions { OnComplete = "Sucess" }))
in jquery you have to write Success function like below :
function Sucess(arg) {
//arg.data
}
in arg.data you will get that object what you are passing from controller.More ever #Html.BeginForm refreshing your whole page not specific content but with With Ajax.begin form you can manage to reload only those content which is under ajax.begin form.

MVC - jQuery validation does not work on dynamically added elements

I know this kind of issue has been solved many times already, however I am unable to get mine fixed based on solutions provided.
I am building a simple library application. There is a feature to add a copy of a book, which uses jQuery to invoke controller actions and return partial views which are then added dynamically to the DOM.
The last dynamically element added is a form with additional details of a created copy. The ajax call is being triggered when a value of a DropDownList (#AuthorBooksDropDown) (also added dynamically) changes.
$('#authorBooksPlaceHolder').on('change', '#AuthorBooksDropDown', function () {
var bookId = $(this).val();
$.get('/Books/AddCopy_RenderDetails/' + bookId, function (data) {
$('#bookDetailsPlaceHolder').html(data);
$('#bookDetailsPlaceHolder').slideDown();
});
$.validator.unobtrusive.parse('#addCopyForm');
});
The call invoked the AddCopy_RenderDetails action get an entity from a DB based on book id, and creates a new copy with certain fields populated.
Controller action:
public PartialViewResult AddCopy_RenderDetails(int id)
{
var book = db.LibraryBooks.Find(id);
var newCopy = new Book()
{
Author = book.Author,
Title = book.Title,
Publisher = book.Publisher,
CollectionId = book.CollectionId,
Collection = book.Collection
};
return PartialView("_AddCopy_Details", newCopy);
}
The view displays remaining fields which need to be populated.
#model CityLibrary.Models.Library.Book
<div class="vertical-separator"></div>
<hr />
#using (Ajax.BeginForm("AddCopy", "Books", new AjaxOptions
{
UpdateTargetId = "bookDetailsPlaceHolder"
}, new { #id = "addCopyForm" }))
{
#Html.AntiForgeryToken()
#Html.HiddenFor(model => model.Author)
#Html.HiddenFor(model => model.Title)
#Html.HiddenFor(model => model.CollectionId)
#Html.HiddenFor(model => model.Collection.Name)
#Html.HiddenFor(model => model.Publisher)
<div class="form-group">
#Html.LabelFor(model => model.Collection.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Collection.Name, new { htmlAttributes = new { #class = "form-control", #disabled = "" } })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ISBN, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ISBN, new { htmlAttributes = new { #class = "form-control", } })
#Html.ValidationMessageFor(model => model.ISBN, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Publisher, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Publisher, new { htmlAttributes = new { #class = "form-control", #disabled = "disabled" } })
#Html.ValidationMessageFor(model => model.Publisher, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.YearPrinted, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.YearPrinted, new { htmlAttributes = new { #class = "form-control", #Value = "" } })
#Html.ValidationMessageFor(model => model.YearPrinted, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-success btn-block" />
</div>
</div>
}
Even though I have $.validator.unobtrusive.parse('#addCopyForm'); invoked when the form is rendered (checked in chrome dev tools), validation still happens on the server side upon pressing a submit button as a POST action is being triggered every time. Not to mention that validation errors do not display upon TABing to next field.
Validation attributes are there in form's inputs:
I also have remote validation which checks whether a entered ISBN is already in the database. Obviously this works on the client side, which in my case simply does not.
Thank you for your time and help.
EDIT:
Well, I've added the following to the end of the view:
<script>
$.validator.unobtrusive.parse('#addCopyForm');
</script>
And it works. I have no idea why triggering it on a function does nothing.
Ajax is async, and your $.validator.unobtrusive.parse('#addCopyForm'); line of code is being called before the html has been added to the DOM. Move it to inside the success callback
$.get('/Books/AddCopy_RenderDetails/' + bookId, function (data) {
$('#bookDetailsPlaceHolder').html(data);
$('#bookDetailsPlaceHolder').slideDown();
$.validator.unobtrusive.parse('#addCopyForm');
});
Try this peace of code
$("form").on("submit", function (e) {
e.preventDefault();
$.validator.unobtrusive.parse($('#addCopyForm')); // here you need define your form id
if ($(this).valid()) // use to validate the form
{
//do ajax call
$.ajax({
type: "Post",
url: "/Books/AddCopy_RenderDetails/" + bookId,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
}
});
}
});

how to set id to Html.TextBox item on MVC

Im trying to catch the textbox element by javascript, in order to put text into it.
so how to set id to the textbox ??
<tr>
// Id to this textbox
<td>#Html.TextBoxFor(item => item.OperationNo)</td>
</tr>
and then to put text into it by JS
//
document.getElementById("Textbox id").Text= " Some text " ;
You can set ID of a textbox like this.
#Html.TextBoxFor(item => item.OperationNo, new { id = "MyId" })
OR
#Html.TextBoxFor(item => item.OperationNo, htmlAttributes: new { id = "MyId" })
Output:
<input ... id="MyId" name="OperationNo" type="text" />
You can use below code for resolve that problem:
function steVal() {
document.getElementById('txtPlace').value = "Set The Text";
}
#Html.TextBoxFor(m => m.OperationNo,new { #id = "txtPlace",#name="txtPlace" })
It should be the property name, which is OperationNo.
So your JS will be
document.getElementById("OperationNo").html = " Some text " ;
You can use the web inspector in Chrome or JS to view the html on your page to see the element attributes.
This is happens in a scenario of using same input fields with same properties in web form. Like the case of Login and Signup forms in single view/page.
Previously it was like this
input one >
<div class="field-wrap">
#Html.TextBoxFor(model => model.Username, new { #class = "form-control",placeholder = "Username", #required = "required", autofocus = "" })
#Html.ValidationMessageFor(model => model.Username, "", new { #class = "text-danger" })
</div>
input two>
<div class="field-wrap">
#Html.TextBoxFor(model => model.Username, new { #class = "form-control", placeholder = "Username", #required = "required", autofocus = "" })
#Html.ValidationMessageFor(model => model.Username, "", new { #class = "text-danger" })
</div>
then i added a unique id # for the username input
the new input one >
<div class="field-wrap">
#Html.TextBoxFor(model => model.Username, new { #class = "form-control", id = "loginUsername", placeholder = "Username", #required = "required", autofocus = "" })
#Html.ValidationMessageFor(model => model.Username, "", new { #class = "text-danger" })
</div>
the new input two >
<div class="field-wrap">
#Html.TextBoxFor(model => model.Username, new { #class = "form-control", id = "SignupUsername" , placeholder = "Username", #required = "required", autofocus = "" })
#Html.ValidationMessageFor(model => model.Username, "", new { #class = "text-danger" })
</div>

Categories