Day 26: Working with Web Resources
Series: Learn Microsoft Dynamics 365 CRM Step-by-Step
A Roadmap from Fresher Developer to Solution Architect
Phase 3: Client-Side Development
Day 26 of 90 Days Learning Challenge
Introduction
Welcome back to our 90-Day Microsoft Dynamics 365 CRM Learning Journey.
In Day 25, we explored client-side development concepts and how JavaScript helps us improve the user experience inside model-driven apps. We discussed how a CRM form can become smarter by reacting to user actions, validating data, showing notifications, hiding or showing fields, and guiding users during business processes.
Today, in Day 26, we are going one step deeper into one of the most important customization building blocks in Dynamics 365 CRM and Power Apps model-driven apps:
Web Resources
If you are a fresher developer, web resources may look like “just files uploaded into CRM.” But as you grow toward a senior developer, technical consultant, or solution architect role, you will realize that web resources are much more than files.
They are reusable client-side assets that help you extend the CRM user interface, create custom logic, load images, build small HTML components, apply styling, and organize JavaScript libraries inside your Dataverse solution.
Microsoft describes web resources as virtual files stored in the Microsoft Dataverse database and retrieved through a unique URL. They can be used to extend model-driven apps with supported file types such as HTML, JavaScript, CSS, XML, images, and more. [learn.microsoft.com]
In simple words:
Web Resources are CRM-hosted files that help developers customize and extend the model-driven app user experience.
For example, you can use web resources to:
- Add JavaScript validation on forms.
- Show a custom HTML page inside a CRM form.
- Store images used by buttons, forms, or custom pages.
- Add CSS for styling an HTML web resource.
- Store JSON or XML configuration.
- Build small reusable UI widgets.
- Support ribbon or command bar customizations.
- Package front-end assets inside a managed or unmanaged solution.
By the end of this blog, you will understand web resources not just as a developer feature, but as an architectural component that must be designed carefully in enterprise CRM projects.
1. What Are Web Resources in Dynamics 365 CRM?
A web resource is a file that is uploaded and stored inside Dataverse as part of your solution. Once uploaded, it can be referenced from forms, dashboards, command bars, JavaScript event handlers, HTML pages, and other supported customization areas.
Microsoft documentation highlights that web resources are stored as solution components, which means they can be exported and moved between environments such as development, test, UAT, and production. [learn.microsoft.com]
This is very important in enterprise projects because every customization should follow proper ALM, or Application Lifecycle Management.
Think of web resources as your CRM application’s front-end toolbox.
Real-World Analogy
Imagine your Dynamics 365 CRM is a modern office building.
- Forms are the office rooms.
- Tables are the filing cabinets.
- Business rules are the instruction posters.
- JavaScript is the smart assistant.
- Web resources are the tools, screens, banners, images, and instruction panels installed inside the office.
Without web resources, your CRM form may only capture data. With well-designed web resources, your CRM form can guide users, validate inputs, display helpful UI, and create a better experience.
2. Why Web Resources Matter in Client-Side Development
In model-driven apps, forms are powerful, but every business requirement cannot be solved by configuration alone. Sometimes you need custom behavior.
For example:
- If a user selects “High Priority,” show a warning.
- If the customer type is “Business,” show extra fields.
- If the credit limit is above a threshold, ask for confirmation.
- If the case category is missing, prevent save.
- If a custom HTML dashboard is required inside the form, load it as a web resource.
- If an integration status needs to be displayed visually, use an HTML or image web resource.
This is where web resources come into the picture.
The most common web resource used by CRM developers is a JavaScript web resource. It contains functions that run on form events such as OnLoad, OnSave, OnChange, tab state change, or Business Process Flow events.
Microsoft recommends using the supported Client API object model for JavaScript customizations in model-driven apps. The documentation also states that only documented Client API objects and methods are supported, and unsupported internal APIs or direct DOM dependencies should not be used. [learn.microsoft.com]
That means a good developer should not randomly manipulate the CRM page using unsupported HTML DOM tricks. Instead, use supported objects such as:
executionContextformContextXrm.WebApiXrm.NavigationXrm.UtilityformContext.uiformContext.dataformContext.getAttributeformContext.getControl
This is the difference between a fresher script and an enterprise-grade client-side solution.
3. Types of Web Resources
Dynamics 365 CRM supports multiple types of web resources. Microsoft documentation lists web resources as files used to extend Dataverse web applications and includes types such as HTML, JavaScript, CSS, XML, XSL, RESX, and image formats. [learn.microsoft.com]
Let’s understand the most commonly used ones.
3.1 JavaScript Web Resources
JavaScript web resources are used to write client-side business logic.
Common examples:
- Form OnLoad logic.
- Field OnChange logic.
- Form OnSave validation.
- Field visibility logic.
- Notification logic.
- Lookup filtering.
- Command bar action logic.
- Calling Dataverse Web API from the client.
Example file name:
jsharma_/scripts/accountForm.jsExample usage:
function onAccountFormLoad(executionContext) {
var formContext = executionContext.getFormContext();
var accountName = formContext.getAttribute("name").getValue();
if (!accountName) {
formContext.ui.setFormNotification(
"Please enter Account Name before proceeding.",
"WARNING",
"account_name_warning"
);
}
}This script can be added to the Account form OnLoad event.
3.2 HTML Web Resources
HTML web resources are used when you want to show custom UI inside CRM.
Examples:
- Custom help panel.
- Embedded mini dashboard.
- Terms and conditions page.
- Custom status tracker.
- Integration response viewer.
- Custom wizard-like experience.
Example file name:
jsharma_/html/caseStatusPanel.htmlHTML web resources are static browser-processed files. Microsoft documentation clearly states that web resources are limited to static files or files processed by the browser and do not support ASP.NET server-side execution like .aspx pages. [learn.microsoft.com]
That means you cannot upload server-side code and expect it to run inside CRM as a backend application.
3.3 CSS Web Resources
CSS web resources are used to style HTML web resources.
Example file name:
jsharma_/css/casePanel.cssExample:
.status-card {
border-radius: 12px;
padding: 16px;
background-color: #f3f7ff;
border: 1px solid #c9dcff;
font-family: Segoe UI, Arial, sans-serif;
}
.status-title {
font-size: 18px;
font-weight: 600;
color: #1f4e79;
}CSS is mainly useful when building HTML web resources.
3.4 Image Web Resources
Image web resources are used to store icons, logos, and visual assets.
Examples:
- Command bar button icon.
- Custom help illustration.
- Status icons.
- Branding images.
- Small form guidance graphics.
Example file name:
jsharma_/images/highPriorityIcon.pngImages make CRM more user-friendly, especially when you want to explain processes visually.
3.5 XML, JSON, and RESX Web Resources
These are less common for beginners but important in enterprise projects.
XML or JSON
Used for configuration data.
Example:
{
"priorityThreshold": "High",
"showCreditWarning": true,
"maxCreditLimit": 100000
}RESX
Used for localization or multilingual labels.
For example, if your CRM application supports English, Hindi, Spanish, or French, RESX files may help manage localized text.
4. Web Resources Architecture Diagram
Below is a simple architecture diagram to understand how web resources fit into model-driven apps.
Diagram Explanation
When a user opens a CRM form, form events are triggered. These events can call JavaScript web resources. JavaScript uses supported Client API methods to interact with form attributes, controls, notifications, navigation, and Dataverse data.
If required, the form can also display an HTML web resource, which may use CSS and images to create a better user experience.
5. How Web Resources Are Used on CRM Forms
Let’s take a common example.
Scenario: Account Form Guidance
Business Requirement:
When an account form opens:
- Check whether Account Name is filled.
- Check whether Relationship Type is selected.
- If required fields are missing, show a warning notification.
- If Account Type is “Business,” show the Business Information section.
- If Account Type is “Individual,” hide the Business Information section.
This can be achieved using a JavaScript web resource.
var JSCRM = JSCRM || {};
JSCRM.Account = JSCRM.Account || {};
JSCRM.Account.onLoad = function (executionContext) {
var formContext = executionContext.getFormContext();
JSCRM.Account.validateRequiredFields(formContext);
JSCRM.Account.handleAccountTypeVisibility(formContext);
};
JSCRM.Account.validateRequiredFields = function (formContext) {
var accountName = formContext.getAttribute("name").getValue();
var relationshipType = formContext.getAttribute("customertypecode").getValue();
if (!accountName || !relationshipType) {
formContext.ui.setFormNotification(
"Please complete Account Name and Relationship Type.",
"WARNING",
"account_required_warning"
);
} else {
formContext.ui.clearFormNotification("account_required_warning");
}
};
JSCRM.Account.handleAccountTypeVisibility = function (formContext) {
var accountType = formContext.getAttribute("customertypecode").getValue();
var businessTab = formContext.ui.tabs.get("tab_business_information");
if (!businessTab) {
return;
}
if (accountType === 3) {
businessTab.setVisible(true);
} else {
businessTab.setVisible(false);
}
};What This Code Teaches
This simple example teaches important development principles:
- Use namespace-based JavaScript.
- Use
executionContext. - Use
formContext. - Avoid hardcoding logic everywhere.
- Keep functions small and reusable.
- Handle null checks.
- Use supported Client API methods.
Microsoft recommends using formContext instead of the deprecated Xrm.Page object for code targeting version 9.0 or later. The form context is obtained using executionContext.getFormContext(). [learn.microsoft.com]
6. Fresher Mistake: Using Xrm.Page Everywhere
Many beginners search old blogs and copy scripts using Xrm.Page.
Example:
var name = Xrm.Page.getAttribute("name").getValue();This may still work in some scenarios, but it is not the modern recommended approach.
Modern approach:
function onLoad(executionContext) {
var formContext = executionContext.getFormContext();
var name = formContext.getAttribute("name").getValue();
}Why is this important?
Because formContext makes your code more flexible. It allows the same function to work in different contexts, such as forms or editable grids, depending on where it is called. Microsoft documentation explains that form context provides a reference to the form or item where the current code is executed. [learn.microsoft.com]
7. Naming Convention for Web Resources
Naming convention is extremely important.
A poor naming convention creates confusion in large projects. A proper naming convention helps developers, testers, architects, and support teams understand the purpose of each file.
Recommended Naming Pattern
publisherprefix_/type/module/fileNameExamples:
jsharma_/scripts/account/accountForm.js
jsharma_/scripts/case/caseValidation.js
jsharma_/html/case/caseSummaryPanel.html
jsharma_/css/common/commonStyles.css
jsharma_/images/icons/highPriority.png
jsharma_/config/case/caseConfig.jsonWhy This Is Better
This structure helps you organize web resources by:
- Publisher prefix.
- Resource type.
- Business module.
- Purpose of the file.
As a Solution Architect, you should define this convention early in the project so that every developer follows the same structure.
8. Web Resource Lifecycle in a Project
A web resource usually follows this lifecycle:
Lifecycle Explanation
First, you understand the requirement. Then you decide whether configuration is enough or JavaScript is required. After that, you create the file, upload it as a web resource, attach it to the correct form event, test it properly, and include it in your solution deployment.
This sounds simple, but in enterprise projects, missing even one step can break production.
For example:
- JavaScript added to form but not added to solution.
- Function name entered incorrectly in event handler.
- Execution context not passed.
- Web resource updated but form not published.
- Browser cache still showing old script.
- Managed solution layering causing unexpected behavior.
These are common real-world issues.
9. How to Add a JavaScript Web Resource to a Form
Here is a practical step-by-step approach.
Step 1: Create Your JavaScript File
Create a file in your local development folder:
accountForm.jsAdd your function:
var JSCRM = JSCRM || {};
JSCRM.Account = JSCRM.Account || {};
JSCRM.Account.onLoad = function (executionContext) {
var formContext = executionContext.getFormContext();
formContext.ui.setFormNotification(
"Welcome to Account form. Please verify customer information.",
"INFO",
"welcome_message"
);
};Step 2: Upload Web Resource
In Power Apps maker portal:
- Go to your solution.
- Select New.
- Select More.
- Select Web resource.
- Choose JavaScript file.
- Provide name and display name.
- Save.
- Publish.
Step 3: Add Library to Form
- Open the table form.
- Go to form libraries.
- Add your JavaScript web resource.
- Select the form event, such as OnLoad.
- Add the function name:
JSCRM.Account.onLoad- Check Pass execution context as first parameter.
- Save and publish.
Step 4: Test
Open the Account form and confirm the notification appears.
10. Common Form Events Where JavaScript Web Resources Are Used
OnLoad
Runs when the form loads.
Use cases:
- Initialize form logic.
- Set default values.
- Show notifications.
- Hide or show tabs.
- Register additional event handlers.
OnChange
Runs when a field value changes.
Use cases:
- Validate entered data.
- Update dependent fields.
- Show or hide controls.
- Perform calculations.
OnSave
Runs when the record is saved.
Use cases:
- Prevent save if validation fails.
- Confirm important changes.
- Check required custom conditions.
Business Process Flow Events
Use cases:
- Validate before moving to next stage.
- Show warnings based on stage.
- Control process movement.
Tab State Change
Use cases:
- Load data only when a tab is expanded.
- Improve performance by delaying heavy logic.
11. HTML Web Resource Example
Let’s say the business wants a simple “Case Integration Status Panel” on the Case form.
The panel should show:
- Case created.
- API request received.
- External system updated.
- Response received.
You can create an HTML web resource:
<!DOCTYPE html>
<html>
<head>
<title>Case Integration Status</title>
../css/caseStatus.css
</head>
<body>
<div class="status-card">
<h2>Case Integration Status</h2>
<ul>
<li>Case Created</li>
<li>API Request Received</li>
<li>External System Update Pending</li>
<li>Response Awaited</li>
</ul>
</div>
</body>
</html>And CSS:
CSS
body {
font-family: Segoe UI, Arial, sans-serif;
background-color: #ffffff;
}
.status-card {
border: 1px solid #d0d7de;
border-radius: 12px;
padding: 16px;
background-color: #f8fbff;
}
h2 {
color: #0f6cbd;
}This HTML web resource can be embedded on a CRM form.
Important Note
HTML web resources are useful, but do not overuse them. If you need complex, reusable, component-based UI, consider modern options such as Power Apps Component Framework or custom pages where appropriate. Microsoft documentation notes that Power Apps component framework and custom pages are generally better options for configurable, reusable, and tighter external integrations. [learn.microsoft.com]
12. Web Resources and Dataverse Web API
Sometimes JavaScript web resources need to read or update Dataverse data.
For that, you can use Xrm.WebApi.
The Dataverse Web API provides a RESTful API based on OData v4 and can be used to work with Dataverse data across different languages, platforms, and devices. [learn.microsoft.com]
Get Jitendra Sharma’s stories in your inbox
Join Medium for free to get updates from this writer.
Example:
JSCRM.Account.retrievePrimaryContact = function (formContext) {
var contactLookup = formContext.getAttribute("primarycontactid").getValue();
if (!contactLookup || contactLookup.length === 0) {
return;
}
var contactId = contactLookup[0].id.replace("{", "").replace("}", "");
Xrm.WebApi.retrieveRecord(
"contact",
contactId,
"?$select=fullname,emailaddress1,telephone1"
).then(
function success(result) {
console.log("Contact Name: " + result.fullname);
console.log("Email: " + result.emailaddress1);
},
function error(error) {
console.log(error.message);
}
);
};Architect-Level Thinking
Before calling Dataverse Web API from JavaScript, ask:
- Is the data already available on the form?
- Can this be done with configuration?
- Is this call required on form load?
- Will it slow down the user experience?
- Should this logic be server-side instead?
- What happens if the API call fails?
- Do we need error logging?
- Are security roles respected?
Client-side calls are powerful, but poor usage can affect performance.
13. Performance Best Practices for Web Resources
Performance is one of the biggest differences between beginner-level customization and enterprise-grade customization.
13.1 Do Not Load Unnecessary JavaScript
If JavaScript is not required on a form, do not add it.
Wrong approach:
- Add one big common JavaScript library to every form.
Better approach:
- Add only required libraries to each form.
- Keep logic modular.
- Use common utility libraries carefully.
13.2 Avoid Heavy Logic on Form Load
Form load should be fast.
Avoid:
- Multiple API calls.
- Complex loops.
- Large HTML rendering.
- Unnecessary notifications.
- Synchronous logic.
Better:
- Load only critical logic first.
- Delay non-critical logic.
- Execute logic on tab expand or field change when possible.
13.3 Use Namespaces
Avoid global function conflicts.
Bad:
function onLoad(executionContext) {
}Better:
var JSCRM = JSCRM || {};
JSCRM.Case = JSCRM.Case || {};
JSCRM.Case.onLoad = function (executionContext) {
};13.4 Handle Errors Gracefully
Bad:
var value = formContext.getAttribute("new_field").getValue();If the field is not on the form, this can fail.
Better:
var attribute = formContext.getAttribute("new_field");
if (attribute) {
var value = attribute.getValue();
}13.5 Avoid Unsupported DOM Manipulation
Do not depend on internal CRM HTML elements. Microsoft documentation warns that unsupported internal APIs and DOM-dependent scripts may change without notice, and only documented Client API objects and methods are supported. [learn.microsoft.com]
14. Security Considerations
Web resources run in the user’s browser and under the Dataverse web application security context. Microsoft documentation explains that web resources can be accessed only through the Dataverse web application security context and require licensed users with necessary privileges. [learn.microsoft.com]
But remember:
Client-side code is visible to users with browser developer tools.
So never store:
- Passwords.
- Client secrets.
- API keys.
- Sensitive business rules that must be hidden.
- Security bypass logic.
- Confidential integration credentials.
If logic is security-sensitive, move it to:
- Plugin.
- Custom API.
- Power Automate with secure connections.
- Azure Function with proper authentication.
- Server-side Dataverse logic.
Important Rule
Client-side JavaScript improves user experience. It should not be your security boundary.
15. Web Resources vs PCF vs Custom Pages
As you grow toward Solution Architect, you must know when not to use web resources.
Use Web Resources When
- Requirement is simple JavaScript form logic.
- You need a small HTML page.
- You need image or CSS assets.
- You need lightweight customization.
- You need form event handling.
Use PCF When
- You need reusable UI controls.
- You need rich component behavior.
- You need dataset control.
- You need modern component lifecycle.
- You need a professional reusable UI element.
Use Custom Pages When
- You need a full app-like experience.
- You need canvas-style flexibility inside model-driven apps.
- You need richer user interaction.
- You need a custom business screen.
Microsoft documentation also indicates that Power Apps component framework and custom pages are generally preferred for configurable, reusable, and tighter external integrations compared with some web resource scenarios. [learn.microsoft.com]
16. Real-World Use Case: Case Priority Warning
Let’s build a simple real-world scenario.
Requirement
When a support agent changes Case Priority to High:
- Show a warning.
- Ask user to confirm escalation.
- If confirmed, show escalation section.
- If not confirmed, reset priority to Medium.
JavaScript Example
var JSCRM = JSCRM || {};
JSCRM.Case = JSCRM.Case || {};
JSCRM.Case.onPriorityChange = function (executionContext) {
var formContext = executionContext.getFormContext();
var priorityAttribute = formContext.getAttribute("prioritycode");
if (!priorityAttribute) {
return;
}
var priorityValue = priorityAttribute.getValue();
var highPriority = 1;
var mediumPriority = 2;
if (priorityValue === highPriority) {
var confirmStrings = {
title: "Confirm High Priority",
text: "You selected High Priority. Do you want to escalate this case?",
confirmButtonLabel: "Yes, Escalate",
cancelButtonLabel: "No"
};
var confirmOptions = {
height: 220,
width: 450
};
Xrm.Navigation.openConfirmDialog(confirmStrings, confirmOptions).then(
function (success) {
if (success.confirmed) {
JSCRM.Case.showEscalationSection(formContext, true);
formContext.ui.setFormNotification(
"High priority case marked for escalation.",
"WARNING",
"high_priority_warning"
);
} else {
priorityAttribute.setValue(mediumPriority);
JSCRM.Case.showEscalationSection(formContext, false);
}
}
);
}
};
JSCRM.Case.showEscalationSection = function (formContext, isVisible) {
var tab = formContext.ui.tabs.get("tab_escalation");
if (tab) {
tab.setVisible(isVisible);
}
};What This Use Case Teaches
This example teaches:
- Event-driven client-side development.
- Confirmation dialogs.
- Form notifications.
- Tab visibility.
- Clean function separation.
- User-guided CRM experience.
17. Animated Flow Diagram: Case Priority Logic
18. Common Errors While Working with Web Resources
Error 1: Function Not Found
Cause:
- Wrong function name.
- Namespace mismatch.
- JavaScript library not added to form.
- File not published.
Fix:
- Verify exact function name.
- Check browser console.
- Confirm library is added.
- Publish all customizations.
Error 2: Execution Context Missing
Cause:
- “Pass execution context as first parameter” not checked.
Fix:
- Open event handler.
- Check the execution context option.
Error 3: Field Not Found
Cause:
- Field is not available on form.
- Wrong schema name.
- Field is inside quick view or different context.
Fix:
- Use correct schema name.
- Add null checks.
- Confirm the field exists on the form.
Error 4: Old Script Still Running
Cause:
- Browser cache.
- CRM caching.
- Incorrect file version.
- Solution layering.
Fix:
- Clear cache.
- Hard refresh.
- Change file version or publish.
- Verify solution layers.
Error 5: Unsupported DOM Manipulation Breaks After Update
Cause:
- Code depends on CRM internal HTML.
Fix:
- Use supported Client API only.
19. Debugging Web Resources
Debugging is a must-have skill for CRM developers.
Useful Debugging Techniques
Use Browser Developer Tools
Open browser developer tools and check:
- Console errors.
- Network requests.
- Loaded JavaScript files.
- API call responses.
Add Console Logs
console.log("Account OnLoad started");
console.log("Account Type:", accountType);Use debugger
debugger;When developer tools are open, code execution pauses at this line.
Check Event Handler Configuration
Always verify:
- Library selected.
- Function name correct.
- Execution context passed.
- Event selected correctly.
- Form published.
Check Solution Layers
If your changes are not reflecting, check whether another managed layer is overriding behavior.
20. Web Resource Design Checklist
Before moving your web resource to UAT or production, review this checklist.
Developer Checklist
- Is the file name following naming convention?
- Is the code using namespace?
- Is
executionContextused correctly? - Is
formContextused instead ofXrm.Page? - Are null checks added?
- Are errors handled?
- Are unnecessary console logs removed?
- Is the script added only where required?
- Is the correct function mapped to the event?
- Is the solution published?
Functional Checklist
- Does the logic match the business requirement?
- Is the user message clear?
- Are mandatory validations working?
- Are edge cases tested?
- Is the behavior tested for create and update forms?
- Is the behavior tested for different security roles?
- Is the behavior tested in UAT?
Architect Checklist
- Is web resource the correct option?
- Should this be configuration, plugin, PCF, or Power Automate instead?
- Is the script reusable?
- Is performance acceptable?
- Is there any security risk?
- Is the logic maintainable?
- Is the solution ALM-friendly?
- Is the code documented?
- Is there a rollback plan?
21. From Fresher Developer to Solution Architect Thinking
A fresher developer asks:
“How do I write JavaScript?”
A senior developer asks:
“How do I write reusable and maintainable JavaScript?”
A solution architect asks:
“Should this logic be JavaScript, plugin, business rule, Power Automate, PCF, custom page, or configuration?”
This is the mindset shift.
Web resources are powerful, but they should not be used for everything.
Example Decision Matrix
| Requirement | Recommended Approach |
| -------------------------------------------- | ---------------------------------- |
| Show or hide field based on simple condition | Business Rule or JavaScript |
| Complex client-side validation | JavaScript Web Resource |
| Reusable rich UI control | PCF |
| Full custom business screen | Custom Page |
| Server-side validation | Plugin |
| Long-running process | Power Automate or backend service |
| Secure integration logic | Plugin, Custom API, Azure Function |
| Form notification | JavaScript Web Resource |22. Best Practices Summary
Here are the key best practices you should remember.
Web Resource Best Practices
- Use proper naming conventions.
- Keep JavaScript modular.
- Use namespaces.
- Use
formContext, notXrm.Page. - Always pass execution context.
- Add null checks.
- Avoid unsupported DOM manipulation.
- Do not store secrets in JavaScript.
- Keep form load lightweight.
- Use
Xrm.WebApicarefully. - Add meaningful user messages.
- Avoid duplicate logic.
- Keep common utility functions separate.
- Test with different roles and form types.
- Include web resources in solutions.
- Publish after changes.
- Follow ALM process.
- Document event mappings.
- Use PCF or custom pages for complex UI.
- Think like an architect, not just a coder.
23. Practice Exercise for Day 26
Try this hands-on exercise.
Requirement
On the Contact form:
- On form load, show an information notification:
- “Please validate email and phone before saving.”
2. On Email field change:
- If email is empty, show warning.
- If email has value, clear warning.
3. On Save:
- If both Email and Mobile Phone are empty, prevent save.
Suggested JavaScript Structure
var JSCRM = JSCRM || {};
JSCRM.Contact = JSCRM.Contact || {};
JSCRM.Contact.onLoad = function (executionContext) {
var formContext = executionContext.getFormContext();
formContext.ui.setFormNotification(
"Please validate email and phone before saving.",
"INFO",
"contact_info"
);
};
JSCRM.Contact.onEmailChange = function (executionContext) {
var formContext = executionContext.getFormContext();
var email = formContext.getAttribute("emailaddress1").getValue();
if (!email) {
formContext.ui.setFormNotification(
"Email address is missing.",
"WARNING",
"email_warning"
);
} else {
formContext.ui.clearFormNotification("email_warning");
}
};
JSCRM.Contact.onSave = function (executionContext) {
var formContext = executionContext.getFormContext();
var eventArgs = executionContext.getEventArgs();
var email = formContext.getAttribute("emailaddress1").getValue();
var mobile = formContext.getAttribute("mobilephone").getValue();
if (!email && !mobile) {
eventArgs.preventDefault();
formContext.ui.setFormNotification(
"Please provide either Email or Mobile Phone before saving.",
"ERROR",
"contact_save_error"
);
}
};What You Should Learn
After completing this exercise, you should understand:
- How to create a JavaScript web resource.
- How to register OnLoad, OnChange, and OnSave events.
- How to use execution context.
- How to show form notifications.
- How to prevent save.
- How to apply client-side validation.
24. Visual Summary
25. Key Takeaways
Web resources are one of the most important client-side customization features in Dynamics 365 CRM and model-driven apps.
They help you extend the CRM user experience using JavaScript, HTML, CSS, images, and configuration files.
For a fresher developer, web resources are the starting point for learning real CRM customization. For a senior developer, they are reusable assets that must be structured properly. For a solution architect, they are one option in a larger design toolbox that also includes business rules, plugins, Power Automate, PCF, custom pages, and integrations.
If you want to grow from fresher developer to solution architect, do not just learn how to upload a JavaScript file. Learn when to use web resources, when to avoid them, how to structure them, how to secure them, and how to design maintainable client-side solutions.
Coming Next
In Day 27, we will continue our client-side development journey with a very exciting topic:
Day 27: Ribbon Workbench Introduction and Command Bar Customization
We will learn how buttons and commands work in Dynamics 365 CRM, how command bar customization improves user productivity, and how developers can create custom actions for real business scenarios.
See you tomorrow in Day 27: Ribbon Workbench Introduction and Command Bar Customization 🚀
Author: Jitendra Sharma
A Roadmap from Fresher Developer to Solution Architect
Series: Learn Microsoft Dynamics 365 CRM Step-by-Step
Day: 26 of 90 Days Learning Challenge
Microsoft Dynamics 365 Dynamics 365 CRM Power Platform Dataverse Model Driven Apps Web Resources JavaScript Client Side Development CRM Customization Power Apps Solution Architect CRM Developer Microsoft Business Applications










