catalog-items
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseService Catalog Development for ServiceNow
ServiceNow服务目录开发
The Service Catalog allows users to request services and items through a self-service portal.
服务目录允许用户通过自助门户请求服务和项目。
Catalog Components
目录组件
| Component | Purpose | Example |
|---|---|---|
| Catalog | Container for categories | IT Service Catalog |
| Category | Group of items | Hardware, Software |
| Item | Requestable service | New Laptop Request |
| Variable | Form field on item | Laptop Model dropdown |
| Variable Set | Reusable variable group | User Details |
| Producer | Creates records directly | Report an Incident |
| Order Guide | Multi-item wizard | New Employee Setup |
| 组件 | 用途 | 示例 |
|---|---|---|
| 目录 | 分类的容器 | IT服务目录 |
| 分类 | 项目组 | 硬件、软件 |
| 项目 | 可请求的服务 | 新笔记本电脑申请 |
| 变量 | 项目上的表单字段 | 笔记本电脑型号下拉框 |
| 变量集 | 可复用的变量组 | 用户详情 |
| 生成器 | 直接创建记录 | 上报事件 |
| 订购指南 | 多项目向导 | 新员工入职设置 |
Catalog Item Structure
目录项结构
Catalog Item: Request New Laptop
├── Variables
│ ├── laptop_model (Reference: cmdb_model)
│ ├── reason (Multi-line text)
│ └── urgency (Choice: Low, Medium, High)
├── Variable Sets
│ └── Delivery Information (Address, Contact)
├── Catalog Client Scripts
│ ├── onLoad: Set defaults
│ └── onChange: Update price
├── Workflows/Flows
│ └── Laptop Approval Flow
└── Fulfillment
└── Creates Task for ITCatalog Item: Request New Laptop
├── Variables
│ ├── laptop_model (Reference: cmdb_model)
│ ├── reason (Multi-line text)
│ └── urgency (Choice: Low, Medium, High)
├── Variable Sets
│ └── Delivery Information (Address, Contact)
├── Catalog Client Scripts
│ ├── onLoad: Set defaults
│ └── onChange: Update price
├── Workflows/Flows
│ └── Laptop Approval Flow
└── Fulfillment
└── Creates Task for ITVariable Types
变量类型
| Type | Use Case | Example |
|---|---|---|
| Single Line Text | Short input | Employee ID |
| Multi Line Text | Long input | Business Justification |
| Select Box | Single choice | Priority |
| Check Box | Yes/No | Express Delivery |
| Reference | Link to table | Requested For |
| Date | Date picker | Needed By Date |
| Lookup Select Box | Filtered reference | Model by Category |
| List Collector | Multiple selections | CC Recipients |
| Container Start/End | Visual grouping | Hardware Options |
| Macro | Custom widget | Cost Calculator |
| 类型 | 使用场景 | 示例 |
|---|---|---|
| 单行文本 | 短输入 | 员工ID |
| 多行文本 | 长输入 | 业务说明 |
| 选择框 | 单选 | 优先级 |
| 复选框 | 是/否 | 加急配送 |
| 引用 | 链接到表格 | 申请人 |
| 日期 | 日期选择器 | 需要日期 |
| 查找选择框 | 过滤后的引用 | 按分类筛选型号 |
| 列表收集器 | 多选 | 抄送收件人 |
| 容器开始/结束 | 视觉分组 | 硬件选项 |
| 宏 | 自定义小部件 | 成本计算器 |
Creating Catalog Variables
创建目录变量
Basic Variable
基础变量
javascript
// Via MCP
snow_create_catalog_variable({
catalog_item: 'laptop_request',
name: 'laptop_model',
type: 'reference',
reference: 'cmdb_model',
reference_qual: 'category=computer',
mandatory: true,
order: 100
});javascript
// Via MCP
snow_create_catalog_variable({
catalog_item: 'laptop_request',
name: 'laptop_model',
type: 'reference',
reference: 'cmdb_model',
reference_qual: 'category=computer',
mandatory: true,
order: 100
});Variable with Dynamic Default
带动态默认值的变量
javascript
// Variable: requested_for
// Type: Reference (sys_user)
// Default value (script):
javascript:gs.getUserID()javascript
// Variable: requested_for
// Type: Reference (sys_user)
// Default value (script):
javascript:gs.getUserID()Variable with Reference Qualifier
带引用限定符的变量
javascript
// Variable: assignment_group
// Type: Reference (sys_user_group)
// Reference Qualifier:
// Simple:
active=true^type=it
// Dynamic (Script):
javascript: 'active=true^manager=' + gs.getUserID()
// Advanced (using current variables):
javascript: 'u_department=' + current.variables.departmentjavascript
// Variable: assignment_group
// Type: Reference (sys_user_group)
// Reference Qualifier:
// Simple:
active=true^type=it
// Dynamic (Script):
javascript: 'active=true^manager=' + gs.getUserID()
// Advanced (using current variables):
javascript: 'u_department=' + current.variables.departmentCatalog Client Scripts
目录客户端脚本
Set Defaults onLoad
加载时设置默认值
javascript
function onLoad() {
// Set default values
g_form.setValue('urgency', 'low');
// Hide admin-only fields
if (!g_user.hasRole('catalog_admin')) {
g_form.setDisplay('cost_center', false);
}
// Set default date to tomorrow
var tomorrow = new GlideDateTime();
tomorrow.addDays(1);
g_form.setValue('needed_by', tomorrow.getDate().getValue());
}javascript
function onLoad() {
// Set default values
g_form.setValue('urgency', 'low');
// Hide admin-only fields
if (!g_user.hasRole('catalog_admin')) {
g_form.setDisplay('cost_center', false);
}
// Set default date to tomorrow
var tomorrow = new GlideDateTime();
tomorrow.addDays(1);
g_form.setValue('needed_by', tomorrow.getDate().getValue());
}Dynamic Pricing onChange
变更时动态计算价格
javascript
function onChange(control, oldValue, newValue, isLoading) {
if (isLoading) return;
// Get price from selected model
var ga = new GlideAjax('CatalogUtils');
ga.addParam('sysparm_name', 'getModelPrice');
ga.addParam('sysparm_model', newValue);
ga.getXMLAnswer(function(price) {
g_form.setValue('item_price', price);
updateTotal();
});
}
function updateTotal() {
var price = parseFloat(g_form.getValue('item_price')) || 0;
var quantity = parseInt(g_form.getValue('quantity')) || 1;
g_form.setValue('total_cost', (price * quantity).toFixed(2));
}javascript
function onChange(control, oldValue, newValue, isLoading) {
if (isLoading) return;
// Get price from selected model
var ga = new GlideAjax('CatalogUtils');
ga.addParam('sysparm_name', 'getModelPrice');
ga.addParam('sysparm_model', newValue);
ga.getXMLAnswer(function(price) {
g_form.setValue('item_price', price);
updateTotal();
});
}
function updateTotal() {
var price = parseFloat(g_form.getValue('item_price')) || 0;
var quantity = parseInt(g_form.getValue('quantity')) || 1;
g_form.setValue('total_cost', (price * quantity).toFixed(2));
}Validation onSubmit
提交时验证
javascript
function onSubmit() {
// Validate business justification for high-cost items
var cost = parseFloat(g_form.getValue('total_cost'));
var justification = g_form.getValue('business_justification');
if (cost > 1000 && !justification) {
g_form.showFieldMsg('business_justification',
'Required for items over $1000', 'error');
return false;
}
// Validate date is in future
var neededBy = g_form.getValue('needed_by');
var today = new GlideDateTime().getDate().getValue();
if (neededBy < today) {
g_form.showFieldMsg('needed_by',
'Date must be in the future', 'error');
return false;
}
return true;
}javascript
function onSubmit() {
// Validate business justification for high-cost items
var cost = parseFloat(g_form.getValue('total_cost'));
var justification = g_form.getValue('business_justification');
if (cost > 1000 && !justification) {
g_form.showFieldMsg('business_justification',
'Required for items over $1000', 'error');
return false;
}
// Validate date is in future
var neededBy = g_form.getValue('needed_by');
var today = new GlideDateTime().getDate().getValue();
if (neededBy < today) {
g_form.showFieldMsg('needed_by',
'Date must be in the future', 'error');
return false;
}
return true;
}Variable Sets
变量集
Creating Reusable Variable Sets
创建可复用的变量集
Variable Set: User Contact Information
├── contact_name (Single Line Text)
├── contact_email (Email)
├── contact_phone (Single Line Text)
└── preferred_contact (Choice: Email, Phone, Either)
Use in multiple catalog items:
- New Laptop Request
- Software Installation
- Network Access RequestVariable Set: User Contact Information
├── contact_name (Single Line Text)
├── contact_email (Email)
├── contact_phone (Single Line Text)
└── preferred_contact (Choice: Email, Phone, Either)
Use in multiple catalog items:
- New Laptop Request
- Software Installation
- Network Access RequestAccessing Variable Set Values
访问变量集的值
javascript
// In workflow or script
var ritm = current; // sc_req_item
// Access variable from variable set
var contactEmail = ritm.variables.contact_email;
var preferredContact = ritm.variables.preferred_contact;javascript
// In workflow or script
var ritm = current; // sc_req_item
// Access variable from variable set
var contactEmail = ritm.variables.contact_email;
var preferredContact = ritm.variables.preferred_contact;Catalog Workflows/Flows
目录工作流/流程
Approval Pattern
审批模式
Flow Trigger: sc_req_item created
├── If: Total cost > $5000
│ └── Request Approval: Department Manager
│ └── If: Rejected
│ └── Update: RITM state = Closed Incomplete
├── If: Total cost > $25000
│ └── Request Approval: VP
├── Create: Catalog Task for Fulfillment
└── Wait: Task completionFlow Trigger: sc_req_item created
├── If: Total cost > $5000
│ └── Request Approval: Department Manager
│ └── If: Rejected
│ └── Update: RITM state = Closed Incomplete
├── If: Total cost > $25000
│ └── Request Approval: VP
├── Create: Catalog Task for Fulfillment
└── Wait: Task completionFulfillment Script
执行脚本
javascript
// In catalog item's "Execution Plan" or workflow
var ritm = current; // sc_req_item
// Create an incident from catalog request
var inc = new GlideRecord('incident');
inc.initialize();
inc.setValue('short_description', ritm.short_description);
inc.setValue('description', ritm.description);
inc.setValue('caller_id', ritm.request.requested_for);
inc.setValue('category', ritm.variables.category);
inc.setValue('priority', ritm.variables.urgency);
inc.insert();
// Link incident to request
ritm.setValue('u_fulfillment_record', inc.getUniqueValue());
ritm.update();javascript
// In catalog item's "Execution Plan" or workflow
var ritm = current; // sc_req_item
// Create an incident from catalog request
var inc = new GlideRecord('incident');
inc.initialize();
inc.setValue('short_description', ritm.short_description);
inc.setValue('description', ritm.description);
inc.setValue('caller_id', ritm.request.requested_for);
inc.setValue('category', ritm.variables.category);
inc.setValue('priority', ritm.variables.urgency);
inc.insert();
// Link incident to request
ritm.setValue('u_fulfillment_record', inc.getUniqueValue());
ritm.update();Record Producers
记录生成器
Creating Incidents via Catalog
通过目录创建事件
javascript
// Record Producer: Report an Issue
// Table: incident
// Script:
// Map variables to incident fields
current.short_description = producer.short_description;
current.description = producer.description;
current.caller_id = gs.getUserID();
current.category = producer.category;
current.subcategory = producer.subcategory;
current.priority = producer.urgency == 'urgent' ? '2' : '3';
// Set assignment based on category
if (producer.category == 'network') {
current.assignment_group.setDisplayValue('Network Support');
} else {
current.assignment_group.setDisplayValue('Service Desk');
}javascript
// Record Producer: Report an Issue
// Table: incident
// Script:
// Map variables to incident fields
current.short_description = producer.short_description;
current.description = producer.description;
current.caller_id = gs.getUserID();
current.category = producer.category;
current.subcategory = producer.subcategory;
current.priority = producer.urgency == 'urgent' ? '2' : '3';
// Set assignment based on category
if (producer.category == 'network') {
current.assignment_group.setDisplayValue('Network Support');
} else {
current.assignment_group.setDisplayValue('Service Desk');
}Order Guides
订购指南
Multi-Step Request Wizard
多步骤申请向导
Order Guide: New Employee Onboarding
├── Step 1: Employee Information
│ └── Variable Set: Employee Details
├── Step 2: Hardware Selection
│ ├── Catalog Item: Laptop
│ ├── Catalog Item: Monitor
│ └── Catalog Item: Peripherals
├── Step 3: Software Requests
│ └── Rule: Show software based on department
├── Step 4: Access Requests
│ └── Cascade Variable: Copy employee info
└── Submit: Creates multiple RITMsOrder Guide: New Employee Onboarding
├── Step 1: Employee Information
│ └── Variable Set: Employee Details
├── Step 2: Hardware Selection
│ ├── Catalog Item: Laptop
│ ├── Catalog Item: Monitor
│ └── Catalog Item: Peripherals
├── Step 3: Software Requests
│ └── Rule: Show software based on department
├── Step 4: Access Requests
│ └── Cascade Variable: Copy employee info
└── Submit: Creates multiple RITMsOrder Guide Rule
订购指南规则
javascript
// Rule: Show software items based on department
function rule(item, guide_variables) {
var dept = guide_variables.department;
// Show engineering software only for Engineering
if (item.name == 'Engineering Software Suite') {
return dept == 'engineering';
}
// Show finance software only for Finance
if (item.name == 'Financial Tools') {
return dept == 'finance';
}
return true; // Show all other items
}javascript
// Rule: Show software items based on department
function rule(item, guide_variables) {
var dept = guide_variables.department;
// Show engineering software only for Engineering
if (item.name == 'Engineering Software Suite') {
return dept == 'engineering';
}
// Show finance software only for Finance
if (item.name == 'Financial Tools') {
return dept == 'finance';
}
return true; // Show all other items
}Pricing & Approvals
定价与审批
Dynamic Pricing
动态定价
javascript
// Catalog Item Script (Pricing)
// Runs when item is added to cart
var basePrice = parseFloat(current.price) || 0;
var quantity = parseInt(current.variables.quantity) || 1;
var expedited = current.variables.expedited == 'true';
var total = basePrice * quantity;
if (expedited) {
total *= 1.5; // 50% rush fee
}
current.recurring_price = 0;
current.price = total;javascript
// Catalog Item Script (Pricing)
// Runs when item is added to cart
var basePrice = parseFloat(current.price) || 0;
var quantity = parseInt(current.variables.quantity) || 1;
var expedited = current.variables.expedited == 'true';
var total = basePrice * quantity;
if (expedited) {
total *= 1.5; // 50% rush fee
}
current.recurring_price = 0;
current.price = total;Approval Rules
审批规则
Approval Definition: High-Value Purchases
Condition: total_cost > 5000
Approver: requested_for.manager
Wait for: Approval
Rejection action: Cancel requestApproval Definition: High-Value Purchases
Condition: total_cost > 5000
Approver: requested_for.manager
Wait for: Approval
Rejection action: Cancel requestBest Practices
最佳实践
- Variable Naming - Use descriptive, lowercase names (no spaces)
- Variable Sets - Reuse common variable groups
- Reference Qualifiers - Filter to relevant records only
- Client Scripts - Minimize server calls (use GlideAjax sparingly)
- Fulfillment - Create tasks, don't complete directly
- Testing - Test as different user roles
- Mobile - Test catalog items on mobile/tablet
- Documentation - Add help text to variables
- 变量命名 - 使用描述性的小写名称(无空格)
- 变量集 - 复用通用变量组
- 引用限定符 - 仅过滤相关记录
- 客户端脚本 - 减少服务器调用(谨慎使用GlideAjax)
- 执行 - 创建任务,不要直接完成
- 测试 - 以不同用户角色测试
- 移动端 - 在手机/平板上测试目录项
- 文档 - 为变量添加帮助文本