Much more stable than straight js. In the js function, set the args.IsValid = true if valid or false if not valid based on custom rules that can span other controls The error message will be written out as an element where it is placed in the markup.
NOTE: Do not assign the property ControlToValidate. Leave it. Adding it stops it working
<asp:CustomValidator ID="cus_WageInstallments"
runat="server"
ClientValidationFunction="ValidateWageInstallments"
ValidationGroup="DocForm"
CssClass="text-danger"
Display="Dynamic"
Text="Please select a Wage Installment"></asp:CustomValidator>
// and your js
function ValidateWageInstallments(sender, args) {
var weeklyCheckbox = document.getElementById("chkWeekly");
var monthlyCheckbox = document.getElementById("chkMonthly");
args.IsValid = true;
if (weeklyCheckbox && monthlyCheckbox) {
if (!weeklyCheckbox.checked && !monthlyCheckbox.checked) {
args.IsValid = false;
}
}
}