Recent gists

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. 🙂