RequiredIfTrue client side validation

Sep 3, 2012 at 10:54 AM
Edited Sep 3, 2012 at 10:57 AM

Hi.

Trying to user RequiredIfTrue, but can't seem to get the client side validation working.
My setup is as follows:

public class ViewModel
{
	public Event Event { get; set; }
}

public class Event
{
	[RequiredIfTrue("StartDateRequired"]
	public virtual DateTime? StartDate { get; set; }
	public bool StartDateRequired { get; set; }
}

@Html.EditorFor(viewModel => viewModel.Event.StartDate)
@Html.ValidationMessageFor(viewModel => viewModel.Event.StartDate)
@Html.HiddenFor(viewModel => m.Event.StartDateRequired)

and the generated html:

<input type="datetime" value="" name="Event.StartDate" id="Event_StartDate" data-val-requiredif-operator="EqualTo" data-val-requiredif-dependentvalue="True" data-val-requiredif-dependentproperty="StartDateRequired" data-val-requiredif="Startdatum måste anges." data-val-date="The field Startdatum: must be a date." data-val="true" class="text-box single-line">

<input type="hidden" value="True" name="Event.StartDateRequired" id="Event_StartDateRequired" data-val-required="The StartDateRequired field is required." data-val="true">

Submitting the form with the input empty does not give a client side validation message.
Server side validation works, though.

Then I noticed the 'data-val-requiredif-dependentproperty="StartDateRequired"'. To me it seems like this should be 'data-val-requiredif-dependentproperty="Event.StartDateRequired", but even if I change this using FireBug there's no validation message displayed.
I'm using MVC 4 and jQuery validation (jQuery version 1.7.2).

Coordinator
Sep 3, 2012 at 1:31 PM

At a quick glance, it looks like client-side script validation is broken in general for MVC 4. I'm fairly certain that would work fine in MVC 3.

I'll have to take some time to see what has changed in the MVC 4 script validation framework and figure out why it's breaking foolproof. 

Are you noticing that foolproof script validation isn't working at all in foolproof? Or is it working most places except for this one instance?

Sep 3, 2012 at 1:49 PM

This is the first and only thing I've tried out, so no more experience I'm afraid.

Sep 27, 2012 at 12:50 PM

Any progress on this issue?

Sure would like to use the stuff.

Coordinator
Sep 27, 2012 at 1:10 PM

Hi Rob, sorry for the delay. I think all you need is a validation message for your hidden input:

    @Html.EditorFor(viewModel => viewModel.Event.StartDate)
    @Html.ValidationMessageFor(viewModel => viewModel.Event.StartDate)
    @Html.HiddenFor(viewModel => viewModel.Event.StartDateRequired)
    @Html.ValidationMessageFor(model => model.Event.StartDateRequired)

Sep 27, 2012 at 5:05 PM

Doesn't help I'm afraid.
Still no client side validation.

Oct 9, 2012 at 3:54 PM

Excuse me while I butt in here.  I am having this same problem, but with MVC 3.  I believe it has to do with having my attributes and properties in a model that is passed to a view model, instead of having the attributes in the view model.  I have to do this because there are are many duplicate properties, like date, name, etc.  Is there some additional programming I need to do, to get it to work?

Example model:

using System.ComponentModel.DataAnnotations;
using Foolproof;

namespace EligibityForm.Models
{
    [MetadataType(typeof(RestrainingOrderMetadata))]
    public partial class RestrainingOrderData
    {
    }

    public class RestrainingOrderMetadata
    {
        [Display(Name = "Have you EVER had a stalking or restraining order placed against you?")]
        public bool EverHadRestrainingOrder { get; set; }


        [Display(Name = "Date of Order")]
        [RequiredIfTrue("EverHadRestrainingOrder")]
        public DateTime RestrainingOrderData.OrderDate { get; set; }

        [Display(Name = "State")]
        [RequiredIfTrue("EverHadRestrainingOrder")]
        public string ROState { get; set; }
        //public string County { get; set; }

        [Display(Name = "Name of Protected Party")]
        [RequiredIfTrue("EverHadRestrainingOrder")]
        public string ProtectedParties { get; set; }

        [StringLength(2000)]
        [Display(Name = "Explanation of Circumstances")]
        [RequiredIfTrue("EverHadRestrainingOrder")]
        public string Comments { get; set; }

    }

Example ViewModel:

using Foolproof;

namespace EligibityForm.Models.CompositeModels
{
    public class HistoryViewModel
    {
        public CivilCompromiseData CivilCompromiseModel { get; set; }
        public DiversionData DiversionDataModel { get; set; }
        //public Person PersonModel { get; set; }
        public PendingOffenseData PendingOffenseModel { get; set; }
        public FelonyData FelonyDataModel { get; set; }
        public ViolationData ViolationDataModel { get; set; }
        public History HistoryModel { get; set; }
        public IEnumerable<RestrainingOrderData> ROModel { get; set; }
        public RestrainingOrderData RestrainingOrderModel { get; set; }
        public Waiver WaiverModel { get; set; }

Nov 27, 2012 at 12:22 PM

Sorry to nag you, but will there be an update for MVC 4?

Coordinator
Nov 27, 2012 at 1:34 PM

Hey guys. I made a quick example project using Robelind's original example. The only thing I changed was adding a hidden input for the bool property like I mentioned before. Clientside seems validation works fine in MVC 4. Hope this helps:

https://dl.dropbox.com/u/73019/Examples/QuickTest.zip

 

Dec 5, 2013 at 10:24 PM
I'm downloading the sample now to check things out... but @nickriggs, have you looked into this at all when you have an EditorTemplate? e.g. if you had in /Views/Shared/EditorTemplates a *.cshtml file called Event.cshtml with the model being @model {Namespace}.Event?

I would expect the name, in this instance, to be Event.StartDate, but am only getting StartDate as the name.

Expectation: <input name="Event.StartDate" /> (the OP has a property on ViewModel called "Event", so it's {Property From Parent View Model}.{Property from Child ViewModel})
Actual: <input name="StartDate" />

the main validators are generating the parent property name of "Event" in this instance.