0

basically i am showing checkboxes in page and checkboxes generated in loop. i have create a custom validation using this ValidationAttribute, IClientValidatable

my server side validation working fine but client side is not firing. please have a look at my code and tell me where i made the mistake.

My Goal

i want user has to select one hobby means user has to select one check boxes out of many.

this way i am generating checkboxes

    <div class="col-md-offset-2 col-md-10">
        <b>Hobbies</b><br />
        @for (int x = 0; x < Model.Hobbies.Count(); x++)
        {
            @Html.CheckBoxFor(p => p.Hobbies[x].IsSelected) @: &nbsp; 
            @Html.LabelFor(p => p.Hobbies[x].IsSelected, Model.Hobbies[x].Name) @: &nbsp;
            @Html.HiddenFor(p => p.Hobbies[x].Name) 
        }
        @Html.ValidationMessageFor(model => model.Hobbies)
    </div>

this way i annotate my view model property

[AtleastOne(ErrorMessage = "Select at least one checkbox.")]
public List<Hobby> Hobbies { get; set; }

here is code for custom validation.

public class AtleastOneAttribute : ValidationAttribute, IClientValidatable
{
    // For Server side
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value != null)
        {
            var oHobby=value as IEnumerable;

            foreach (var _object in oHobby)
            {
                Hobby _oHobby = (Hobby)_object;
                if (_oHobby.IsSelected)
                {
                    return ValidationResult.Success;
                }
            }

        }
        return new ValidationResult(ErrorMessage);
    }
    // Implement IClientValidatable for client side Validation
    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
            ValidationType = "atleastonetrue",
        };
        yield return rule;
    }
}

client side code

<script type="text/javascript">

    $.validator.unobtrusive.adapters.add('atleastonetrue',  function (options) {
        //options.rules['restrictbackdates'] = { mindate: options.params.mindate };
        options.messages['atleastonetrue'] = options.message;
        alert('hello');
        alert(options.message);
    });

    $.validator.addMethod("atleastonetrue", function (value, element, param) {
        alert('hello');

        //var date = new Date(value);
        //var minDate = new Date(param.mindate);
        //return date >= minDate;
    });
</script>

where i made the mistake in my code for which client side code is not firing?

thanks

EDIT

Generated html for checkbox

<div class="col-md-offset-2 col-md-10">
                <b>Hobbies</b><br>
<input type="checkbox" value="true" name="Hobbies[0].IsSelected" id="Hobbies_0__IsSelected" data-val-required="The IsSelected field is required." data-val="true"><input type="hidden" value="false" name="Hobbies[0].IsSelected">  &nbsp; 
<label for="Hobbies_0__IsSelected">Reading</label>  &nbsp;
<input type="hidden" value="Reading" name="Hobbies[0].Name" id="Hobbies_0__Name"><span data-valmsg-replace="true" data-valmsg-for="Hobbies[0].IsSelected" class="field-validation-valid"></span><input type="checkbox" value="true" name="Hobbies[1].IsSelected" id="Hobbies_1__IsSelected" data-val-required="The IsSelected field is required." data-val="true"><input type="hidden" value="false" name="Hobbies[1].IsSelected">  &nbsp; 
<label for="Hobbies_1__IsSelected">Sports</label>  &nbsp;
<input type="hidden" value="Sports" name="Hobbies[1].Name" id="Hobbies_1__Name"><span data-valmsg-replace="true" data-valmsg-for="Hobbies[1].IsSelected" class="field-validation-valid"></span><input type="checkbox" value="true" name="Hobbies[2].IsSelected" id="Hobbies_2__IsSelected" data-val-required="The IsSelected field is required." data-val="true"><input type="hidden" value="false" name="Hobbies[2].IsSelected">  &nbsp; 
<label for="Hobbies_2__IsSelected">Movies</label>  &nbsp;
<input type="hidden" value="Movies" name="Hobbies[2].Name" id="Hobbies_2__Name"><span data-valmsg-replace="true" data-valmsg-for="Hobbies[2].IsSelected" class="field-validation-valid"></span>                
            </div>

My Model and ViewModel

  public class Product
    {
        public int ID { set; get; }
        public string Name { set; get; }
    }

    public class Hobby 
    {
        public string Name { get; set; }
        public bool IsSelected { get; set; }

    }

    public class SampleViewModel
    {
        [Display(Name = "Products")]
        public List<Product> Products { set; get; }

        [AtleastOne(ErrorMessage = "Select at least one checkbox.")]
        public List<Hobby> Hobbies { get; set; }

        [Required(ErrorMessage = "Select any Product")]
        public int SelectedProductId { set; get; }

        [Required(ErrorMessage = "Select Male or Female")]
        public string Gender { get; set; }
    }
Mou
  • 15,673
  • 43
  • 156
  • 275
  • 1
    Does the HTML that is generated include the expected data attributes associated with your validation? Other tips here: http://stackoverflow.com/questions/9245872/asp-net-mvc-3-custom-unobtrusive-validation – stephen.vakil Mar 25 '16 at 20:24
  • here i posted the generated html for check boxes. have a look please. – Mou Mar 25 '16 at 20:30
  • Doesn't seem to be emitting the expected validation attributes into the HTML. Why is it emitting `required` here? I don't see that in your code. – stephen.vakil Mar 25 '16 at 20:48
  • i debug and notice my `GetClientValidationRules()` is not invoking. can u tell me any reason why it is not firing? – Mou Mar 25 '16 at 20:53
  • Can you post the definition of `Hobby`? I suspect that it is not looking at the annotations for `Hobbies` because you are only ever creating checkboxes for a specific `Hobby` and so it doesn't think it needs to apply annotations that are on the `Hobbies` property. I also suspect that the `IsSelected` field is annotated as `[Required]` in the `Hobby` class, explaining why it's emitting the `data-val-required` ... but that's just a guess. – stephen.vakil Mar 25 '16 at 20:57
  • my model and viewmodel code posted. have a look. – Mou Mar 25 '16 at 20:58
  • i am working with MVC4 with VS2012 IDE. – Mou Mar 25 '16 at 21:05

0 Answers0