|
| 1 | +# Dynamic Field Dependencies with GlideAjax |
| 2 | + |
| 3 | +This folder contains advanced Client Script examples demonstrating real-time field dependencies using GlideAjax for server-side data retrieval, cascading dropdowns, and dynamic form behavior. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +Modern ServiceNow forms often require dynamic behavior based on user selections. This example demonstrates: |
| 8 | +- **Real-time field updates** using GlideAjax for server-side queries |
| 9 | +- **Cascading dropdown menus** that filter based on parent selections |
| 10 | +- **Conditional field visibility** based on complex business logic |
| 11 | +- **Debouncing** to prevent excessive server calls |
| 12 | +- **Loading indicators** for better user experience |
| 13 | +- **Error handling** for failed AJAX calls |
| 14 | +- **Performance optimization** with caching and batching |
| 15 | + |
| 16 | +## Script Descriptions |
| 17 | + |
| 18 | +- **dynamic_category_subcategory.js**: Client Script implementing cascading category/subcategory dropdowns with real-time filtering. |
| 19 | +- **conditional_field_loader.js**: Advanced example showing conditional field loading based on multiple dependencies. |
| 20 | +- **ajax_script_include.js**: Server-side Script Include (Client Callable) that provides data for the client scripts. |
| 21 | +- **debounced_field_validator.js**: Real-time field validation with debouncing to reduce server load. |
| 22 | + |
| 23 | +## Key Features |
| 24 | + |
| 25 | +### 1. GlideAjax Communication |
| 26 | +Efficient client-server communication: |
| 27 | +```javascript |
| 28 | +var ga = new GlideAjax('MyScriptInclude'); |
| 29 | +ga.addParam('sysparm_name', 'getSubcategories'); |
| 30 | +ga.addParam('sysparm_category', categoryValue); |
| 31 | +ga.getXMLAnswer(callback); |
| 32 | +``` |
| 33 | + |
| 34 | +### 2. Cascading Dropdowns |
| 35 | +Dynamic filtering of child fields: |
| 36 | +- Parent field change triggers child field update |
| 37 | +- Child options filtered based on parent selection |
| 38 | +- Multiple levels of cascading supported |
| 39 | +- Maintains previously selected values when possible |
| 40 | + |
| 41 | +### 3. Debouncing |
| 42 | +Prevents excessive server calls: |
| 43 | +- Waits for user to stop typing before making request |
| 44 | +- Configurable delay (typically 300-500ms) |
| 45 | +- Cancels pending requests when new input received |
| 46 | +- Improves performance and user experience |
| 47 | + |
| 48 | +### 4. Loading Indicators |
| 49 | +Visual feedback during AJAX calls: |
| 50 | +- Shows loading spinner or message |
| 51 | +- Disables fields during data fetch |
| 52 | +- Clears loading state on completion or error |
| 53 | +- Prevents duplicate submissions |
| 54 | + |
| 55 | +## Use Cases |
| 56 | + |
| 57 | +- **Category/Subcategory Selection**: Filter subcategories based on selected category |
| 58 | +- **Location-Based Fields**: Update city/state/country fields dynamically |
| 59 | +- **Product Configuration**: Show/hide fields based on product type |
| 60 | +- **Assignment Rules**: Dynamically populate assignment groups based on category |
| 61 | +- **Cost Estimation**: Calculate and display costs based on selections |
| 62 | +- **Availability Checking**: Real-time validation of resource availability |
| 63 | +- **Dynamic Pricing**: Update pricing fields based on quantity/options |
| 64 | + |
| 65 | +## Implementation Requirements |
| 66 | + |
| 67 | +### Client Script Configuration |
| 68 | +- **Type**: onChange (for field changes) or onLoad (for initial setup) |
| 69 | +- **Table**: Target table (e.g., incident, sc_req_item) |
| 70 | +- **Field**: Trigger field (e.g., category) |
| 71 | +- **Active**: true |
| 72 | +- **Global**: false (table-specific for better performance) |
| 73 | + |
| 74 | +### Script Include Configuration |
| 75 | +- **Name**: Descriptive name (e.g., CategoryAjaxUtils) |
| 76 | +- **Client callable**: true (REQUIRED for GlideAjax) |
| 77 | +- **Active**: true |
| 78 | +- **Access**: public or specific roles |
| 79 | + |
| 80 | +### Required Fields |
| 81 | +Ensure dependent fields exist on the form: |
| 82 | +- Add fields to form layout |
| 83 | +- Configure field properties (mandatory, read-only, etc.) |
| 84 | +- Set up choice lists for dropdown fields |
| 85 | + |
| 86 | +## Performance Considerations |
| 87 | + |
| 88 | +### Optimization Techniques |
| 89 | +1. **Cache responses**: Store frequently accessed data client-side |
| 90 | +2. **Batch requests**: Combine multiple queries into single AJAX call |
| 91 | +3. **Minimize payload**: Return only required fields |
| 92 | +4. **Use indexed queries**: Ensure server-side queries use indexed fields |
| 93 | +5. **Debounce input**: Wait for user to finish typing |
| 94 | +6. **Lazy loading**: Load data only when needed |
| 95 | + |
| 96 | +### Best Practices |
| 97 | +- Keep Script Includes focused and single-purpose |
| 98 | +- Validate input parameters server-side |
| 99 | +- Handle errors gracefully with user-friendly messages |
| 100 | +- Test with large datasets to ensure performance |
| 101 | +- Use browser developer tools to monitor network calls |
| 102 | +- Implement timeout handling for slow connections |
| 103 | + |
| 104 | +## Security Considerations |
| 105 | + |
| 106 | +### Input Validation |
| 107 | +Always validate parameters server-side: |
| 108 | +```javascript |
| 109 | +// BAD: No validation |
| 110 | +var category = this.getParameter('sysparm_category'); |
| 111 | +var gr = new GlideRecord('cmdb_ci_category'); |
| 112 | +gr.addQuery('parent', category); // SQL injection risk |
| 113 | + |
| 114 | +// GOOD: Validate and sanitize |
| 115 | +var category = this.getParameter('sysparm_category'); |
| 116 | +if (!category || !this._isValidSysId(category)) { |
| 117 | + return '[]'; |
| 118 | +} |
| 119 | +``` |
| 120 | + |
| 121 | +### Access Control |
| 122 | +- Respect ACLs in Script Includes |
| 123 | +- Use GlideRecordSecure when appropriate |
| 124 | +- Don't expose sensitive data to client |
| 125 | +- Implement role-based filtering |
| 126 | + |
| 127 | +### XSS Prevention |
| 128 | +- Sanitize data before displaying |
| 129 | +- Use g_form.setValue() instead of innerHTML |
| 130 | +- Validate choice list values |
| 131 | +- Escape special characters |
| 132 | + |
| 133 | +## Error Handling |
| 134 | + |
| 135 | +### Client-Side |
| 136 | +```javascript |
| 137 | +ga.getXMLAnswer(function(response) { |
| 138 | + if (!response || response === 'error') { |
| 139 | + g_form.addErrorMessage('Failed to load data. Please try again.'); |
| 140 | + return; |
| 141 | + } |
| 142 | + // Process response |
| 143 | +}); |
| 144 | +``` |
| 145 | + |
| 146 | +### Server-Side |
| 147 | +```javascript |
| 148 | +try { |
| 149 | + // Query logic |
| 150 | +} catch (ex) { |
| 151 | + gs.error('Error in getSubcategories: ' + ex.message); |
| 152 | + return 'error'; |
| 153 | +} |
| 154 | +``` |
| 155 | + |
| 156 | +## Testing Checklist |
| 157 | + |
| 158 | +- [ ] Test with empty/null values |
| 159 | +- [ ] Test with invalid input |
| 160 | +- [ ] Test with large datasets (1000+ records) |
| 161 | +- [ ] Test on slow network connections |
| 162 | +- [ ] Test concurrent user interactions |
| 163 | +- [ ] Test browser compatibility (Chrome, Firefox, Safari, Edge) |
| 164 | +- [ ] Test mobile responsiveness |
| 165 | +- [ ] Verify ACL enforcement |
| 166 | +- [ ] Check for console errors |
| 167 | +- [ ] Monitor network tab for performance |
| 168 | + |
| 169 | +## Browser Compatibility |
| 170 | + |
| 171 | +Tested and compatible with: |
| 172 | +- Chrome 90+ |
| 173 | +- Firefox 88+ |
| 174 | +- Safari 14+ |
| 175 | +- Edge 90+ |
| 176 | +- ServiceNow Mobile App |
| 177 | + |
| 178 | +## Related APIs |
| 179 | + |
| 180 | +- **GlideAjax**: Client-server communication |
| 181 | +- **GlideForm (g_form)**: Form manipulation |
| 182 | +- **GlideUser (g_user)**: User context |
| 183 | +- **GlideRecord**: Server-side queries |
| 184 | +- **JSON**: Data serialization |
| 185 | + |
| 186 | +## Additional Resources |
| 187 | + |
| 188 | +- ServiceNow Client Script Best Practices |
| 189 | +- GlideAjax Documentation |
| 190 | +- Client-Side Scripting API Reference |
| 191 | +- Performance Optimization Guide |
0 commit comments