c# - Foolproof MVC 5 deppending validation -
grettings friends...
so have set of checkboxes set in model:
[displayname("páginas consultadas")] public list<checkboxes> paginasconsultadas { get; set; }
and have fieldtext ("paraqueusaestaspag") required if of checkboxes checked...
[displayname("¿para que usa esta(s) página(s)?")] public string paraqueusaestaspag { get; set; }
and part of view:
<div class="col-lg-4" id="divpagconsultadas"> <span>@html.labelfor(model => model.paginasconsultadas, @html.displaynamefor(model => model.paginasconsultadas))</span> @{ (int = 0; < model.paginasconsultadas.count(); i++) { <div class="checkbox"> <label> @html.checkboxfor(model => model.paginasconsultadas[i].valorcheckbox) @model.paginasconsultadas[i].nombrecheckbox </label> </div> @html.hiddenfor(model => model.paginasconsultadas[i].valorrespuesta, new { @value = @model.paginasconsultadas[i].valorrespuesta }) } } </div> </div> <br /> <div class="row"> <div class="col-lg-12"> @html.labelfor(model => model.paraqueusaestaspag, @html.displaynamefor(model => model.paraqueusaestaspag)) @html.textareafor(model => model.paraqueusaestaspag, 5, 1, new { @class = "form-control", placeholder = "esta pregunta se responde con base en la respuesta de la pregunta anterior" }) @html.validationmessagefor(model => model.paraqueusaestaspag) </div> </div> <br /> <div class="row"> <div class="col-lg-12"> <button type="submit" class="btn btn-default" onclick="dispararpleasewait()">enviar encuesta...</button> </div> </div>
there's mode using foolproof (i.e [requiredif])?
update: follow elad idea, class next:
public class pagseleccionadasvalidation : validationattribute, iclientvalidatable { //todo private readonly string _chkpagsel; public pagseleccionadasvalidation(string chkpagsel) { _chkpagsel = chkpagsel; } public string p {get; set;} protected override validationresult isvalid(object value, validationcontext validationcontext) { if (value == null) { var propertyinfo = validationcontext.objecttype.getproperty(_chkpagsel); var lista = (list<checkboxes>)propertyinfo.getvalue(validationcontext.objectinstance, null); bool hayalgunacheck = lista.any(r => r.valorcheckbox == true); if (hayalgunacheck) { return new validationresult(this.errormessagestring); } else { return validationresult.success; } } return validationresult.success; } public ienumerable<modelclientvalidationrule> getclientvalidationrules(modelmetadata metadata, controllercontext context) { var rule = new modelclientvalidationrule { errormessage = formaterrormessage(metadata.displayname), validationtype = "valpagselecc" }; rule.validationparameters["valpag"] = p; yield return rule; } }
in js called "js-valpagsel.js" put this:
$.validator.unobtrusive.adapters.addsingleval('valpagselecc', 'valpag'); $.validator.addmethod('valpagselecc', function (value, element, params) { //var checkvalue = [find element via jquery params.checkpropertinputname]; if (value) { return false; // test } else { return false; }
});
and in view:
<script src="/scripts/jquery-1.10.2.js"></script> <script src="/scripts/jquery.validate.js"></script> <script src="/scripts/jquery.validate.unobtrusive.min.js"></script> <script src="/scripts/bootstrap.js"></script> <script src="/scripts/respond.js"></script> <script src="/scripts/blur.js"></script> <script src="/scripts/jquery-ui-1.11.1.js"></script> <script src="/scripts/jquery.validate.js"></script> <script src="/scripts/jquery.validate.unobtrusive.js"></script> <script src="/scripts/custom/js-valpagsel.js"></script> <textarea class="form-control" cols="1" data-val="true" data-val-valpagselecc="el campo ¿para que usa esta(s) página(s)? no es válido." data-val-valpagselecc-valpag="" id="paraqueusaestaspag" name="paraqueusaestaspag" placeholder="esta pregunta se responde con base en la respuesta de la pregunta anterior" rows="5"></textarea>
what make field [required]
, in action
check if 1 of checkboxes checked. if not, can remove specific required error modelstate
before checking modelstate.isvalid
.
example:
if (model.mycheckbox.checked) { modelstate.remove("checkboxname"); } if(modelstate.isvalid) { //do stuff... }
since require client-side validation well, add option. can use custom data annotation. need create class inherits validationattribute
, implements iclientvalidatable
.
public class requiredif : validationattribute, iclientvalidatable { private string _checkpropertyname; public requiredif(string checkpropertyname) { _checkpropertyname = checkpropertyname; } protected override validationresult isvalid(object value, validationcontext validationcontext) { //get propertyinfo object var phonepropertyinfo = validationcontext.objecttype.getproperty(_checkpropertyname); //get value property bool checkvalue = (bool)phonepropertyinfo.getvalue(validationcontext.objectinstance, null); if(!checkvalue) return new validationresult(this.errormessagestring); return null; } public ienumerable<modelclientvalidationrule> getclientvalidationrules(modelmetadata metadata, controllercontext context) { modelclientvalidationrule rule = new modelclientvalidationrule(); rule.errormessage = this.errormessagestring; rule.validationtype = "requiredif"; rule.validationparameters.add("checkpropertinputname", _checkpropertyname); yield return rule; } }
this simplified example, can work along these lines. can pass in constructor , pull data model via reflection, in example.
on client side need js along these lines:
$.validator.unobtrusive.adapters.add('requiredif', ['checkpropertinputname'], function (options) { options.rules['requiredif'] = options.params; options.messages['requiredif'] = options.message; }); $.validator.addmethod('requiredif', function (value, element, params) { var checkvalue = *[find element via jquery params.checkpropertinputname]*; });
Comments
Post a Comment