Sunday, 20 January 2013

adding voice input in siebel openUI :: Physical Render experiement


Please Note: Here we are using a webkit property. That means this feature will work only in google chrome.
Google chrome supports it's own voice search property. We can add this property to our application by adding "x-webkit-speech" in our input fields. Here we can create a physical render and implement this feature.


<!-------------------CODE Begins----------------------------!>

if( typeof( SiebelAppFacade.GoogleVoicePR ) === "undefined" ){
    SiebelJS.Namespace( "SiebelAppFacade.GoogleVoicePR" );
   
    SiebelApp.S_App.RegisterConstructorAgainstKey( "GoogleVoicePRenderer", "SiebelAppFacade.GoogleVoicePR" );
   
    SiebelAppFacade.GoogleVoicePR = ( function(){
       
       
        function GoogleVoicePR( pm ){
            SiebelAppFacade.GoogleVoicePR.superclass.constructor.call( this, pm );
            var controls = this.GetPM().Get( "GetControls" );
            var cntrl = controls[ "Last Name" ];   
            var lastNameCntrl  = cntrl.GetInputName();
            $('input[name="'+lastNameCntrl+'"]').attr("x-webkit-speech","x-webkit-speech");

        }
       
        SiebelJS.Extend( GoogleVoicePR, SiebelAppFacade.PhysicalRenderer );
       
        return GoogleVoicePR;
    }());
}


<!-------------------Code Ends------------------------------!>

Thursday, 17 January 2013

Mapping & Finishing customization (Part – 4)



This is our final steps in this customization. Here we are going to Map our custom physical render & Physical Model.  We are validating the EmailAddress field in contact form applet.
We are mapping our Key. Hope you remember our key, that we used to register.


So in tools go to contact  form applet.
Expand Applet user property
1.       Create a new user property Name -> Physical_Render and Render Key as its value (Shown in fig)
Another user property Physical_Model and Model key as its  value.
Compile Object.
2.       Now Copy our code (Physical Render & Physical model )to SCRIPTS->Siebel->custom folder
3.       Open OBJECTS Folder. There you can see “manifest_extensions.map”. Open  this in a notepad or wordpad.  Map our Key with applet.

4.       Open “custom_manifest.xml” in the same folder.
Find  <PLATFORM_KEY_SPECIFIC>
                                <PLATFORM Name="Desktop">
Here we map our physical render
Open a new node and write our file name as shown in fig

Find <KEY_COMMON>
Here we map our physical Model
And map our new key as shown in fig.


Now we finished everything. Make sure that you compiled applet. Clear your browser cache.  And launch application and change your email. Hope everything works well.

Coding Physical Render(Part -3)




I have given three color for code. Red indicated that it is mandatory. Black indicates comment and green indicates custom code.

if( typeof( SiebelAppFacade.ValidatePR ) === "undefined" ){
    SiebelJS.Namespace( "SiebelAppFacade.ValidatePR" );
   
    SiebelApp.S_App.RegisterConstructorAgainstKey( "ValidatePRenderer", "SiebelAppFacade.ValidatePR" );
   
    SiebelAppFacade.ValidatePR = ( function(){
       
                               
        function ValidatePR( pm ){
            SiebelAppFacade.ValidatePR.superclass.constructor.call( this, pm );
            this.GetPM().AttachPMBinding( "isEmailSet",  validateEmail, { scope: this });
                /* This is very important. We bing “isEmailSet” variable. So that this will track changes in this variable in physical model. and if changes happed, then validateEmail will execute. */
        }
       
        SiebelJS.Extend( ValidatePR, SiebelAppFacade.PhysicalRenderer );
       
                                 function validateEmail() {
                var controls = this.GetPM().Get( "GetControls" );
            var cntrl = controls[ "EmailAddress" ];        
/*The  controls[ "EmailAddress" ]; will return an object  that contain all information about EmailAddress*/
                                                var emailcntrl  = cntrl.GetInputName();
/*cntrl.GetInputName(); Using the above object getting input name  */
                                                var email = $('input[name="'+emailcntrl+'"]').val();
/*Here is jQuery!!... using our input name we are reading the value in it. */
                                                alert(email);
                                                var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
                                                if( !emailReg.test( email ) ) {
                                                                alert("Please enter a valid Email");
                                                                return false;
                                                } else {
                                                                alert("This is a valid Email");
                                                                return true;
                                                }
/*Using a regular expression, we are testing whether it is a valid email or not.. old browser script.. */
                                }
       
        return ValidatePR;
    }());
}

Now if you change value in email field, will trigger Physical Model.. then Physical render and email filed will get validated.  Hope you understand… :)

Coding Physical Model (Part -2 )



Now let’s take a look in to the code( that posted in lastpost) one by one.  
I have given three color for code. Red indicated that it is mandatory. Black indicates comment and green indicates custom code.


Physical Model
/*---------------------------Coding starts------------------------*/
if( typeof( SiebelAppFacade.ValidatePM ) === "undefined" ){
 /* No Need to worry about this line. This line make sure that the same definition is not yet defined. */
                SiebelJS.Namespace( "SiebelAppFacade.ValidatePM" );
/* SiebelJS.Namespace( "SiebelAppFacade.ValidatePM" ); This will create new name space called ValidatePM. */
                SiebelApp.S_App.RegisterConstructorAgainstKey("ValidatePModel","SiebelAppFacade.ValidatePM" );
/*Above code will register our constructor It s format is
RegisterConstructorAgainstKey (key, constructor)”. This is very important because we need this key to map our customized file in many places.
*/
                SiebelAppFacade.ValidatePM = ( function(){
                /*we just started to define our class. Its name is ValidatePM */
                                function ValidatePM( proxy ){
                                                SiebelAppFacade.ValidatePM.superclass.constructor.call( this, proxy);
                                }
                /*Calling super class*/
                                SiebelJS.Extend( ValidatePM, SiebelAppFacade.PresentationModel );
                /* Above line add  our class to frame work, now our class can access many prebuilt functions. */               
                                ValidatePM.prototype.Init = function(){
                                                /*Init method will initialize, we can initialize properties, methods etc.. */
                                                SiebelAppFacade.ValidatePM.superclass.Init.call( this );
                                                this.AddProperty( "isEmailSet", "" );       
                                                this.AddMethod( "FieldChange",  OnFieldChange, { sequence : false, scope: this } );
                                };
                                
                                function OnFieldChange( control, value ){
                                                if( control.GetName() === "EmailAddress" ){
                                                                this.SetProperty( "isEmailSet", ( value ? true: false ) );
                                                }
                                }
                                return ValidatePM;
                }());

}

/*-------------------------------Coding Ends--------------------------------------*/

 
Now lets take a look in to Init function.


ValidatePM.prototype.Init = function(){
                        SiebelAppFacade.ValidatePM.superclass.Init.call( this );
                         this.AddProperty( "isEmailSet", "" );                                                             this.AddMethod( "FieldChange",  OnFieldChange, { sequence : false, scope: this } );
                                };
Here  this.AddProperty( "isEmailSet", "" );       created a property called  isEmailSet” and initialized this value as null. Now I initialized a method this.AddMethod( "FieldChange",  OnFieldChange, { sequence : false, scope: this } );     read more


Now lets discuss our custom method
function OnFieldChange( control, value ){
                    if( control.GetName() === "EmailAddress" ){
                               this.SetProperty( "isEmailSet", ( value ? true: false ) );
                         }
 }

Every field change will trigger this method. And this will check for changed  control name. In our case, we are listening to changes in email field. So if email address has any  change, then we will set isEmailset to true.
This change will trigger our PhysicalRender file. Because in physical render file we will listen this property (That we will discuss later).  So any change in this property (isEmailSet) will trigger our custom methods in physical render file.


Wednesday, 16 January 2013

Introduction to Physical Model & Physical Render in Siebel Open UI



Before looking into details we can discuss a real time situation. Normally Siebel will not validate whether email is in right format or not.  So here we can implement a small validation using this Physical model and physical render. Remember one thing, I am just explain a situation for your understanding.. Actually we can do many customizations like changing color, theme, handling any events… by using this…
Our validation (Email Validation) should work whenever the user leaves his control from email field with a change in existing value. That means we need to catch an event called FieldChange .  Our Physical model will catch that change in email field. Here we can validate it(Whether email is in right format or not), but for better understanding we can validate this in our physical render file. So we need to pass this information from Physical model  to physical render file right?  To do this we need to keep a variable (property) let say “isEmailSet”, in Physical model and bind the same in physical render, so that any change in this variable will trigger physical render, and validation will proceed.
 When the email filed value changes our Physical model change isEmailSet to ture, this will invoke physical render and it will validate.
Physical Model is a JavaScript file that helps us to deal with Meta data and data in Siebel. Using physical model we can customize logic, behavior content and most importantly it help us to get events that happens in browsers such as mouse over, focus, blur(leaving focus) etc…
Physical Render is another JavaScript file that helps to build user interface. This file allows us to use third-party scripts to execute in Siebel. This binds a presentation model to physical control. 

Example of Physical Model

if( typeof( SiebelAppFacade.SummaryPM ) === "undefined" ){
               
                SiebelJS.Namespace( "SiebelAppFacade.SummaryPM" );
                SiebelApp.S_App.RegisterConstructorAgainstKey( "SummaryPModel","SiebelAppFacade.SummaryPM" );
               
                SiebelAppFacade.SummaryPM = ( function(){
                                function SummaryPM( proxy ){
                                                SiebelAppFacade.SummaryPM.superclass.constructor.call( this, proxy);
                                }
                               
                                SiebelJS.Extend( SummaryPM, SiebelAppFacade.PresentationModel );
                               
                                SummaryPM.prototype.Init = function(){
                                                SiebelAppFacade.SummaryPM.superclass.Init.call( this );
                                                this.AddProperty( "isEmailSet", "" );       
                                                this.AddMethod( "FieldChange",  OnFieldChange, { sequence : false, scope: this } );
                                };
                               
                                function OnFieldChange( control, value ){
                                                if( control.GetName() === "EmailAddress" ){
                                                                this.SetProperty( "isEmailSet", ( value ? true: false ) );
                                                }
                                }
                                return SummaryPM;
                }());
}

Example of Physical Render
if( typeof( SiebelAppFacade.ValidatePR ) === "undefined" ){
    SiebelJS.Namespace( "SiebelAppFacade.ValidatePR" );
  
    SiebelApp.S_App.RegisterConstructorAgainstKey( "ValidatePRenderer", "SiebelAppFacade.ValidatePR" );
  
    SiebelAppFacade.ValidatePR = ( function(){
      
      
        function ValidatePR( pm ){
            SiebelAppFacade.ValidatePR.superclass.constructor.call( this, pm );
            this.GetPM().AttachPMBinding( "isEmailSet",  validateEmail, { scope: this });
        }
      
        SiebelJS.Extend( ValidatePR, SiebelAppFacade.PhysicalRenderer );
      
         function validateEmail() {
            alert("going to validate");
            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( !emailReg.test( email ) ) {
                alert("Please enter a valid Email");
                return false;
            } else {
                alert("This is a valid Email");
                return true;
            }
        }
      
        return ValidatePR;
    }());
}

Let’s take a look into our code one by one…in next post :)