Dynamics 365中JavaScript点击Finished按钮标记约会为Completed失效求助
Fix: Appointment Reverts to Original Status After Marking as Completed via JavaScript in Dynamics 365
Let's break down why your code is causing the status to revert and fix it step by step.
Root Causes of the Issue
- Missing Form Save: Your code sets the
statecodeandstatuscodevalues but never saves the form. Without saving, the changes are only temporary and will revert when the form refreshes or system processes run. - Event Timing Conflict: When you click the "Finished" button, Dynamics 365 runs its own internal logic to update the process status. Your code might be executing before this logic completes, leading to your changes being overwritten.
- Deprecated API Usage:
Xrm.Pageis deprecated in newer Dynamics 365 versions—using the modernformContextAPI is more reliable and avoids potential compatibility issues.
Updated Code Solutions
Option 1: Modern API (Recommended)
This uses formContext (the supported replacement for Xrm.Page) and adds proper saving + delay to avoid conflicts:
function OnLoad(executionContext) { const formContext = executionContext.getFormContext(); formContext.data.process.addOnProcessStatusChange(statusOnChange, formContext); } function statusOnChange(executionContext) { const formContext = executionContext.getFormContext(); const processStatus = formContext.data.process.getStatus(); if (processStatus === "finished") { // Delay execution to let system process the status change first setTimeout(() => markAsComplete(formContext), 500); } } function markAsComplete(formContext){ const stateCodeAttr = formContext.getAttribute("statecode"); const statusCodeAttr = formContext.getAttribute("statuscode"); if (stateCodeAttr && statusCodeAttr) { // Optional: Verify your status codes match your environment's configuration // console.log("State Code options:", stateCodeAttr.getOptions()); // console.log("Status Code options:", statusCodeAttr.getOptions()); stateCodeAttr.setValue(1); stateCodeAttr.setSubmitMode("always"); statusCodeAttr.setValue(3); statusCodeAttr.setSubmitMode("always"); // Save the form to persist changes formContext.data.save().then( () => console.log("Appointment marked as completed successfully!"), (error) => { console.error("Save failed:", error); alert("Failed to mark appointment as completed. Check logs for details."); } ); } else { alert("State Code or Status Code fields are missing from the form."); } }
Option 2: Legacy API (For Older Environments)
If you're stuck using Xrm.Page, this modified version fixes the core issues:
function OnLoad() { Xrm.Page.data.process.addOnProcessStatusChange(statusOnChange); } function statusOnChange() { const processStatus = Xrm.Page.data.process.getStatus(); if (processStatus === "finished") { setTimeout(markAsComplete, 500); } } function markAsComplete(){ const stateCodeAttr = Xrm.Page.getAttribute("statecode"); const statusCodeAttr = Xrm.Page.getAttribute("statuscode"); if (stateCodeAttr && statusCodeAttr) { stateCodeAttr.setValue(1); stateCodeAttr.setSubmitMode("always"); statusCodeAttr.setValue(3); statusCodeAttr.setSubmitMode("always"); // Save to persist changes Xrm.Page.data.save().then( () => console.log("Appointment saved as completed."), (error) => { console.error("Error saving:", error); alert("Failed to update appointment status."); } ); } else { alert("State Code or Status Code fields are not on the form."); } }
Key Fixes Explained
- Form Save: Calling
formContext.data.save()(orXrm.Page.data.save()) ensures your status changes are written to the database instead of being temporary. - Delay Execution: The
setTimeoutgives Dynamics 365 time to finish its internal process status updates before your code runs, preventing your changes from being overwritten. - Status Code Validation: Uncomment the
console.loglines to check if yourstatecode=1andstatuscode=3actually map to the "Completed" status in your environment—some customizations might change these values.
Additional Checks
- User Permissions: Make sure the user has permission to update the appointment's status (check security roles for "Write" access to the Appointment entity and status transitions).
- Conflicting Scripts/Plugins: Verify no other form scripts or plugins are modifying the appointment status after your code runs.
- Event Registration: Ensure the
OnLoadfunction is properly registered on the appointment form's OnLoad event (and passes the execution context if using the modern API).
内容的提问来源于stack exchange,提问作者MswatiLomnyama
相关产品推荐
相关产品推荐

