本文介绍如何在 dynamics 365 模型驱动应用中,通过自定义 html/javascript 弹窗(web resource)让用户即时填写必填字段(如选项集),并将输入值安全回传至主表单,避免强制跳转到关联实体表单。
本文介绍如何在 dynamics 365 模型驱动应用中,通过自定义 html/javascript 弹窗(web resource)让用户即时填写必填字段(如选项集),并将输入值安全回传至主表单,避免强制跳转到关联实体表单。
在 Dynamics 365 中,当业务流程要求用户在提交前必须填写某字段(例如“赢取原因”“解决备注”等选项集或文本字段)时,简单弹出提示框(alert() 或 Xrm.Navigation.openAlertDialog)无法满足“现场编辑+即时回填”的需求。正如问题所示,直接跳转至 Opportunity Close 或 Case Resolution 等关联实体表单(如点击“赢取”触发的独立窗体)虽是系统默认行为,但用户体验割裂、上下文丢失,且不适用于需轻量级干预的场景。
✅ 推荐方案:使用 Xrm.Navigation.openWebResource 加载自定义弹窗
该方法支持加载嵌入式 HTML 页面(Web Resource),可完全自定义 UI(含下拉选项集、输入框、验证逻辑),并通过 window.parent.Xrm API 安全访问并更新主表单字段。
<!DOCTYPE html><html><head> <title>填写必填字段</title> <meta charset="utf-8" /> <style> body { font-family: 'Segoe UI', sans-serif; padding: 20px; } label { display: block; margin: 10px 0 4px; } select, input { width: 100%; padding: 6px; border: 1px solid #ccc; } button { margin-top: 15px; padding: 8px 16px; background: #0078d4; color: white; border: none; cursor: pointer; } </style></head><body> <h3>请填写以下字段后继续</h3> <label for="reasonSelect">赢取原因 *</label> <select id="reasonSelect"> <option value="">-- 请选择 --</option> <option value="1">战略客户签约</option> <option value="2">价格优势中标</option> <option value="3">技术方案领先</option> </select> <button onclick="submitAndClose()">确认并返回</button> <script> function submitAndClose() { const select = document.getElementById("reasonSelect"); const value = select.value; if (!value) { alert("请选择赢取原因!"); return; } try { // 获取父页面 Xrm 对象(Dynamics 365 客户端 API) const parentXrm = window.parent.Xrm; if (parentXrm && parentXrm?.getFormContext) { const formContext = parentXrm.getFormContext(); // 更新主表单字段(此处为 optionset 字段,逻辑名假设为 'new_winningreason') formContext.getAttribute("new_winningreason")?.setValue(parseInt(value)); formContext.data.refresh(false); // 可选:刷新字段显示 } window.close(); // 关闭弹窗 } catch (e) { alert("回填失败:" + e.message); } } </script></body></html>
发布 Web Resource 并获取唯一名称(如 new_/html/fieldPrompt.html)
在主表单 JavaScript 中触发弹窗
在按钮事件(如“赢取”前校验)或 onSave 事件中调用:
function openFieldPrompt(executionContext) { const formContext = executionContext.getFormContext(); const reasonAttr = formContext.getAttribute("new_winningreason"); // 若字段为空,则弹出自定义窗体 if (!reasonAttr?.getValue()) { const webResourceName = "new_/html/fieldPrompt.html"; const windowOptions = { height: 300, width: 500, position: 1 // 1 = center }; Xrm.Navigation.openWebResource(webResourceName, windowOptions); }}
通过该方案,你既保留了原生表单的完整性,又实现了轻量、可控、可复用的字段补录体验——真正让弹窗“有用”,而不只是“有声”。