Custom HTML Helper for Validation Msg - razor

I wrote a custom HTTML Helper Tag for the output of Validation Messages. It works properly, however it is always present.
#Html.MyValidationMsg(m => m.FirstName)
public static IHtmlContent MyValidationMsg<TModel, TProperty>(this IHtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
{
MemberExpression memberExpression = expression.Body as MemberExpression;
var reqAttrib = memberExpression.Member
.GetCustomAttributes(typeof(RequiredAttribute), false)
.Cast<RequiredAttribute>()
.SingleOrDefault();
var displayAttrib = memberExpression.Member
.GetCustomAttributes(typeof(DisplayAttribute), false)
.Cast<DisplayAttribute>()
.SingleOrDefault();
var errMsg = reqAttrib.ErrorMessage ?? displayAttrib.Name + " is required.";
var content = new HtmlContentBuilder()
.AppendHtml("<div class=\"rvt-inline-alert rvt-inline-alert--standalone rvt-inline-alert--danger\">")
.AppendHtml("<span class=\"rvt-inline-alert__icon\">")
.AppendHtml("<svg aria-hidden=\"true\" xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\">")
.AppendHtml("<g fill=\"currentColor\">")
.AppendHtml("<path d=\"M8,0a8,8,0,1,0,8,8A8,8,0,0,0,8,0ZM8,14a6,6,0,1,1,6-6A6,6,0,0,1,8,14Z\" />")
.AppendHtml("<path d=\"M10.83,5.17a1,1,0,0,0-1.41,0L8,6.59,6.59,5.17A1,1,0,0,0,5.17,6.59L6.59,8,5.17,9.41a1,1,0,1,0,1.41,1.41L8,9.41l1.41,1.41a1,1,0,0,0,1.41-1.41L9.41,8l1.41-1.41A1,1,0,0,0,10.83,5.17Z\"/>")
.AppendHtml("</g>")
.AppendHtml("</svg>")
.AppendHtml("</span>")
.AppendHtml("<span class=\"rvt-inline-alert__message\" role=\"alert\" id=\"radio-list-message\">")
.AppendHtml(errMsg)
.AppendHtml("</span>")
.AppendHtml("</div>");
return content;
}
How would I hide it on initial load of the Razor Page and when the field is invalid make it appear?
Thank you for your help

There're two reason why the message always occurs.
As #Sonal Borkar said, the first reason is your var errMsg = reqAttrib.ErrorMessage ?? displayAttrib.Name + " is required." makes it return some value even if there's no [Required] attribute docorated at all.
But don't change it to be var errMsg = reqAttrib.ErrorMessage != null ? displayAttrib.Name + " is required.", because the reqAttrib might be null. Instead, you can change the code as below :
var errMsg = reqAttrib==null ?
"":
reqAttrib?.ErrorMessage ?? displayName + " is required.";
Secondly, you forgot to check whether the current property has already got a value. Suppose we have a property with a [Required] attribute decorated, and it does have a value assigned, then we should not display the required message like "xxx is requried".
Besides, there're some other bugs of null object reference in your code:
var displayAttrib = memberExpression.Member
.GetCustomAttributes(typeof(DisplayAttribute), false)
.Cast<DisplayAttribute>()
.SingleOrDefault();
var errMsg = reqAttrib.ErrorMessage ?? displayAttrib.Name + " is required.";
the reqAttrib might be null, so the reqAttrib.ErrorMessage might throw errors.
the displayAttrib might be null too
if displayAttrib is null, we should fall back tomemberExpression.Member.Name
To Fix the bugs, change your code as below :
public static IHtmlContent MyValidationMsg<TModel, TProperty>(this IHtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
{
MemberExpression memberExpression = expression.Body as MemberExpression;
var reqAttrib = memberExpression.Member
.GetCustomAttributes(typeof(RequiredAttribute), false)
.Cast<RequiredAttribute>()
.SingleOrDefault();
var contentBuilder = new HtmlContentBuilder();
// if the current property has no [Required] attribute, there's no need to display required message
if(reqAttrib == null ){return contentBuilder; }
// check the value of current property
var compiled = expression.Compile();
var model = (TModel) helper.ViewData.Model ;
if(model == null){
throw new Exception("No Model associated with the view !");
}
var propValue = (TProperty) compiled.Invoke(model);
// I just test nullable props here, you might custom it to fulfill your requirements, eg : whether the length of string matches
if(propValue != null){ return contentBuilder; }
var member = memberExpression.Member;
var displayName= member
.GetCustomAttributes(typeof(DisplayAttribute), false)
.Cast<DisplayAttribute>()
.SingleOrDefault()
?.Name // might be null
?? member.Name; // fall back
var errMsg = reqAttrib==null ?
"":
reqAttrib?.ErrorMessage ?? displayName + " is required.";
if(String.IsNullOrEmpty(errMsg)){ return contentBuilder; }
return contentBuilder
.AppendHtml("<div class=\"rvt-inline-alert rvt-inline-alert--standalone rvt-inline-alert--danger\">")
.AppendHtml("<span class=\"rvt-inline-alert__icon\">")
.AppendHtml("<svg aria-hidden=\"true\" xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\">")
.AppendHtml("<g fill=\"currentColor\">")
.AppendHtml("<path d=\"M8,0a8,8,0,1,0,8,8A8,8,0,0,0,8,0ZM8,14a6,6,0,1,1,6-6A6,6,0,0,1,8,14Z\" />")
.AppendHtml("<path d=\"M10.83,5.17a1,1,0,0,0-1.41,0L8,6.59,6.59,5.17A1,1,0,0,0,5.17,6.59L6.59,8,5.17,9.41a1,1,0,1,0,1.41,1.41L8,9.41l1.41,1.41a1,1,0,0,0,1.41-1.41L9.41,8l1.41-1.41A1,1,0,0,0,10.83,5.17Z\"/>")
.AppendHtml("</g>")
.AppendHtml("</svg>")
.AppendHtml("</span>")
.AppendHtml("<span class=\"rvt-inline-alert__message\" role=\"alert\" id=\"radio-list-message\">")
.AppendHtml(errMsg)
.AppendHtml("</span>")
.AppendHtml("</div>");
}

BIG THANKS to #itminus for taking the time to get me on the correct path.
I ended up scratching this path entirely in favor of overriding jquery.validate. Also manipulated the DOM with javascript / jquery to get the desired outcome.
Desired output for an error message:
<div class="rvt-inline-alert rvt-inline-alert--danger">
<span class="rvt-inline-alert__icon">
<svg width="16" height="16" viewBox="0 0 16 16" aria-hidden="true">
<g fill="currentColor">
<path d="M8,0a8,8,0,1,0,8,8A8,8,0,0,0,8,0ZM8,14a6,6,0,1,1,6-6A6,6,0,0,1,8,14Z"/>
<path d="M10.83,5.17a1,1,0,0,0-1.41,0L8,6.59,6.59,5.17A1,1,0,0,0,5.17,6.59L6.59,8,5.17,9.41a1,1,0,1,0,1.41,1.41L8,9.41l1.41,1.41a1,1,0,0,0,1.41-1.41L9.41,8l1.41-1.41A1,1,0,0,0,10.83,5.17Z"/>
</g>
</svg>
</span>
<span class="rvt-inline-alert__message" role="alert">Your Name is required.</span>
</div>
Code in _ValidationScriptsPartial.cshtml to do the magic:
<script type="text/javascript">
var settings = {
errorElement: "span",
errorClass: "rvt-validation-danger", //around textbox on error
errorPlacement: function (error, element) {
var avg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
avg.setAttribute("width", "16");
avg.setAttribute("height", "16");
avg.setAttribute("viewBox", "0 0 16 16");
avg.setAttribute("aria-hidden", "true");
var g = document.createElement("g");
g.setAttribute("fill", "currentColor");
var p1 = document.createElement("path");
p1.setAttribute("d", "M8,0a8,8,0,1,0,8,8A8,8,0,0,0,8,0ZM8,14a6,6,0,1,1,6-6A6,6,0,0,1,8,14Z");
var p2 = document.createElement("path");
p2.setAttribute("d", "M10.83,5.17a1,1,0,0,0-1.41,0L8,6.59,6.59,5.17A1,1,0,0,0,5.17,6.59L6.59,8,5.17,9.41a1,1,0,1,0,1.41,1.41L8,9.41l1.41,1.41a1,1,0,0,0,1.41-1.41L9.41,8l1.41-1.41A1,1,0,0,0,10.83,5.17Z");
g.appendChild(p1);
g.appendChild(p2);
avg.appendChild(g);
var spanIcon = document.createElement("span");
spanIcon.setAttribute("class", "rvt-inline-alert__icon");
spanIcon.innerHTML += avg.outerHTML;
var spanMsg = document.createElement("span");
spanMsg.setAttribute("class", "rvt-inline-alert__message");
spanMsg.setAttribute("role", "alert");
spanMsg.innerHTML += error[0].innerHTML;
var c = document.createElement("div");
c.setAttribute("class", "rvt-inline-alert rvt-inline-alert--danger");
c.innerHTML += spanIcon.outerHTML + spanMsg.outerHTML;
error.replaceWith(c);
}
};
$.validator.unobtrusive.options = settings;
</script>

Related

how can i change the html code in crm form?

I used dynamics CRM 2015 and i want to change the OptionSet type to checkboxs.
Just like this:
enter image description here
My solution is use JQuery get the td tag in crm form,and use html() change the td html code.
Like this $("#ubg_note_d").html().But question comes that i can't get the td tag which i want to display the checkbox.Only after i used the browser DEVELOPER TOOLS and select the element,then i can get the tag......i have blocked by this for 1 day,any helps?;)
note:i tried the js and jquery,both can't get the td tag.My code is run in the form Onload event,and i tried the filed Onchange event,trouble still there...
Thing you are trying to achieve is unsupported. Instead you can achieve the same using supported way by creating html web resource, which can be added on form on later.
Code for web resource is as below.
<html><head>
<title></title>
<script type="text/javascript" src="new_jquery_1.10.2.js"></script>
<script type="text/javascript">
// function will be called when web resource is loaded on Form.
$(document).ready(function () {
ConvertDropDownToCheckBoxList();
});
//Coverts option list to checkbox list.
function ConvertDropDownToCheckBoxList() {
var dropdownOptions = parent.Xrm.Page.getAttribute("new_makeyear").getOptions();
var selectedValue = parent.Xrm.Page.getAttribute("new_selectedyears").getValue();
$(dropdownOptions).each(function (i, e) {
var rText = $(this)[0].text;
var rvalue = $(this)[0].value;
var isChecked = false;
if (rText != '') {
if (selectedValue != null && selectedValue.indexOf(rvalue) != -1)
isChecked = true;
var checkbox = "< input type='checkbox' name='r' / >" + rText + ""
$(checkbox)
.attr("value", rvalue)
.attr("checked", isChecked)
.attr("id", "id" + rvalue)
.click(function () {
//To Set Picklist Select Values
var selectedOption = parent.Xrm.Page.getAttribute("new_selectedyears").getValue();
if (this.checked) {
if (selectedOption == null)
selectedOption = rvalue;
else
selectedOption = selectedOption + "," + rvalue
}
else {
var tempSelected = rvalue + ",";
if (selectedOption.indexOf(tempSelected) != -1)
selectedOption = selectedOption.replace(tempSelected, "");
else
selectedOption = selectedOption.replace(rvalue, "");
}
parent.Xrm.Page.getAttribute("new_selectedyears").setValue(selectedOption);
//To Set Picklist Select Text
var selectedYear = parent.Xrm.Page.getAttribute("new_selectedyeartext").getValue();
if (this.checked) {
if (selectedYear == null)
selectedYear = rText;
else
selectedYear = selectedYear + "," + rText
}
else {
var tempSelectedtext = rText + ",";
if (selectedYear.indexOf(tempSelectedtext) != -1)
selectedYear = selectedYear.replace(tempSelectedtext, "");
else
selectedYear = selectedYear.replace(rText, "");
}
parent.Xrm.Page.getAttribute("new_selectedyeartext").setValue(selectedYear);
})
.appendTo(checkboxList);
}
});
}
</script>
<meta charset="utf-8">
</head><body>
<div id="checkboxList">
</div>
</body></html>
Refer below given link for
enter link description here
No code needed for that. It's just configuration on CRM to change the display format : checkbox.

APNS - Node APN - payload - single quote

I am testing push notification using the node-apn module in node js. All works fine except that special characters such as a single quote does not properly escape. The push notification with a single quote (i.e. we'll becomes we\'ll in the actual notification). I tried regex, mongoose.toObject, message.message.toString() to no avail.
Message.findOne(query).lean().exec(function (err, doc){
if (!doc || doc == null) {
message.save(function(e) {
console.log("message saved")
if (e) {
console.log("there is an error")
console.log(e)
} else {
console.log(message.device_token)
var mesg = message.toObject();
var msg = JSON.stringify(mesg);
var payload = {
"contact" : message.contact,
"did" : message.did,
"id" : message.message_id,
"date" : message.date,
"message" : message.message
}
var clean = message.message.toString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
var note = new apns.Notification();
var myDevice = new apns.Device(message.device_token);
note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expires 1 hour from now.
note.badge = 3;
note.alert = message.message;
note.payload = payload;
apnsConnection.pushNotification(note, myDevice);
}
})
}
});
});
I solved this issue by escaping the json formmatted single quote (which was //') in the message.message value using the replace function:
var messageStringCleaned = message.message.toString().replace(/\\/g,"");
var payload = {
"contact" : message.contact,
"did" : message.did,
"id" : message.message_id,
"date" : message.date,
"message" : messageStringCleaned
}
var note = new apns.Notification();
var myDevice = new apns.Device(message.device_token);
note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expires 1 hour from now.
note.badge = 3;
note.alert = messageStringCleaned;
note.payload = payload;
apnsConnection.pushNotification(note, myDevice);

Parse URL (ActionScript 3.0)

I would like to know how would one parse an URL.
protocol://mydomain.com/something/morethings/this_is_what_i_want/even_if_it_has_slashes
I need to get "this_is_what_i_want/even_if_it_has_slashes"
How should I do this?
Thanks!
Try this :
var u:String = 'protocol://mydomain.com/something/morethings/this_is_what_i_want/even_if_it_has_slashes',
a:Array = u.split('/'),
s:String = ''
for(var i=0; i<a.length; i++){
if(i > 3){
s += '/'+a[i]
}
}
trace(s) // gives : /morethings/this_is_what_i_want/even_if_it_has_slashes
Another approach would be using Regex like this:
.*?mydomain\.com[^\/]*\/[^\/]+\/[^\/]+\/([^?]*)
(Breakdown of the components.)
This looks for a pattern where it skips whatever comes before the domain name (doesn't matter if the protocol is specified or not), skips the domain name + TLD, skips any port number, and skips the first two sub path elements. It then selects whatever comes after it but skips any query strings.
Example: http://regexr.com/39r69
In your code, you could use it like this:
var url:String = "protocol://mydomain.com/something/morethings/this_is_what_i_want/even_if_it_has_slashes";
var urlExp:RegExp = /.*?mydomain\.com[^\/]*\/[^\/]+\/[^\/]+\/([^?]*)/g;
var urlPart:Array = urlExp.exec(url);
if (urlPart.length > 1) {
trace(urlPart[1]);
// Prints "this_is_what_i_want/even_if_it_has_slashes"
} else {
// No matching part of the url found
}
As you can see on the regexr link above, this captures the part "this_is_what_i_want/even_if_it_has_slashes" for all of these variations of the url:
protocol://mydomain.com/something/morethings/this_is_what_i_want/even_if_it_has_slashes
protocol://mydomain.com:8080/something/morethings/this_is_what_i_want/even_if_it_has_slashes
protocol://mydomain.com/something/morethings/this_is_what_i_want/even_if_it_has_slashes.html
protocol://mydomain.com/something/morethings/this_is_what_i_want/even_if_it_has_slashes.html?hello=world
mydomain.com/something/morethings/this_is_what_i_want/even_if_it_has_slashes
protocol://subdomain.mydomain.com:8080/something/morethings/this_is_what_i_want/even_if_it_has_slashes
Edit: Fixed typo in regexp string
Simple way,
var file:String = 'protocol://mydomain.com/something/morethings/this_is_what_i_want/even_if_it_has_slashes';
var splitted:Array = file.split('/');
var str1:String = splitted.splice(3).join('/'); //returns 'something/morethings/this_is_what_i_want/even_if_it_has_slashes'
var str1:String = splitted.splice(5).join('/'); //returns 'this_is_what_i_want/even_if_it_has_slashes'
If you want to be a little more flexible in the feature (e.g. you need the domain), you can use my Url class.
Class for URL parsing
package
{
import flash.net.URLVariables;
public class Url
{
protected var protocol:String = "";
protected var domain:String = "";
protected var port:int = 0;
protected var path:String = "";
protected var parameters:URLVariables;
protected var bookmark:String = "";
public function Url(url:String)
{
this.init(url);
}
protected function splitSingle(value:String, c:String):Object
{
var temp:Object = {first: value, second: ""};
var pos:int = value.indexOf(c);
if (pos > 0)
{
temp.first = value.substring(0, pos);
temp.second = value.substring(pos + 1);
}
return temp;
}
protected function rtrim(value:String, c:String):String
{
while (value.substr(-1, 1) == c)
{
value = value.substr(0, -1);
}
return value;
}
protected function init(url:String):void
{
var o:Object;
var urlExp:RegExp = /([a-z]+):\/\/(.+)/
var urlPart:Array = urlExp.exec(url);
var temp:Array;
var rest:String;
if (urlPart.length <= 1)
{
throw new Error("invalid url");
}
this.protocol = urlPart[1];
rest = urlPart[2];
o = this.splitSingle(rest, "#");
this.bookmark = o.second;
rest = o.first;
o = this.splitSingle(rest, "?");
o.second = this.rtrim(o.second, "&");
this.parameters = new URLVariables();
if (o.second != "")
{
try
{
this.parameters.decode(o.second);
}
catch (e:Error)
{
trace("Warning: cannot decode URL parameters. " + e.message + " " + o.second);
}
}
rest = o.first
o = this.splitSingle(rest, "/");
if (o.second != "")
{
this.path = "/" + o.second;
}
rest = o.first;
o = this.splitSingle(rest, ":");
if (o.second != "")
{
this.port = parseInt(o.second);
}
else
{
switch (this.protocol)
{
case "https":
this.port = 443;
break;
case "http":
this.port = 80;
break;
case "ssh":
this.port = 22;
break;
case "ftp":
this.port = 21;
break;
default:
this.port = 0;
}
}
this.domain = o.first;
}
public function getDomain():String
{
return this.domain;
}
public function getProtocol():String
{
return this.protocol;
}
public function getPath():String
{
return this.path;
}
public function getPort():int
{
return this.port;
}
public function getBookmark():String
{
return this.bookmark;
}
public function getParameters():URLVariables
{
return this.parameters;
}
}
}
Example usage
try {
var myUrl:Url = new Url("protocol://mydomain.com/something/morethings/this_is_what_i_want/even_if_it_has_slashes");
trace("Protocol: " + myUrl.getProtocol());
trace("Domain: " + myUrl.getDomain());
trace("Path: " + myUrl.getPath());
trace("What you want: " + myUrl.getPath().split("/").splice(2).join("/") );
} catch (e:Error) {
trace("Warning: cannot parse url");
}
Output
Protocol: protocol
Domain: mydomain.com
Path: /something/morethings/this_is_what_i_want/even_if_it_has_slashes
What you want: morethings/this_is_what_i_want/even_if_it_has_slashes
Description
The init function checks with the regular expression if the given url starts with some letters (the protocol) followed by a colon, two slashes and more characters.
If the url contains a hash letter, everything behind its fist occurrence is taken as a bookmark
If the url contains a question mark, everything behind its fist occurrence is taken as key=value variables and parsed by the URLVariables class.
If the url contains a slash, everything behind its first occurrence is taken as the path
If the rest (everything between the last protocol slash and the first slash of the path) contains a colon, everything behind it will be converted to an integer and taken as the port. If the port is not set, a default will be set in dependency of the protocol
The rest is the domain
For answering your question, I use the path of the given url, split it by slash, cut of the 'something' and join it by slash.

Access array element by string in AS3

As we know its possible to access field by name using indexer.
var obj:* = {name:"Object 1"};
trace(obj["name"]); // "Object 1"
But how to access an array element by String?
var arr:Array = new Array();
var obj:* = {items:arr};
trace(obj["items[0]"]); // Undefined
Ok, basically you want to be able to have a string be interpreted as actionscript. No elegant solution I'm afraid. You could write a parser that handles some simple syntax in a string and retrieves the value.
Here's a simple example:
var obj:Object = {
items:[1, 2, 3],
subObj: {
subitems: [4, 5, 6]
}
};
trace(getValueInObject(obj, "items[0]")); // 1
trace(getValueInObject(obj, "subObj.subitems[2]")); // 6
// takes an object and a "path", and returns the value stored at the specified path.
// Handles dot syntax and []
function getValueInObject(obj : Object, pathToValue : String) : * {
pathToValue = pathToValue.replace(/\[/g, ".").replace(/]/g, "");
var pathFractions : Array = pathToValue.split(".");
var currentObject : Object = obj;
while (pathFractions.length > 0 && currentObject != null) {
var fraction : String = pathFractions.shift();
currentObject = currentObject[fraction];
}
if (currentObject != null) {
return currentObject;
}
return null;
}

Client-Side Validation for entire model using MVC 3 (unobtrusive ajax)

I've got client-side validation working for individual properties, however, I would like to validate at the model level (2 or more properties) using client-side validation.
I'm using #Html.ValidationSummary(true) to display the validation error for the Model attribute that I created.
However, when the model error is generated, it doesn't display a message. It prevents the action from being made, but no error is displayed.
Anybody know why this would be the case?
My hunch is that it has something to do with client-side validation since server-side doesn't work in this case since I have to use an Ajax form.
Any advice would be appreciated!
Model Attribute
public class AuditDetailValidatorAttribute : ValidationAttribute, IClientValidatable
{
public AuditDetailValidatorAttribute()
{
ErrorMessage = "Must select an NCN level...";
}
public override bool IsValid(object value)
{
AuditRequirementDetail audit = value as AuditRequirementDetail;
if (audit == null || audit.AuditResult.Id == 0 || audit.AssessmentLevel.Id == 0)
{
return true;
}
else
{
return !(audit.AuditResult.Id == 4 && audit.AssessmentLevel.Id == 1);
}
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
return new List<ModelClientValidationRule>
{
new ModelClientValidationRule
{
ValidationType = "required",
ErrorMessage = this.ErrorMessage
}
};
}
}
Model Class
[AuditDetailValidator]
public class AuditRequirementDetail
{
// Constructor
public AuditRequirementDetail()
{
// instantiate the contained objects on AuditRequirementDetail creation
AssessmentLevel = new AssessmentLevel();
AuditResult = new AuditResult();
Requirement = new RequirementDetail();
Attachment = new Attachment();
Counter = 0;
}
/* rest of the code */
}
View
#model pdiqc.Models.AuditRequirement.AuditRequirementDetail
#{
var SuccessTarget = "success" + Model.DetailID;
var IsValidTarget = "IsValid" + Model.DetailID;
var PerformCompletedTarget = "PerformCompleted" + Model.DetailID;
var AuditResultTarget = "AuditResult_Id" + Model.DetailID;
var AssessmentLevelTarget = "AssessmentLevel_Id" + Model.DetailID;
var DesignatorTarget = "Designator_Id" + Model.DetailID;
var EvidenceTarget = "Evidence_Id" + Model.DetailID;
var AttachmentTarget = "Attachments_Id" + Model.DetailID;
var AuditResultReferral = "#" + AuditResultTarget;
var AssessmentLevelReferral = "#" + AssessmentLevelTarget;
var DesignatorReferral = "#" + DesignatorTarget;
var EvidenceReferral = "#" + EvidenceTarget;
var AttachmentReferral = "#" + AttachmentTarget;
}
#using (Ajax.BeginForm("PerformRequirement", "Audit", new AjaxOptions { HttpMethod = "POST", OnSuccess = "success" }, new {Class="PerformReqForm" }))
{
#Html.ValidationSummary(true)
if ((Model.AuditResult.Id == 1 && Model.AssessmentLevel.Id > 1) || Model.Evidence == string.Empty || Model.Evidence == null)
{
<input class="#IsValidTarget" name="IsValid" type="hidden" value=false />
}
else
{
<input class="#IsValidTarget" name="IsValid" type="hidden" value=true />
}
<p class="reqText">#Model.RequirementLabel.ConfigurableLabelDesc ##ViewBag.PerformCounter - #ModelMetadata.FromLambdaExpression(x => x.Requirement.Text, ViewData).SimpleDisplayText</p>
<div class="hide">
/* REST OF CODE */
}
I wrote a custom validator for a checkbox to make sure it was cheeked and had to do the following.
<script type="text/javascript">
$(function() {
$.validator.unobtrusive.adapters.addBool('requiredcheckbox', 'required');
}(jQuery));
</script>
Also include #Html.ValidationMessageFor(x=>x.yourProp)