Beyond the Applet: Architects Guide to Modernizing Siebel CRM with Redwood UX & Web Component Framework
If you have spent any time in the enterprise software ecosystem over the last decade, you’ve likely noticed a massive shift. The era of clunky, rigid, and gray-on-gray back-office interfaces is dead. Modern enterprise users expect their business tools to look, feel, and react like top-tier consumer applications.
For years, Siebel CRM developers relied on Open UI, Custom PR/PM injections, and raw jQuery manipulation to bend the interface to their will. While powerful, this approach often led to brittle codebases, deep upgrade friction, and thousands of lines of manual DOM manipulation.
Enter the Siebel Web Component Framework (WCF) coupled with Oracle JET and Redwood UX.
This paradigm shift marks the transition from old-school, server-rendered views to a highly deterministic, declarative, JSON-driven UI architecture powered under the hood by the reactivity of Knockout.js.
The Architecture: Under the Hood of Modern Siebel UI
To understand the power of this framework, we must look at how it abstracts complexity. Instead of writing custom HTML layout files and heavy JavaScript renderers, the UI is now modeled as a digital twin via a JSON specification.
The magic happens through a highly decoupled three-layer communication chain:
- Knockout.js: The core reactive engine. It manages the Model-View-ViewModel (MVVM) bindings, tracking state changes via
observablesand updating the DOM automatically. - Oracle JET: Oracle’s enterprise-grade UI toolkit. It provides the actual web components (
oj-form-layout,oj-select-single, etc.) styled with the Redwood UX design system guidelines. - Siebel Web Component Framework: The bridge. It parses the JSON config, fetches metadata from the Siebel Business Components (BC), and binds Siebel actions to the client-side ViewModels.
Anatomy of a Maximum JSON Specification
In this architecture, the JSON config doesn’t just list fields—it fully describes the container layouts, adaptive break-points, client-side validation rules, data providers, and localized strings.
Here is what a complete, enterprise-grade JSON specification looks like for a Financial Deal Management form:
{
"$schema": "[http://json-schema.org/draft-07/schema#](http://json-schema.org/draft-07/schema#)",
"componentId": "fins_corporate_deal_applet",
"type": "oj-form-layout",
"version": "2.4.0",
"context": {
"siebelView": "FINS Corporate Deal View",
"siebelApplet": "FINS Deal Ephemeral Form Applet",
"businessComponent": "FINS Corporate Deal",
"responsive": {
"sm": { "maxColumns": 1, "labelEdge": "top" },
"md": { "maxColumns": 2, "labelEdge": "start" },
"lg": { "maxColumns": 3, "labelEdge": "start" }
}
},
"properties": {
"labelWidth": "33%",
"direction": "row"
},
"dataProviders": {
"currencyConverter": {
"type": "oj.ValidationGroup",
"options": { "style": "currency", "currency": "EUR", "currencyDisplay": "symbol" }
},
"riskLevelLovProvider": {
"type": "ArrayDataProvider",
"source": "SiebelLOV",
"lovType": "FINS_RISK_LEVEL",
"cache": "session"
}
},
"fields": [
{
"id": "field_deal_name",
"type": "oj-input-text",
"bcField": "Name",
"labelHint": "Deal Name",
"value": "[[Name]]",
"required": "[[isFieldRequired]]",
"disabled": "[[isReadOnlyMode]]",
"validators": [
{
"type": "regExp",
"options": { "pattern": "[A-Z0-9_]{5,}", "messageDetail": "Minimum 5 uppercase characters required." }
}
]
},
{
"id": "field_amount",
"type": "oj-input-number",
"bcField": "Deal Amount",
"labelHint": "Deal Amount",
"value": "[[DealAmount]]",
"properties": {
"converter": "[[currencyConverter]]"
}
},
{
"id": "field_risk_level",
"type": "oj-select-single",
"bcField": "Risk Level",
"labelHint": "Risk Assessment",
"value": "[[RiskLevel]]",
"properties": {
"data": "[[riskLevelLovProvider]]",
"itemText": "label"
}
}
],
"actions": [
{
"id": "toolbar_main",
"type": "oj-toolbar",
"items": [
{
"id": "btn_submit",
"type": "oj-button",
"label": "Submit Deal",
"chroming": "callToAction",
"onClick": "[[handleInvokeMethod('SubmitForApproval')]]",
"disabled": "[[isSubmitDisabled]]"
}
]
}
],
"expressions": {
"isSubmitDisabled": "[[DealAmount]] < 10000 || [[Status]] === 'Active'",
"isFieldRequired": "[[DealType]] === 'Credit Line'"
}
}
Turning JSON into Reality: The HTML Template & ViewModel
When the Web Component Framework reads this JSON configuration string—typically stored within an Applet User Property like WebComponentConfig inside Siebel Web Tools—it renders a perfectly tailored, reactive HTML structure.
- The HTML Template Output
The runtime engine produces declarative, standards-compliant web components. Notice how variables like [[DealAmount]] plug right into the custom elements:
<div class="oj-web-component-layout redwood-theme">
<oj-form-layout id="fins_corporate_deal_applet" max-columns="2" label-edge="start">
<oj-input-text id="field_deal_name" value="[[Name]]" label-hint="Deal Name" required="[[isFieldRequired]]" disabled="[[isReadOnlyMode]]"></oj-input-text>
<oj-input-number id="field_amount" value="[[DealAmount]]" label-hint="Deal Amount" converter="[[currencyConverter]]"></oj-input-number>
<oj-select-single id="field_risk_level" value="[[RiskLevel]]" label-hint="Risk Assessment" data="[[riskLevelLovProvider]]" item-text="label"></oj-select-single>
</oj-form-layout>
<div class="oj-flex oj-sm-justify-content-flex-end mt-4">
<oj-button id="btn_submit" chroming="callToAction" on-oj-action="[[handleMenuAction]]" disabled="[[isSubmitDisabled]]">
<span><oj-bind-text value="Submit Deal"></oj-bind-text></span>
</oj-button>
</div>
</div>
2. The Presentation Model (PM) Layer
Behind the scenes, the Presentation Model handles data routing. Using ko.computed and built-in Oracle JET providers, the JavaScript context wires client inputs straight back to the Siebel business layer without heavy RPC roundtrips for basic logic:
// Inside your custom Siebel Presentation Model / View Model context
define(['ojs/ojarraydataprovider', 'knockout'], function(ArrayDataProvider, ko) {
return function() {
this.Init = function() {
// 1. Initialize reactive observables for form states
this.AddProperty("DealAmount", ko.observable(0));
this.AddProperty("Status", ko.observable("Draft"));
this.AddProperty("RiskLevel", ko.observable("Medium"));
// 2. Instantiate the LOV Data Provider from Siebel repository cache
var rawLovData = [
{ value: "High", label: "High Risk Profile" },
{ value: "Medium", label: "Medium Risk Profile" },
{ value: "Low", label: "Low Risk Profile" }
];
this.AddProperty("riskLevelLovProvider", new ArrayDataProvider(rawLovData, { keyAttributes: 'value' }));
// 3. Evaluate conditional expressions reactively
this.AddProperty("isSubmitDisabled", ko.computed(function() {
return this.GetProperty("DealAmount")() < 10000 || this.GetProperty("Status")() === "Active";
}, this));
// 4. Map the UI actions directly to Siebel Server execution channels
this.handleMenuAction = function(event) {
SiebelApp.S_App.GetActiveView().GetActiveApplet().InvokeMethod("SubmitForApproval");
};
};
};
});
Key Takeaways for Siebel Architects
Shifting your architecture to the Web Component Framework offers massive advantages over custom jQuery patches:
Zero DOM Manipulation: Knockout.js acts as the traffic controller. You modify the data in the model, and the view updates automatically. No more $(‘#field_id’).hide().
Client-Side Speed: Conditional calculations (expressions), validation patterns (validators), and localized lists operate completely within the user’s browser, freeing up valuable Siebel Application Server resources.
Streamlined Upgrades: Because your presentation layer is declared cleanly as a JSON specification, your configurations remain safely decoupled from internal Siebel engine schema changes.
Looking Forward
The future of Siebel CRM isn’t just about maintaining data records—it’s about maximizing employee efficiency through seamless user experiences. Embracing the declarative power of Oracle JET web components wrapped in the Redwood UX aesthetic allows engineering teams to construct modern, pixel-perfect, lightning-fast enterprise workspaces that feel truly native.
