Client Side Validation Not Working With Foreign Keys - asp.net-mvc-3

Client side validation is not working for me for foreign keys only.
I have
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
included as well as
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
set in my web.config file.
There are no custom attributes or anything. It's something as simple as
[Required(ErrorMessage = "Fiscal year is required")]
[Display(Name = "Fiscal Year")]
public int FiscalYearId { get; set; }
Any ideas on this? I've searched for a solution, but all I have found are cases where it does not work at all and most solutions say to make sure the two above scripts are sourced and the two above keys are added to the web.conifg file.
I am getting no js errors and I have monitored with firebug. Everything appears to work perfectly, but it obviously is not.
Once I correct the non-foreign key fields and resubmit, data validations do work server side. This is an issue because it is creating a double validation and annoys the hell out of the users.
Help is much appreciated.
Below is the Html portion. It is contained in a using block. It's standard MVC3 generated CRUD code.
<div class="editor-label">
<label for="FiscalYearId">Fiscal Year</label>
</div>
<div class="editor-field">
<select id="FiscalYearId" name="FiscalYearId">
<option value="">---Select Fiscal Year---</option>
<option value="1">FY2013</option>
</select>
<span class="field-validation-valid" data-valmsg-for="FiscalYearId" data-valmsg-replace="true"></span>
</div>

I think there are no metadata attributes rendered in html. Try this in your view:
if (this.ViewContext.FormContext == null)
{
this.ViewContext.FormContext = new FormContext();
}

Related

Ajax.BeginForm doesn't fire AJAX script, falls back on postback

I will update this problem with the solution, I wanted to include my problem and solution as I wasn't able to find it on Stackoverflow. If you want to jump in with the solution, feel free.
I have a newly created 'Empty' MVC5 project created using Visual Studio 2013. I needed a from and wanted AJAX behavior if possible. Using Ajax.BeginForm was always straight-forward in MVC3 so I thought it would be in MVC5 also.
However none of the javascript functions I've specified in OnBegin, OnFailure or OnSuccess inside the AjaxOptions are invoked when I click the submit button. Instead an Ajaxless post is sent to the server, this has shown to be true by examining Request.IsAjaxRequest which returns false.
I have concluded that for some reason, then, ajax isn't being used at all. I've checked a number of things such as web.config, my layout scripts, etc.
My layout includes the following scripts:
<script src="~/Scripts/jquery-1.5.1.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
My web.config includes:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
</configuration>
My view:
#model ContactEnquiryViewModel
#{
AjaxOptions ContactOptions = new AjaxOptions()
{
OnBegin = "OnConactFormBegin()",
OnSuccess = "OnContactFormSuccess()",
OnFailure = "OnContactFormFailure()"
};
}
<div id="EnquiryFormContainer">
#using (Ajax.BeginForm("Contact", "Home", new { formName = "EnquiryForm" }, ContactOptions))
{
#Html.HiddenFor(m => m.Subject)
<div class="field">
#Html.LabelFor(m => m.FirstName)
#Html.TextBoxFor(m => m.FirstName)
<div class="validation">
#Html.ValidationMessageFor(m => m.FirstName)
</div>
</div>
<div class="field">
#Html.LabelFor(m => m.LastName)
#Html.TextBoxFor(m => m.LastName)
<div class="validation">
#Html.ValidationMessageFor(m => m.LastName)
</div>
</div>
<div class="field">
#Html.LabelFor(m => m.Email)
#Html.TextBoxFor(m => m.Email)
<div class="validation">
#Html.ValidationMessageFor(m => m.Email)
</div>
</div>
<div class="field">
#Html.LabelFor(m => m.PhoneNumber)
#Html.TextBoxFor(m => m.PhoneNumber)
<div class="validation">
#Html.ValidationMessageFor(m => m.PhoneNumber)
</div>
</div>
<div class="field">
#Html.LabelFor(m => m.Comments)
#Html.TextAreaFor(m => m.Comments)
<div class="validation">
#Html.ValidationMessageFor(m => m.Comments)
</div>
</div>
<div id="submitButtonContainer">
<input type="submit" value="Submit" name="submit" />
</div>
}
</div>
My controller action (unfinished):
[HttpPost]
public ActionResult Contact(ContactViewModel viewModel, String formName = "")
{
if (Request.IsAjaxRequest())
{
return new EmptyResult();
}
return new EmptyResult();
}
I have checked some other posts on this problem, and couldn't find a solution. Though some hinted at the possible solution, I was confused by the Microsoft CDN (http://www.asp.net/ajaxlibrary/cdn.ashx).
On the Microsoft CDN they have the following section:
The following ASP.NET MVC JavaScript files are hosted on this CDN:
ASP.NET MVC 5.0
http://ajax.aspnetcdn.com/ajax/mvc/5.0/jquery.validate.unobtrusive.js
http://ajax.aspnetcdn.com/ajax/mvc/5.0/jquery.validate.unobtrusive.min.js
ASP.NET MVC 4.0
http://ajax.aspnetcdn.com/ajax/mvc/4.0/jquery.validate.unobtrusive.js
http://ajax.aspnetcdn.com/ajax/mvc/4.0/jquery.validate.unobtrusive.min.js
ASP.NET MVC 3.0
http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.unobtrusive-ajax.js
http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.unobtrusive-ajax.min.js
http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.js
http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.min.js
http://ajax.aspnetcdn.com/ajax/mvc/3.0/MicrosoftMvcAjax.js
http://ajax.aspnetcdn.com/ajax/mvc/3.0/MicrosoftMvcAjax.debug.js
ASP.NET MVC 2.0
http://ajax.aspnetcdn.com/ajax/mvc/2.0/MicrosoftMvcAjax.js
http://ajax.aspnetcdn.com/ajax/mvc/2.0/MicrosoftMvcAjax.debug.js
ASP.NET MVC 1.0
http://ajax.aspnetcdn.com/ajax/mvc/1.0/MicrosoftMvcAjax.js
http://ajax.aspnetcdn.com/ajax/mvc/1.0/MicrosoftMvcAjax.debug.js
They would seem to suggest the only script you'll need for MVC5 is jquery.validate.unobtrusive.
To get a local copy as part of your MVC project"
From VS2013, right click on your MVC 5 project, select "Manage NuGet Packages".
Select "Online" and search for "jquery.unobtrusive-ajax",
Then Install "Microsoft.jQuery.Unobtrusive.Ajax".
I had the same issue on a dummy MVC5 project.
Add this to your BundleConfig
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.unobtrusive*",
"~/Scripts/jquery.validate*"));
Add this to your layout.cshtml
#Scripts.Render("~/bundles/jqueryval")
I didn't add any new files to my projects so if you have an MVC 4 or 5 web project, I doubt if you would need to add any extra js files.
It solved my issue. I hope it solves yours.
Everything has started working since I included the following script in my layout:
<script src="http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.unobtrusive-ajax.min.js"></script>
On the Microsoft CDN it looks as though this script is MVC3-specific.
Feel free to contribute better ways if possible, or answer the question: "Why isn't this script included in the MVC project template (VS2013)?"
Did you check if your web.config file contains
<appSettings>
<!-- this one is for client side validation -->
<add key="ClientValidationEnabled" value="true" />
<!-- this is for unobtrusive ajax -->
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
I had the same issue and the solution was actually to make sure that the script references are in the right order (specifically that #Scripts.Render("~/bundles/jquery") appears before #Scripts.Render("~/bundles/jqueryval"))
For some reason it wasn't like it by default when creating the new project and adding the nuget packages
Adding reference to the javascript file jquery.unobtrusive-ajax.js worked for me.
For me it was a little bit peculiar and counter-intuitive.
The page was displayed from the controller with a custom route attribute:
[Route("contact")]
[HttpGet]
public ActionResult Contact()
{
return this.View();
}
but the POST action handling the AjaxRequest had no [Route("contact")] attribute and that's why it didn't work.
For me it was the way i posted the form:
Changing Submit
Into <button type="submit" value="">Submit</button> solved my problem.

Why does my Ajax.BeginForm reload the entire page when I have specifically targeted an ID for replacement?

Apologies in advance for the question, but though I found numerous suggestions here, none have worked out for me. I'm feeling crazy, so...
I have an MVC 3 application that, when it first loads up, displays table with Model data for all users. That part works fine. I have two text boxes, one for account ID and another for user that allows me to requery the database for more specific user data. When I use the submit button, I get the data back but the entire page refreshes and, while I get the form and table back with the correct data, the rest of the page is white. No graphics I had previously or anything. Another interesting thing is that if i submit the form again, from the white page, with whatever valid parameters, the AJAX DOES work. I'm baffled.
The form looks like this:
#using (Ajax.BeginForm("TaskList", "Dispatch",
new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "tblBody",
InsertionMode = InsertionMode.Replace }, new { id = "frmTaskList" }))
{
<table id="tblTaskList" class="tblTaskList">
<thead>
<tr>
<th>Ticket ID</th>
<th>Date</th>
<th>Customer Name</th>
</tr>
</thead>
<tbody id="tblBody" class="tblBody">
#{for (var ix = 0; ix < Model.Value.Count - 1; ix++)
{
<tr id="#(Model.Value[ix].TicketId)">
<td>#Model.Value[ix].TicketId</td>
<td>#Model.Value[ix].Created</td>
<td>#Model.Value[ix].ContactName</td>
</tr>
}}
</tbody>
</table>
<input type="text" id="hidAccId" name="hidAccId" value="" />
<input type="text" id="hidUserId" name="hidUserId" value="" />
<input type="submit" id="btnTaskList" value="Submit" />
}
Also the scripts I'm using, placed at the top of the page:
<script src="../../Scripts/jquery-ui-1.8.11.min.js" type="text/javascript"></script>
<script src="../../Scripts/jquery-1.7.2.min.js" type="text/javascript"></script>
<script src="../../Scripts/jquery.unobtrusive-ajax.js" type="text/javascript"></script>
Side note: I have tried using #Url.Content instead of the src attribute to no avail. I've also experimented using the following, again with no different result:
<script src="#Url.Content("~/Scripts/MicrosoftAjax.js")" type="text/javascript"> </script>
<script src="#Url.Content("~/Scripts/MicrosoftMvcAjax.js")" type="text/javascript"></script>
You have jQuery and jQuery-ui referenced twice. It's not necessary. The following should be enough:
<script src="#Url.Content("~/Scripts/jquery-1.7.2.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery-ui-1.8.11.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
You obviously should ensure that jquery-1.7.2.min.js is present in the Scripts folder. Out of the box ASP.NET MVC 3 comes only with jQuery 1.5. As far as the Microsoft* scripts are concerned, forget about those, they are no longer used in ASP.NET MVC 3.
Also you don't have a submit button in your form.
This:
<input type="button" id="btnTaskList" value="Submit" />
should be:
<input type="submit" id="btnTaskList" value="Submit" />
if you expect a form submission to happen.

Ajax with partial view: getting complete postback

I have a view in which I am attempting to do an ajax call (using MVC Ajax support) and insert the returned partial view into a div on the page. As far as I can tell, what I'm doing is very by-the-book. But instead of an Ajax call and an updated div, I'm getting a full postback.
Here's the relevant chunk of the view:
<fieldset>
<legend>Available Instructors</legend>
<p>
#{ using (Ajax.BeginForm("InstructorSearch", "CourseSection", new AjaxOptions() { UpdateTargetId = "divSearchResult" }))
{
#Html.Raw(" Search: ")
<select id="SearchType" name="SearchType">
<option value="Last" #( (ViewBag.SearchType == "Last") ? " selected" : "")>Last Name</option>
<option value="First" #( (ViewBag.SearchType == "First") ? " selected" : "")>First Name</option>
</select>
#Html.Raw(" ")
<input type="text" id="SearchText" name="SearchText" value="#( ViewBag.SearchText)" />
#Html.Raw(" ")
<input type="submit" id="Search" name="Search" value="Search" />
}
}
</p>
<div id="divSearchResult"></div>
</fieldset>
Here's the method on the controller:
[HttpPost]
public PartialViewResult InstructorSearch(string searchType, string searchText)
{
var list = Services.InstructorService.ListInstructors(
base.CurrentOrganizationId.Value,
(searchType == "First") ? searchText : null,
(searchType == "Last") ? searchText : null,
0,
Properties.Settings.Default.InstructorListPageSize
);
return PartialView(list);
}
I've checked, and I'm loading MicrosoftAjax.js and MicrosoftMvcAjax.js.
So I'm stumped. I know that I can do all this in jQuery quite easily, and I've done that elsewhere, but this is a situation where, for reasons not worth getting into, if this could be made to work it would be the simplest, cleanest, easiest-to-understand solution.
I've checked, and I'm loading MicrosoftAjax.js and MicrosoftMvcAjax.js.
Those scripts are obsolete in ASP.NET MVC 3. You can completely remove them from your site. They are useless. They are included only for backwards compatibility if you were upgrading from previous versions in which case you must explicitly disable unobtrusive AJAX in your web.config:
<!-- Remark: don't do this => only for demonstration purposes -->
<add key="UnobtrusiveJavaScriptEnabled" value="false"/>
In ASP.NET MVC 3, Ajax.* helpers use jQuery by default. So must reference the jquery.unobtrusive-ajax.js which is what makes Ajax.* helpers work:
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>

How to pass data from viewbag to model in CSHTML

I'm having a hard time passing data to my model using viewbag.
Here is some example to enlighten you:
#model UCPBEscheatment.Models.aspnet_Membership
#{
ViewBag.Title = "AnswerForgotPassword";
}
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm())
{
<em style="font-size:small">#Html.ValidationSummary(true, "Forgot Password was unsuccessful. Please correct the errors and try again.")</em>
<fieldset style="background-color:#f0f0f0">
<legend> Forgot Password </legend>
<br />
• Second step: <em style="color:Teal"> Answer your secret question</em>
<br /><br />
<b> Secret Question:</b> #ViewBag.question
<br /><br />
<b> Secret Answer: </b>#Html.EditorFor(a => a.PasswordAnswer)
<br /><br />
#{
INPUT CODE HERE TO PASS A VALUE TO THE MODEL USING VIEWBAG LIKE:
ex.
#MODEL.USERID = VIEWBAG.USERID
}
<input type="submit" value="Submit" />
</fieldset>
}
It doesn't work that way. You can't assign to the model that is being returned in the post. I'd suggest adding the user's id to the form url and using the id on the url to find the user that needs the password secret validated.
#using (Html.BeginForm("validatepassword","account",new { id = ViewBag.UserID }))
{
...
}
Or better yet, set the user id on the model and use it from there instead of the ViewBag, but still using it in the url to post back.

JSP drop down list - using selected item

I have a drop down list and a form with a few textboxes. I would like to populate this form with details of selected item in the drop down list.
I'm doing this in java MVC app (or wannabe) and I have in my jsp page something like this:
<select name="item">
<c:forEach items="${persons}" var="selectedPerson">
<c:set var="person" value="${selectedPerson}" />
<option value="$selectedPerson.id">${selectedPerson.LastName}</option>
</c:forEach>
</select>
Persons is a list of the Person class.
I wonder is it possible to use the variable 'person' directly to fill the form, for example:
<textarea name="name" rows="1" cols="34" >
${selectedPerson.Name}
</textarea>
so that the rest of the form updates when the selectedPerson is changed?
I know how to do this within c#, but I don't have experience with java technologies.
Is it necessary to submit the form to servlet to do this, or it can be done on the client, since I have all my data in the persons list, from the moment of populating the drop down list?
The ${} syntax is JSP syntax, which will only be parsed and run once on the server to generate the HTML, and then sent down the wire as HTML. The changes to the select list then just happen in the client browser: the server doesn't know anything about them.
What you want to do is register a javascript listener on the select box. You should look into using a library ideally to help you do this. JQuery is a very popular solution and is worth reading up on if you're going to be doing this type of development.
If you end up using JQuery, you'll want to do something like the following
<select id="item" name="item">
<c:forEach items="${persons}" var="selectedPerson">
<c:set var="person" value="${selectedPerson}" />
<option value="$selectedPerson.id">${selectedPerson.LastName}</option>
</c:forEach>
</select>
<input name="lastName" id="lastName" type="text"/>
<script type="text/javascript">
$(function() {
$("#item").change(function() {
$("#lastName").val($("option:selected", this).text());
});
});
</script>
This will make more sense once you've read a basic JQuery tutorial, but basically what it does is that each time the select list changes value, it gets the selected option and sets it's content to the lastName input field. Hope this helps.

Resources