Lightswitch Custom Validation Refresh

March 04, 2015

I found an odd problem this week in a SharePoint-enabled Lightswitch HTML Client application. I am sharing the solution here in case there is somebody out there with a similar situation.

SYMPTOMS

You have a Lightswitch HTML application (banner definition in my case). You use custom validation function in beforeApplyChanges function.

myapp.AddEditBanners.beforeApplyChanges = function (screen) {  
    var hasErrors = false;  
    if (screen.Banner.EndDate && screen.Banner.EndDate <= screen.Banner.StartDate) {  
        screen.findContentItem("EndDate").validationResults = \[  
            new msls.ValidationResult(screen.Banner.EndDate, "La fecha de fin tiene que ser posterior a la fecha de inicio.")  
        \];  
        return false;  
    }  
};

Your validation works! However, when you try to correct the field that is being validated, the Save button doesn't work anymore and it keeps the custom validation message on the screen (it says in Spanish that the end date has to be later than the start date).

image

Furthermore, you get an error message that says "Cannot continue. There are validation errors on the page".

image

CAUSE

Apparently, Lightswitch code generator attaches the validation refresh on control events such as focus, blur, keyup etc, but only on default LS validations (data type, length, required fields and similar).

Custom validations on beforeApplyChanges are not refreshed on data changes in the controls and due to the page being in invalid state, the Save button doesn't trigger the beforeApplyChanges function again. It's a kind of a subtle bug in LS code generation that causes deadlock: we can't save because the validation isn't firing and it isn't firing because we can't save.

SOLUTION

Well, the best solution would be for Lightswitch to expose an additional hookup point for custom validation, one that should be refreshed automatically with any control change. However, it is improbable that it would ever be included in Lightswitch code.

The available solution for now is to register a change listener for those properties in our screen that trigger custom validation. Once the value is changed, we remove the validation errors for that field if there are any. This ensures that the Save button will work, triggering the custom validation logic again. We can hook up the change listener in the screen created event.

myapp.AddEditBanners.created = function (screen) {  
    function onBannerNameChange() {  
        if (screen.findContentItem("BannerName").hasValidationErrors()) {  
            screen.findContentItem("BannerName").validationResults = \[\];  
        }  
    }  
    screen.Banner.addChangeListener("BannerName", onBannerNameChange);  
};

However, we have to be careful to unregister the change listener when the screen is closed. This technique is explained in this MSDN Forum post by Huy Nguyen.

screen.details.rootContentItem.handleViewDispose(function () {  
  
    screen.Banner.removeChangeListener("BannerName", onBannerNameChange);  
});

Profile picture

Written by Edin Kapić Insatiably curious code-writing tinkerer. Geek father. Aviation enthusiast. Cuisine journeyman. Follow me on Twitter