diff --git a/Client-Side Components/Catalog Client Script/Smart Form Validation/README.md b/Client-Side Components/Catalog Client Script/Smart Form Validation/README.md new file mode 100644 index 0000000000..3a97c0ffcc --- /dev/null +++ b/Client-Side Components/Catalog Client Script/Smart Form Validation/README.md @@ -0,0 +1,121 @@ +# Smart Form Validation for Catalog Items + +This snippet provides intelligent form validation functionality for ServiceNow Catalog Items with real-time feedback and custom validation rules. + +## Overview + +The feature includes two implementations: +1. Basic Implementation (`basic_implementation.js`) +2. Advanced Implementation (`advanced_implementation.js`) + +## Basic Implementation + +### Features +- Real-time field validation +- Common validation rules (email, phone, number, date) +- Field-specific error messages +- Form-level validation + +### Usage +```javascript +// Apply in Catalog Client Script +// Select both "onChange" and "onSubmit" for "Client script runs" +// Copy content from basic_implementation.js +``` + +## Advanced Implementation + +### Enhanced Features +- All basic features +- Custom validation rules +- Field dependencies +- Validation history (undo/redo support) +- Validation summary dialog +- Working hours validation +- Password strength checking +- Future date validation + +### Usage +```javascript +// Apply in Catalog Client Script +// Select both "onChange" and "onSubmit" for "Client script runs" +// Copy content from advanced_implementation.js +``` + +## Technical Details + +### Dependencies +- ServiceNow Platform UI Framework +- GlideForm API +- GlideModal (advanced implementation) + +### Validation Rules +1. Basic Rules: + - Email validation + - Phone number format + - Numeric values + - Date format + +2. Advanced Rules: + - Password strength + - Future dates + - Working hours + - Custom dependencies + +## Implementation Guide + +1. Create a new Catalog Client Script: + - Table: Catalog Client Script [catalog_script_client] + - Type: Both onChange and onSubmit + - Active: true + +2. Choose implementation: + - For basic needs: Copy `basic_implementation.js` + - For advanced features: Copy `advanced_implementation.js` + +3. Configure Rules: + - Modify existing rules + - Add custom validation rules + - Set up field dependencies + +## Best Practices + +1. Performance: + - Use appropriate validation timing + - Cache validation results + - Optimize regular expressions + +2. User Experience: + - Clear error messages + - Immediate feedback + - Helpful validation summaries + +3. Maintenance: + - Document custom rules + - Keep validation logic organized + - Regular expression testing + +## Limitations + +- Browser compatibility considerations +- Form field type restrictions +- Performance with many fields + +## Troubleshooting + +Common issues and solutions: +1. Validation not triggering + - Check event handlers + - Verify field types + - Console for errors + +2. Custom rules not working + - Validate rule syntax + - Check field values + - Test regular expressions + +## Version Information + +- Compatible with ServiceNow: Rome and later +- Browser Requirements: Modern browsers +- Last Updated: October 2025 \ No newline at end of file diff --git a/Client-Side Components/Catalog Client Script/Smart Form Validation/script.js b/Client-Side Components/Catalog Client Script/Smart Form Validation/script.js new file mode 100644 index 0000000000..31cc34b0b6 --- /dev/null +++ b/Client-Side Components/Catalog Client Script/Smart Form Validation/script.js @@ -0,0 +1,190 @@ +/** + * Smart Form Validation + * Comprehensive form validation with custom rules and real-time feedback + */ + +function onChange(control, oldValue, newValue, isLoading) { + if (isLoading || newValue === '') { + return; + } + + var validator = new SmartFormValidator(); + validator.validateField(control, newValue); +} + +function onSubmit() { + var validator = new SmartFormValidator(); + return validator.validateForm(); +} + +var SmartFormValidator = Class.create(); +SmartFormValidator.prototype = { + initialize: function() { + // Validation rules with regex patterns and custom functions + this.rules = { + // Basic field types + email: { + pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, + message: 'Please enter a valid email address' + }, + phone: { + pattern: /^\+?[\d\s-]{10,}$/, + message: 'Please enter a valid phone number' + }, + number: { + pattern: /^\d+$/, + message: 'Please enter a valid number' + }, + date: { + validate: function(value) { + var date = new Date(value); + return !isNaN(date.getTime()); + }, + message: 'Please enter a valid date' + }, + // Special validations + password: { + validate: function(value) { + return /^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,}$/.test(value); + }, + message: 'Password must contain at least 8 characters, one letter, one number, and one special character' + }, + futureDate: { + validate: function(value) { + var date = new Date(value); + return date > new Date(); + }, + message: 'Date must be in the future' + }, + workingHours: { + validate: function(value) { + var time = value.split(':'); + var hour = parseInt(time[0]); + return hour >= 9 && hour < 17; + }, + message: 'Time must be between 9 AM and 5 PM' + } + }; + + // Field dependencies storage + this.dependencies = {}; + }, + + // Add a dependency between fields + addDependency: function(field, dependentField, validationFunc) { + if (!this.dependencies[field]) { + this.dependencies[field] = []; + } + this.dependencies[field].push({ + field: dependentField, + validate: validationFunc + }); + }, + + // Validate dependencies for a field + validateDependencies: function(field) { + if (this.dependencies[field]) { + this.dependencies[field].forEach(function(dep) { + var dependentValue = g_form.getValue(dep.field); + var isValid = dep.validate(dependentValue); + + if (!isValid) { + g_form.showFieldMsg(dep.field, 'This field depends on ' + field, 'warning'); + } + }); + } + }, + + // Validate a single field + validateField: function(control, value) { + var fieldType = this._getFieldValidationType(control); + var rule = this.rules[fieldType]; + + if (rule) { + var isValid = rule.pattern ? + rule.pattern.test(value) : + rule.validate(value); + + if (!isValid) { + g_form.showFieldMsg(control, rule.message, 'error'); + return false; + } + + // Check field dependencies + this.validateDependencies(control); + g_form.hideFieldMsg(control); + return true; + } + return true; + }, + + // Validate entire form + validateForm: function() { + var isValid = true; + var fields = g_form.getFields(); + var invalidFields = []; + + fields.forEach(function(field) { + var fieldName = field.getName(); + var value = g_form.getValue(fieldName); + + if (!this.validateField(fieldName, value)) { + isValid = false; + invalidFields.push(fieldName); + } + }, this); + + if (!isValid) { + this._showValidationSummary(invalidFields); + } + + return isValid; + }, + + // Determine validation type for a field + _getFieldValidationType: function(fieldName) { + var field = g_form.getField(fieldName); + var type = field.getType(); + + // Check for special validation rules + var validationType = g_form.getValue(fieldName + '_validation_type'); + if (validationType && this.rules[validationType]) { + return validationType; + } + + // Map field types to validation rules + switch(type) { + case 'email': + return 'email'; + case 'phone': + return 'phone'; + case 'integer': + case 'decimal': + return 'number'; + case 'date': + return 'date'; + default: + return null; + } + }, + + // Show validation summary dialog + _showValidationSummary: function(invalidFields) { + var dialog = new GlideModal('validation_summary'); + dialog.setTitle('Form Validation Errors'); + + var html = '
Please correct the following fields:
'; + html += '