I have saved a couple of code snippets lately and just wanted to add them to the blog too. This one enables “focus out” unobtrusive validation. I use this in a couple of forms on the site. Part of this gist also has a little code where I was messing around with “remote” validation to get it to work with the focus out validation – of course, I wasn’t thinking, just geeking out. The remote stuff is already baked in to jquery validation and I already had code to handle the focus out portion, so it wasn’t really worth the time, but I didn’t spend much on it. Anyway, the code:
window.Em = window.Em || {};
Em = {
setFocusOutValidation: function (form) {
var s = $.data(form, "validator").settings;
s.onfocusout = function (element) {
if ($(element).val().length > 0) {
$(element).valid();
}
};
s.showErrors = function (map, list) {
this.defaultShowErrors();
if (list && list.length > 0) {
for (prop in map) {
$("#" + prop).focus();
}
}
Em.displayValidationSummaryErrors(list);
};
return s;
},
displayValidationSummaryErrors: function (list) {
$("[data-valmsg-summary]")
.removeClass("validation-summary-valid")
.addClass("validation-summary-errors");
$("[data-valmsg-summary] ul").html("");
$.each(list, function (idx, data) {
$("[data-valmsg-summary] ul").append($("<li></li>")
.html(data.message));
});
}
}
The focus out validation will check if the field is valid (also remotely) and if not, the focus will stay on the invalid field. Sometimes it can get a little wonky, but for the most part it works well. Typically when it doesn’t seem to “work” it is because the validation is setup backwards, like comparing a “new password” to the “confirm password”, rather than the other way around.
Gist
The next gist is a Telerik MVC grid extension I started messing with to handle filtering. Turns out I was making it harder than necessary, and there was already an extension method in the NopCommerce codebase. Oh well, here it is anyway:
public static IList<T> ApplyFilter<T>(this IList<T> list,
FilterDescriptor filter) {
// We wont allow filtering on anything but string type properties
if (filter.MemberType != typeof(string))
throw new ArgumentException(@"Filtering is only allowed
for properties with a type of 'string'.");
var value = filter.Value.ToString();
switch (filter.Operator) {
case FilterOperator.IsEqualTo:
list = list.Where(x => {
var propertyValue = x.GetType()
.GetProperty(filter.Member)
.GetValue(x, null);
return String.Equals((string)propertyValue, value,
StringComparison.InvariantCultureIgnoreCase);
}).ToList();
break;
case FilterOperator.IsNotEqualTo:
list = list.Where(x => {
var propertyValue = x.GetType()
.GetProperty(filter.Member).GetValue(x, null);
return String.Equals((string)propertyValue, value,
StringComparison.InvariantCultureIgnoreCase) == false;
}).ToList();
break;
case FilterOperator.StartsWith:
list = list.Where(x => {
var propertyValue = x.GetType()
.GetProperty(filter.Member).GetValue(x, null);
return ((string)propertyValue).StartsWith(value,
StringComparison.InvariantCultureIgnoreCase);
}).ToList();
break;
case FilterOperator.Contains:
list = list.Where(x => {
var propertyValue = x.GetType()
.GetProperty(filter.Member).GetValue(x, null);
return ((string)propertyValue).IndexOf(value,
StringComparison.InvariantCultureIgnoreCase) > -1;
}).ToList();
break;
case FilterOperator.EndsWith:
list = list.Where(x => {
var propertyValue = x.GetType()
.GetProperty(filter.Member).GetValue(x, null);
return ((string)propertyValue).EndsWith(value,
StringComparison.InvariantCultureIgnoreCase);
}).ToList();
break;
}
return list;
}
Gist
The last one is just a little quickie example of how to select data attributes with jQuery:
var d = $("input[data-toggle-class]");
$.each(d, function (idx, data) {
console.log(idx, data);
});
Gist
I was originally looking for a way to select a wildcard in the data attribute, but I couldn’t get it working. Anyway, this works fine – though I did not actually end up using it. 🙂