Quick recap of PM from my previous blog Open UI Customization - Part 1 - Intro
Presentation Model:
A presentation model is a single or set of JavaScript files that work with runtime(data generated at client-side) and metadata (data from server) and allow you to control and customize the logic, content and client interaction.
It determines the logic to apply, captures client interactions, such as the user leaving a control, collects field values, and sets properties. A presentation model can get Properties and Methods from the proxy, and then expose them for external use. It doesn’t do any rendering of physical HTML ( you know who handles that – yes PR)
Physical Renderer:
A physical renderer is a single or set of JavaScript files that Siebel Open UI uses to build the user interface. It allows you to use custom or third-party JavaScript code to render the user interface. It binds a presentation
model to a physical control.
Example email address validation: Let’s take a very simple example of validating email Id entered by user for a contact on Contact Form Applet at client side (no server trip). High level flow should be:
- user types in email id and steps off the field.
- email validation should happen at client side and error to be thrown to user if invalid email id.
Let’s first get the bird’s eye view of how to go about it.
- your business logic should go in PM layer
- You need to setup your PM to capture the event of user modifying email id and alert your PR to handle it. For that you will need a property – call it as – isEmailSet . Whenever user updates email id, isEmailSet will be set to true.
- Validating email id and throwing appropriate error should go in PR layer
- PR will trigger ValidateEmail() function whenever isEmailSet property is set by PM. ValidateEmail() function will evaluate the email id entered and will alert user if it is of wrong format.
- Applet PM template here - Template-AppletPM.js
- Applet PR template here - Template-AppletPR.js
Presentation Model for Contact Form Applet:
Let’s create copy the Template-AppletPM.js file into /custom and rename it as ContactPM.js. You need to store your file here: \PUBLIC\enu\FILES\<Siebel_Build>\SCRIPTS\siebel\custom\ContactPM.js
I have modified the template to look like below. Let’s give a close look at what I have done.
- It’s fine if you are not very conversant with JavaScript at this moment. Any text with Green font and gray background – you can ignore time being!
- I replaced MyJS text with ContactPM in the whole of the template file.
- Now, review below text with yellow background.
if( typeof( SiebelAppFacade.ContactPM ) === "undefined" ){ SiebelJS.Namespace( "SiebelAppFacade.ContactPM" ); define("siebel/custom/ContactPM", [], function () { SiebelAppFacade.ContactPM = (function () { function ContactPM (proxy) { SiebelAppFacade.ContactPM.superclass.constructor.call(this, proxy); } SiebelJS.Extend(ContactPM, SiebelAppFacade.PresentationModel); ContactPM.prototype.Init = function () { SiebelAppFacade.ContactPM.superclass.Init.call(this); this.AddProperty("isEmailSet", ""); this.AddMethod("FieldChange", OnFieldChange, { sequence: false, scope: this }); SiebelJS.Log("Model Init call"); }; function OnFieldChange(control, value) { SiebelJS.Log("Model OnFieldChange call for field:"+control.toString()); if (control.GetName() === "EmailAddress") { this.SetProperty("isEmailSet", (value ? true : false)); } } return ContactPM; } ()); return "SiebelAppFacade.ContactPM"; }); } |
- I added Property - isEmailSet
this.AddProperty("isEmailSet", "");
- I added a Method to track FieldChange event and call my function: OnFieldChange ()
this.AddMethod("FieldChange", OnFieldChange, { sequence: false, scope: this });
- Whenever user updates any field from UI, FieldChange event will call my OnFieldChange function. If user has updated EmailAddress control then, isEmailSet will be set to true.
- I added a custom function: OnFieldChange () – remember this function is getting called everytime a field is updated. So, first check if the control changed is EmailAddress, if so set isEmailSet to true
Physical Renderer for Contact Form Applet:
Let’s create copy the Template-AppletPR.js file into /custom and rename it as ContactPR.js. You need to store your file here: \PUBLIC\enu\FILES\<Siebel_Build>\SCRIPTS\siebel\custom\ContactPR.js
I have modified the template to look like below. Let’s give a close look at what I have done.
- It’s fine if you are not very conversant with JavaScript at this moment. Any text with Green font and gray background – you can ignore time being!
- I replaced MyJS text with ContactPR in the whole of the template file.
- Now, review below text with yellow background.
|
- In init method, I attached PM Property - isEmailSet to PR and whenever isEmailSet is set to true calls my function validateEmail
this.AttachPMBinding("isEmailSet", validateEmail);
- I added custom function: validateEmail() to validate email entered by user and throw appropriate error.
After adding ContactPM.js and ContactPR.js, all you need is to register them again Contact Form Applet and test. Follow below high level steps:
- Register .js files: Navigate to Sitemap –> Admin – Application –> Manifest Files and register your custom files here.
- Register ContactPM.js to Contact Form Applet:
- Navigate to Sitemap –> Admin – Application –> Manifest Administration and fill details as below:
- Register ContactPR.js to Contact Form Applet:
- Navigate to Sitemap –> Admin – Application –> Manifest Administration and fill details as below:
- Test!: Clear your browser cache and login to the application and test
Now the final bit to explain the text with Green font and gray background previously. NameSpace: Here Open UI maintains a list of objects instantiated in at the client side.
Let’s look at ContactPM.js
Step 1: Verify that ContactPM Object class doesn’t exist as you can have only one instance of class in JavaScript
if( typeof( SiebelAppFacade.ContactPM ) === "undefined" ){
Step 2: Add ContactPM to Siebel SiebelAppFacade NameSpace.
SiebelJS.Namespace( "SiebelAppFacade.ContactPM" );
Step3: Define custom Presentation model file location and other dependencies if any. Presently we have no dependencies hence []
define("siebel/custom/ContactPM", [], function () {
Step 4: Add ContactPM Constructor within the class
SiebelAppFacade.ContactPM = (function () {
Step 4.1: declare Class constructor as function function ContactPM (proxy) { Step 4.2: inherit super Class constructor to custom class SiebelAppFacade.ContactPM.superclass.constructor.call(this, proxy);
}
Step 4.3: declare your class as an extension of PM. Extended class now can access all prebuilt functions within default PM SiebelJS.Extend(ContactPM, SiebelAppFacade.PresentationModel); step 4.4: init method to add properties and methods ContactPM.prototype.Init = function () { SiebelAppFacade.ContactPM.superclass.Init.call(this); this.AddProperty("isEmailSet", ""); this.AddMethod("FieldChange", OnFieldChange, { sequence: false, scope: this }); SiebelJS.Log("Model Init call"); }; step 5: define custom methods here
function OnFieldChange(control, value) { SiebelJS.Log("Model OnFieldChange call for field:"+control.toString()); if (control.GetName() === "EmailAddress") { this.SetProperty("isEmailSet", (value ? true : false)); } } return ContactPM; } ()); return "SiebelAppFacade.ContactPM"; }); } |
Now, let’s look at ContactPR.js
Step 1: Verify that ContactPR Object class doesn’t exist as you can have only one instance of class in JavaScript
if( typeof( SiebelAppFacade.ContactPR ) === "undefined" ){
Step 2: Add ContactPR to Siebel SiebelAppFacade NameSpace.
SiebelJS.Namespace( "SiebelAppFacade.ContactPR" ); Step3: Define custom Physical Renderer file location and other dependencies if any. Presently we have no dependencies hence []
define("siebel/custom/ContactPR", ["order!siebel/phyrenderer"], function () { Step 4: Add ContactPR Constructor within the class
SiebelAppFacade.ContactPR = (function () { Step 4.1: declare Class constructor as function function ContactPR(pm) { Step 4.2: inherit super Class constructor to custom class SiebelAppFacade.ContactPR.superclass.constructor.call(this, pm); };
Step 4.3: declare your class as an extension of PR. Extended class now can access all prebuilt functions within default PR SiebelJS.Extend(ContactPR, SiebelAppFacade.PhysicalRenderer);
step 4.4: init method to Attach PM Binding ContactPR.prototype.Init = function () {
SiebelAppFacade.ContactPR.superclass.Init.call(this); SiebelJS.Log("ContactPR - Init call");
this.AttachPMBinding("isEmailSet", validateEmail);
};
step 5: define custom methods here
function validateEmail() { SiebelJS.Log("Contact PR - validateEmail");
var controls = this.GetPM().Get( "GetControls" );
var cntrl = controls[ "EmailAddress" ];
var emailcntrl = cntrl.GetInputName();
var email = $('input[name="'+emailcntrl+'"]').val();
var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
if(email == "") // If email is blank then don’t validate! return true;
alert("going to validate");
if( !emailReg.test( email ) ) {
alert("Please enter a valid Email");
return false;
}
else {
alert("This is a valid Email");
return true;
}
}
return ContactPR;
} ());
return "SiebelAppFacade.ContactPR";
});
}
|
I hope you enjoyed this thorough explanation for Applet PM and PR with a simple example. If so, please hit like! Let me know if you have any questions.
Shiv
No comments:
Post a Comment