Overview
SmartCheck Validation represents a secure server-side validation method. It facilitates the validation of custom fields, ensuring that applications and form inputs adhere to specified criteria and return accurate results. This approach enhances user experience compared to alternative validation methodologies and is preferred over Submit Logic. With SmartCheck, users are able to view error messages in context and in a centralized location.
Utilizing SmartCheck Validation with the message type of Field allows users to view all messages in one centralized location, as well as context-specific messages. Please refer to the image below.
By clicking the x within the contextual error message, such as the description field above, users can temporarily conceal the message. Clicking the error message at the top will direct the cursor to the field containing the error (if a corresponding input exists). The contextual error message will also disappear once the value in the relevant field has been modified.
Prior to utilizing SmartCheck validation, it is necessary to . . .
1. Configure SmartCheck Validation
2. Integrate SmartCheck Validation with the Submit Button
Please note that once SmartCheck Validation is implemented, it will be enabled universally. If Submit Logic or other validation methods were previously established prior to activating SmartCheck Validation, it is essential to test these validations to ensure they function as intended or to replace them with SmartCheck Validation.
Configuration of SmartCheck Validation
SmartCheck Validation may be configured for each object type within the system (e.g., individual UTA Level 1/2/3, company, user, transaction) and subsequently linked to a Submit button.
1. Each entity will include a SmartCheck Validation link that can be accessed on the corresponding Settings page. Click this link to commence the configuration process for the SmartCheck validation statements.
2. The SmartCheck Validation list view will be displayed. A New Validation button will be located at the top. Click this button.
3. The SmartCheck validation screen will appear, comprising the following three tabs:
- Main
- Code Builder
- Source
4. Enter the appropriate name and description text into the relevant fields on the Main tab and click Save.
5. Proceed to the Code Builder tab to incorporate validation using two possible methods.
- New Validation: Employ the drop-down menus at the top of the screen to create a new validation. Further details regarding the available options are provided in the SmartCheck Validation Structure section below.
- Existing Submit Logic: Utilize the drop-down menu at the bottom of the screen to select a submit button and any existing validation associated with that button.
6. Click the Insert button under the relevant section. This action will redirect you to the Source tab, showcasing the updated validation statement.
7. Click the Save button to preserve all modifications.
8. Utilize the Trial Run feature located at the bottom of the Source tab to verify whether any errors occur during the execution of the validation statements.
Incorporating SmartCheck Validation into Submit Button
Upon the creation of the validation statements, you may proceed to integrate the logic into the Submit or Save buttons.
1. Each entity will feature a [Submit & Save Buttons] link on the corresponding Settings page. Click this link to initiate the process of adding the SmartCheck validation statements to a button.
2. The Submit & Save Buttons page will be displayed, presenting a list of configured buttons. Click the Edit button for the button you wish to modify.
3. Select the SmartCheck Validation option from the corresponding drop-down menu.
4. Click Save at the bottom of the page.
SmartCheck Update History
Modifications to the SmartCheck logic can be tracked using the Update History feature, which is available for each configured SmartCheck validation.
If a user clicks on the Update History button, they will receive an overview of all changes made to that specific SmartCheck validation, including the date and time of the change and the individual responsible for the modification.
Users may also compare versions by selecting the checkbox on the left of the list view and subsequently clicking on the Compare button.
Users will be presented with a screen displaying the differences between the two versions.
Structure of SmartCheck Validation
Each SmartCheck Validation statement adheres to the following structure:
- If Statement (condition to be evaluated)
- Result (assigned outcome based on the condition)
- Message (to be displayed if the result is false)
In the example provided below:
if(ssParseNumFromCurrency(form.getStr("cf_myCADcurrency"),"@sslocale@",1,true) > 5) { result.isPassed=false; result.addMsg("Some message here"); } if(ssParseNumFromCurrency(form.getStr("cf_myDKKcurrency"),"da-DK",1,true) > 5) { result.isPassed=false; result.addMsg("Some message here"); }
If the custom field is a currency and the format varies based on different locales, utilize
ssParseNumFromCurrency(value,locale,getnumtype,emptyok):
- "@sslocale@" returns the locale of the logged-in user, e.g., "fr-CA"
- getnumtype: 1=real number (10000,78 becomes 10000.78), 2=formatted currency (10000,78)
- emptyok: field may be empty
Example: ssParseNumFromCurrency("10000,78","fr-CA",1,true) will yield 10000.78
if(ssParseNumFromCurrency(form.getStr("cf_myCADcurrency"),"@sslocale@",1,true) > 5) { result.isPassed=false; result.addMsg("Some message here"); }
For other currencies with a format that remains constant regardless of the user's locale, such as DKK, it can be implemented as:
ssParseNumFromCurrency(value,getLocalestrByCurrency('DKK'),1,true) OR ssParseNumFromCurrency(value,"da-DK",1,true)
(getLocalestrByCurrency will retrieve the "default" locale of the currency code)
if(ssParseNumFromCurrency(form.getStr("cf_myDKKcurrency"),"da-DK",1,true) > 5) { result.isPassed=false; result.addMsg("Some message here"); }
Recognize the If, Result, Message structure:
if(ssParseNum(form.getStr("cf_Store Value")) > 5)
Check If the contents of the form value (stored in the custom field named cf_Store_Value) are greater than 5,
result.isPassed=false;
Assign the value of the Result to "false" and display the custom message below.
result.addMsg("Some message here");
Form Value versus Stored Value
Within the SmartCheck code builder, there exists a selection option to choose between Form Value and Stored Value. The Form Value represents the value entered by an individual into their application (form), including information that has not yet been saved. Conversely, the Stored Value refers to the value from the server (information that has been saved). By utilizing the Form Value, validation can be performed based on information entered by the user, even if they have not yet clicked save on their application.
Here is an illustration of how to reference the Form Value for a standard field:
if(form.getStr("sf_Application Name") == "")
Here is how to reference the Stored Value for the same standard field:
if("@Application Name@" == "")
It is noteworthy that the stored value is referenced using the variable syntax as discussed in the variable processor lesson.
Field vs System Messages
In the SmartCheck code builder, there exists a selection option allowing you to choose between Field and System Messages. Field messages are displayed both at the top of the application and on the specific field that failed validation; this type is recommended for the majority of validations. Conversely, System messages are only displayed at the top of the application. System messages may be employed when your validation involves comparisons between multiple fields, as it may not be clear which field should be highlighted with the error message.
Below is an example of how to invoke a system message:
result.addMsg("Your message goes here.");
Here is an example of invoking a Field message on a custom field:
result.addMsg("cf_@field name.id@", "Your message goes here.");
Please note that the field name is included before your message, allowing the system to identify where to position the validation message, and it determines where to place the cursor should the message be clicked.
Configuring Messages for Multilingual Systems
Messages can also be rendered in various languages based on the user’s selected language within the portal. The langid variable for the language must be incorporated within the syntax to associate the message with a specific language setting.
The message below would only be displayed for the English language:
result.addMsg("Your message goes here.", 1);
The langid may also be utilized for Field messages:
result.addMsg("cf_@field name.id@", "Your message goes here.", 1);
The following is an example that incorporates multiple languages:
if(((form.getStr("cf_Strategy").length() - form.getStr("cf_Strategy").replace(';','').length())>4)) { result.isPassed=false; result.addMsg("cf_@Strategy.id@","You can pick up to 4 primary strategies you use.", 1); result.addMsg("cf_@Strategy.id@","Puedes elegir 4 estrategias principales.", 14); result.addMsg("cf_@Strategy.id@","Vous pouvez choisir à 4 stratégies primaires", 6); result.addMsg("cf_@Strategy.id@","Você pode escolher 4 estratégias primárias.", 16); }
Important: The langid variable must be included in every SmartCheck message within the system and cannot be selectively applied to specific messages.
Examples
Check if an amount exceeds $100,000
if(ssParseNum(form.getStr("cf_Amount Requested")) > 100000) { result.isPassed=false; result.addMsg("cf_@Amount Requested.id@","Amount Requested cannot exceed $100,000"); }
Application Name field is blank
if(form.getStr("sf_Application Name") == ""){ result.isPassed=false; result.addMsg("Application name cannot be blank"); }
Requested Amount is less than X
if(ssParseNum(form.getStr("cf_Requested Amount")) < 5000) { result.isPassed=false; result.addMsg("cf_@Requested Amount.id@","Field test message"); }
Number value exceeds 5
if(ssParseNum(form.getStr("cf_Store Value")) > 5) { result.isPassed=false; result.addMsg("Some message here"); }
Single file upload field is empty
if("@Single File Field.filename@" == "") { result.isPassed=false; result.addMsg("Please upload a file here"); }
Multi-file upload field is empty
if(ssParseNum("@level1.MUlti upload.numoffiles@") < 1) { result.isPassed=false; result.addMsg("Please upload at least one file"); }
Dynamic XML field contains no entries
if("@xml.fieldname.sectionnodename.rownodename.nodecount@"==0) { result.isPassed=false; result.addMsg("xml_@fieldname.id@","At least one entry is required in the XML worksheet."); }
Comparing two custom date fields with separate custom time fields storing 24-hour time
if(ssConvertDate(form.getStr("cf_Event Start Date"),"@dateformat@", "yyyy-mm-dd")+' '+form.getStr("cf_Event Start Time") >= ssConvertDate(form.getStr("cf_Event End Date"),"@dateformat@", "yyyy-mm-dd")+' '+form.getStr("cf_Event End Time")) { result.isPassed=false; result.addMsg("cf_@Event End Time.id@","End Date must take place after the Start Date"); }
Comparing a date custom field to the current date
if ((ssConvertDate(form.getStr("cf_Individual Review Start Date"), "@dateformat@", "yyyy-mm-dd") > "@date(currentdate)@")) { result.isPassed = false; result.addMsg("cf_@Individual Review Start Date.id@", "Please enter a date less than or equal to today for the date."); }
Comparing a date custom field to a date that is six months prior (date must be at least six months ago)
if(ssConvertDate(form.getStr("cf_Date"),"@dateformat@", "yyyy-mm-dd") > "<!--@sscalculation(DATE_ADD('@date(currentdate)@', INTERVAL -6 MONTH))-->"){ result.isPassed=false; result.addMsg("cf_@Date.id@","Date must be at least 6 months prior to today's date"); }
NOTE: When utilizing @sscalculation, it is mandatory to enclose the syntax in double quotes.
Comparing two date custom fields which also store time
if(ConvertDateTimeStr(form.getStr("cf_Cycle Start Date"),"@dateformat@", "yyyy-mm-dd") >= ConvertDateTimeStr(form.getStr("cf_Cycle Deadline"),"@dateformat@", "yyyy-mm-dd")) { result.isPassed=false; result.addMsg('cf_@Cycle Deadline.id@','The submission deadline date cannot be before the open date'); }
Ensuring an entered date is at least three business days away
if(ssConvertDate(form.getStr("cf_Date EOI Revision Deadline"),"@dateformat@",'yyyy-mm-dd') < "<!--@sscalculation(SS_FUNC.addbusdays('@date(currentdate)@',3))-->") { result.isPassed=false; result.addMsg("cf_@Date EOI Revision Deadline.id@","Date must be at least 3 business days away"); }
NOTE: When utilizing @sscalculation, it is mandatory to enclose the syntax in double quotes.
Date custom field is blank
if ((ssConvertDate(form.getStr("cf_Project Start Date"), "@dateformat@", "yyyy-mm-dd") == "")) { result.isPassed = false; result.addMsg("cf_@Project Start Date.id@", "Project Start Date is a required field."); }
Validation on a Select Many Checkbox Field
if(form.getStr("cf_Request Type").indexOf("General Operating")==-1 ) { result.isPassed=false; result.addMsg("General Operating was not selected"); }
To trigger when the value is selected, use '!=-1'. This is typically employed in conjunction with another field for validations.
Select Many Checkbox field requires at least five values to be selected
if(((form.getStr("cf_Check Box Field").length() - form.getStr("cf_Check Box Field").replace(';','').length())<=4)) { result.isPassed=false; result.addMsg("cf_@Check Box Field.id@","At least 5 items must be selected."); }
At least one role must be selected for a contact
if("@rolelist@" == "") { result.isPassed=false; result.addMsg("At least one role must be selected."); }
Validation on an email field
if(!isEmail(form.getStr("cf_Additional Email 1"))) { result.isPassed=false; result.addMsg("cf_@Additional Email 1.id@","Please enter a valid email address."); }
Validate that the status of the organization is Active
if("@client.status@" != "Active") { result.isPassed=false; result.addMsg("Please update your Organization Profile then return to this record and click Submit Application."); }
Validation on a Note Enabled Multiple-Line custom field
When validating against a Note Enabled field, within the result.addMsg() alert, you must include h preceding the custom field reference.
if(form.getStr("cf_notefield")=="") { result.isPassed= false; result.addMsg("cf_h@notefield.id@","You must type in a description before submitting for revisions."); }
Minimum word count requirement
This is applied to multiline text fields to enforce a minimum word entry.
if(form.getStr("cf_Leadership").split(' ').length < 100) {
result.isPassed=false;
result.addMsg("cf_@Leadership.id@","Leadership question must have a minimum of 100 words");
}
Count contacts in a specific role
This is used to ensure that at least one contact is associated with the record in a specific role.
if("@level1.[#(?object=contact::criteria=rolename IN ('Panel Reviewer - Pending','Panel Reviewer - Accepted')::groupfunction=count)~userid~#]@" < "1") { result.isPassed=false; result.addMsg("Please assign reviewers in the Panel Reviewer Pending or Panel Reviewer Accepted role."); }
Defining VAR Variables
Utilizing JavaScript variables to define values that will be evaluated within the SmartCheck Validation.
var countWatch="[#(?object=activity::criteria=typename='Watchlist Scan' and statusname='Scan Run')~count(eventid)~#]"; if(countWatch=="0") { result.isPassed=false; result.addMsg("Please run a watchlist scan."); }
Application Limit Check via Specific Criteria
This involves validating an application through a custom field on the form and incorporating that into report criteria.
var maxstores="TEST@ReportProperty2(32735,exportdata,,'@displ_FY@::@typeid@')@"; var selectedstore=form.getStr("cf_txt_StoreNumber"); var y=maxstores.indexOf(selectedstore); if(y!=-1) { result.isPassed=false; result.addMsg("cf_@txt_StoreNumber.id@","Test"); }
Validate EIRCODES (Irish post codes)
if(form.getStr("whatever") == "something") { function isValidEircode(eircode) {
const regex = /^(?:[A-Za-z]\d{2}|D6W)\s?[A-Za-z0-9]{4}$/i;
return regex.test(eircode.trim());
} if(isValidEircode(form.getStr("cf_txt_TrainingLocationEircode")) === false) {
result.isPassed=false;
result.addMsg("cf_1948531","Please add a valid Eircode");
}
}
Validate IBANs & BICs (Bank Identifiers)
if(form.getStr("whatever") == "something") {
function isValidIBAN(input) {
const regex = /^IE.{20}$/i;
return regex.test(input);
} if(isValidIBAN(form.getStr("cf_txt_IBAN")) === false) {
result.isPassed=false;
result.addMsg("cf_1948551","Please add a valid Irish IBAN");
} function isValidBIC(input) {
const regex = /^(?:.{4})IE.{2,5}$/i;
return regex.test(input);
} if(isValidBIC(form.getStr("cf_txt_BIC")) === false) {
result.isPassed=false;
result.addMsg("cf_1948552","Please add a valid BIC");
}
}
To include other scripts in a SmartCheck script:
//@include(AnotherSmartCheckScriptName)@