Hello!
I'm attempting to modify a currently existing form, hosted on a third party site, to require at least one checkbox be checked prior to submission. I have the code (pulled and modified from a VERY old discussion here on the boards) placed as a block of rich text at the bottom of the form. It's SO close to working. I was hoping that someone might be able to help me with the final step. Thank you in advance!!
The hosted page: 
www.yodlee.com/company/contact-us-2
The code:
<script>// <![CDATA[
MktoForms2.whenReady(function(mktoForm){
const specialFieldGroups = [
{
fields : ["Product_Interest_Account_Verification__c", "Product_Interest_Data_Aggregation__c", "Product_Interest_Data_Analytics_FI__c", "Product_Interest_Data_Analytics_Other__c", "Product_Interest_Fin_Wellness_Sol__c", "Product_Interest_Wealth_Mgmt_Solution__c"],
minFilled : 1,
maxFilled : Infinity,
message: "Please check at least one product of interest."
}
];
/* -- NO NEED TO CHANGE BELOW THIS LINE -- */
const formEl = mktoForm.getFormElem()[0];
mktoForm.onValidate(function(nativeValid){
if(!nativeValid) return;
let currentValues = mktoForm.getValues(),
firstOffenderGroup;
specialFieldGroups.some(function(group){
let numFilled = group.fields
.filter(function(fieldName){ console.log(currentValues[fieldName])
return (currentValues[fieldName] !== "" && currentValues[fieldName] !== "no");
})
.length;
if(numFilled < group.minFilled || numFilled > group.maxFilled){
firstOffenderGroup = group;
return true;
}
});
if(firstOffenderGroup) {
let fieldEl = formEl.querySelector("[name='" + firstOffenderGroup.fields[0] + "']");
mktoForm.showErrorMessage(firstOffenderGroup.message, MktoForms2.$(fieldEl));
}
});
});
// ]]></script>
					
				
			
			
				
			
			
				Solved! Go to Solution.
It's missing actually stopping the form from submitting.
Should be:
MktoForms2.whenReady(function(mktoForm){
   const specialFieldGroups = [
      {
         fields : ["Product_Interest_Account_Verification__c", "Product_Interest_Data_Aggregation__c", "Product_Interest_Data_Analytics_FI__c", "Product_Interest_Data_Analytics_Other__c", "Product_Interest_Fin_Wellness_Sol__c", "Product_Interest_Wealth_Mgmt_Solution__c"],
         minFilled : 1,
         maxFilled : Infinity,
         message: "Please check at least one product of interest."
      }
   ];
   
   /* -- NO NEED TO CHANGE BELOW THIS LINE -- */
   
   const formEl =  mktoForm.getFormElem()[0];
   
   mktoForm.onValidate(function(nativeValid){
      if(!nativeValid) return;
            
      let currentValues = mktoForm.getValues(),      
          firstOffenderGroup;
      
      specialFieldGroups.some(function(group){
         let numFilled = group.fields
           .filter(function(fieldName){ console.log(currentValues[fieldName])
             return (currentValues[fieldName] !== "" && currentValues[fieldName] !== "no");
           })
           .length; 
         if(numFilled < group.minFilled || numFilled > group.maxFilled){
            firstOffenderGroup = group;
            return true;
         }
      });
         
      if(firstOffenderGroup) {
         let fieldEl = formEl.querySelector("[name='" + firstOffenderGroup.fields[0] + "']");
         mktoForm.submittable(false);
         mktoForm.showErrorMessage(firstOffenderGroup.message, MktoForms2.$(fieldEl));
      } else {
         mktoForm.submittable(true);
      }
      
   });
   
});
However note that embedding custom forms JS in a RTA requires special handling to avoid surprises.
You haven't explained what isn't working.
You're absolutely correct. Good call. My apologies!
When a user does not check one of the desired boxes, the popup "Please check at least one product of interest." does appear for a moment, but the page submits anyway.
It's missing actually stopping the form from submitting.
Should be:
MktoForms2.whenReady(function(mktoForm){
   const specialFieldGroups = [
      {
         fields : ["Product_Interest_Account_Verification__c", "Product_Interest_Data_Aggregation__c", "Product_Interest_Data_Analytics_FI__c", "Product_Interest_Data_Analytics_Other__c", "Product_Interest_Fin_Wellness_Sol__c", "Product_Interest_Wealth_Mgmt_Solution__c"],
         minFilled : 1,
         maxFilled : Infinity,
         message: "Please check at least one product of interest."
      }
   ];
   
   /* -- NO NEED TO CHANGE BELOW THIS LINE -- */
   
   const formEl =  mktoForm.getFormElem()[0];
   
   mktoForm.onValidate(function(nativeValid){
      if(!nativeValid) return;
            
      let currentValues = mktoForm.getValues(),      
          firstOffenderGroup;
      
      specialFieldGroups.some(function(group){
         let numFilled = group.fields
           .filter(function(fieldName){ console.log(currentValues[fieldName])
             return (currentValues[fieldName] !== "" && currentValues[fieldName] !== "no");
           })
           .length; 
         if(numFilled < group.minFilled || numFilled > group.maxFilled){
            firstOffenderGroup = group;
            return true;
         }
      });
         
      if(firstOffenderGroup) {
         let fieldEl = formEl.querySelector("[name='" + firstOffenderGroup.fields[0] + "']");
         mktoForm.submittable(false);
         mktoForm.showErrorMessage(firstOffenderGroup.message, MktoForms2.$(fieldEl));
      } else {
         mktoForm.submittable(true);
      }
      
   });
   
});
However note that embedding custom forms JS in a RTA requires special handling to avoid surprises.
I greatly appreciate the info and the warning, Sanford! Thank you very much!