Skip to content

Dynamic Assistant

As opposed to standard assistants, the dynamic nature allows for defining the steps using procedures. The steps must be defined as structures and a method can be set which will be executed when saving a given step.

assistant Survey using SurveyAnswerSet {
   label = "Sample Survey";
   savemode = OnFinish;


   init command {
      execute {
   steps {
      dynamic GenerateSurveySetUp(Param1);
      final step {
         list SurveyAnswerList using SurveyAnswerSet {
            filter = [SurveyId = Param1];
   finish command {
      execute {


  • In the projection include fragment FndDynamicAssistantSDK;
  • With the dynamic keyword, define a function that returns the set-up procedure. This should be a structure of type FndDynamicAssistantSetUp.
  • This structure has 3 attributes that you may provide procedure names as text.
  • InitMetaFunction - return the list of initialization commands
  • StepsMetaFunction - return the list of steps
  • FinishMetaFunction - return the list of finish commands
  • Steps should be returned from a procedure as a list of FndDynamicAssistantStep structures.
  • The SaveAction attribute of a step should point to a procedure that gets called when the step is completed. This procedure should return a structure of type FndDynamicNextStep which should give information about what the next step should be.
  • Commands should be returned as a list of FndDynamicCommandDef structures to be used during init/finish. Currently ‘set’, ‘alert’ and ‘action’ are supported.

Getting the Steps

Dynamic Assistant need to know its Steps. You need to implement a function which returns an Array of Structures of type “FndDynamicAssistantStep”. it’s an array because each structure instance defines a single step. So, the array contains declaration of each step.

This Structure Contains many Attributes. All you need to do in your function implementation (plsql) is query the dynamic instance you need use and loop through each item in it and fill the Structure. (for example, for survey it’s survey Questions you need to loop through and fill the structure attributes with)

The FndDynamicAssistantStep Structure attributes are as follows. Note that you don’t need to fill all attributes for all steps

Attribute Description
Label Step label
StepLabel Label shown in the Assistant Progress indicator (default label)
Entity Entity Used
Description Description of Step
Name Name used for the client group
Datatype Data Type of the entity attribute for which data is collected
ControlType Type of visual Control to be used for the entity attribute (default text control )
MultiLine Should the Control support Multiline (default false)
BindAttribute Entity attribute to which control is bound
BindAttributeLabel Label to show for the Entity Attribute (default attribute name)
SaveAction Action method used to save the data in each step
SaveActionParameters Parameters for the save action: supports interpolation. Ex. (QuestionId:${QuestionId},SurveyId:${SurveyId},Answer:${Answer})
ProjectionName Name of the Projection
DefaultValue Any default value to be used in the step (initial default values)
Required True if it’s a mandatory attribute
Enumeration Enumeration to be used in the step
Reference Lov Reference to be used in the step
Visible If a step is visible (default true)
Enabled If a step is enabled (default true)
RemarkNeeded If a remark attribute is needed for the step
RemarkAttribute Entity attribute to which remark is bound to
RemarkAttributeLabel Label of the remark (default attribute name of remark attribute)
TerminateAllowed If termination is allowed at this step (default false – survey specific)
DynamicLovOptions Options Available for check box group control (survey specific)

Init and Finish Commands

As In normal assistants init and finish commands are supported in Dynamic assistants. It supports statically defined ones as well as dynamically defined ones.

Statically defined commands can be specified in the usual way for assistants. If you define dynamic ones (supports only alert and set operations for now) then they will be executed after static ones.

Defining dynamic commands is similar to defining steps. Implement a function which return an array of “FndDynamicCommandDef” structure

FndDynamicCommandDef structure

Attribute Description
Method 'Set' / 'alert'
ArgName value/ msg
ArgValue Argument value /alert message
Result not supported in dynamic
Assign Attribute to assign value to
Next not supported in dynamic

Saving at each step

Dynamic assistant works by saving at each step. It’s so because in most cases we need collect values to same attribute at each step. And we may be working with many records. So, we should define an action to save values in our projection. And at each step’s “saveAction” attribute, specify that method. Then at the end of each step (when pressing ‘nex’t) framework calls that action along with the bind parameters. For different steps, we can use different save actions. (if different parameter types are needed etc)

Dynamic assistant allows to skip certain steps (even go back to an earlier step). For that to happen the save action should return the next step. Also if there is a default values to the next step that too needs to be sent, this is done again using a structure.“FndDynamicNextStep”

Attribute Description
NextStep Next step number
DefaultValue Default value of the next step
TerminateInfo True if the can terminate the (survey specific)


  • Same limitations for standard assistants apply.
  • The user cannot finish the dynamic assistant mid-way. A workaround is that the developers provide a terminating question.

Finish Command customization

In the finish command there are options for a customizable icon, label and finish message, and can be used as follows

finish command {  
    label = "Click to Finish";  
    icon = "calculator";  
    message = "Are you sure that this is what you want to do?";  

    execute {  

Supported Assistant Properties

  • init
  • finish command
  • cancel command
  • label
  • savemode
  • steps

Supported Steps

  • dynamic
  • final step
  • cancelled step



layer Core;
description "Put some useful description here ...";
category Users;

include fragment FndDynamicAssistantSDK;

----------------------------- MAIN ENTRY POINTS -----------------------------
entityset SurveySet for TstSurvey;
entityset SurveyAnswerSet for TstSurveyAnswer;
entityset SurveyQuestionSet for TstSurveyQuestion;

------------------------------ ENTITY DETAILS -------------------------------

virtual TstSurvey {
   attribute SurveyId Text;
   attribute SurveyName Text;
   attribute Description Text;

virtual TstSurveyQuestion {
   attribute SurveyId    Text;
   attribute QuestionId  Number;
   attribute QuestionNo  Number;
   attribute Question    Text;

virtual TstSurveyAnswer {
   attribute SurveyId Text;
   attribute QuestionId  Number;
   attribute Answer Text;

action PostAnswerWithResult Structure(FndDynamicNextStep) {
   initialcheck none;
   parameter SurveyId Text;
   parameter QuestionId Text;
   parameter Answer Text {
      required = [false];

function GenerateSurveySteps List<Structure(FndDynamicAssistStep)> {
   parameter SurveyId Text;

function GenerateSurveySetUp  Structure(FndDynamicAssistSetup) {
   parameter SurveyId Text;

function GenerateInitCommands  List<Structure(FndDynamicCommandDef)> {
   parameter SurveyId Text;

function GenerateFinishCommands  List<Structure(FndDynamicCommandDef)> {
   parameter SurveyId Text;


layer Core;

FUNCTION Generate_Survey_Steps___(
   survey_id_ IN VARCHAR2 ) RETURN Fnd_Dynamic_Assist_Step_Arr
   arr_       Fnd_Dynamic_Assist_Step_Arr := Fnd_Dynamic_Assist_Step_Arr();
   steps_     Fnd_Dynamic_Assist_Step_Rec;
   step_idx_  NUMBER;

   CURSOR questions IS         
      select * from ${PROJECTION}_TST_SURVEY_QUESTION_VRT t where t.survey_id = survey_id_ order by t.question_no;         
   step_idx_ := 1;
   FOR rec_ IN questions LOOP      
      steps_ := Generate_Step_Structure___(rec_, arr_, step_idx_);
      step_idx_ := step_idx_ + 1;

   RETURN arr_;   
END Generate_Survey_Steps___;

FUNCTION Generate_Step_Structure___(
   arr_       IN OUT Fnd_Dynamic_Assist_Step_Arr, 
   step_idx_  IN OUT NUMBER) RETURN Fnd_Dynamic_Assist_Step_Rec
   steps_ Fnd_Dynamic_Assist_Step_Rec;
   steps_.label := q_record_.question;
   steps_.step_label := 'Q-' || q_record_.question_no;
   steps_.entity := 'TstSurveyAnswer';
   steps_.description := q_record_.question; := 'Answer';
   steps_.default_value := 'QuestionId:' || q_record_.question_no || ',SurveyId:' || q_record_.survey_id;
   steps_.datatype := 'Text';
   steps_.save_action := 'PostAnswerWithResult';
   steps_.save_action_parameters := 'QuestionId:${QuestionId},SurveyId:${SurveyId},Answer:${Answer}';
   steps_.bind_attribute := 'Answer';
   steps_.bind_attribute_label := 'My Answer'; -- seriol no/ part no any label can be given

   steps_.projection_name := 'Survey';
   steps_.visible := TRUE;
   IF(q_record_.question_no = 1) THEN 
      steps_.enabled := TRUE;
      steps_.enabled := FALSE;
   END IF;
   arr_(step_idx_) := steps_;

   RETURN steps_;

END Generate_Step_Structure___;

FUNCTION Post_Answer_With_Result___ (
   survey_id_   IN VARCHAR2,
   question_id_ IN VARCHAR2,
   answer_      IN VARCHAR2 ) RETURN Fnd_Dynamic_Next_Step_Rec
   next_step_ Fnd_Dynamic_Next_Step_Rec;

      (objkey, survey_id, question_id, answer, obj_created_by)
      (sys_guid(), survey_id_, question_id_, answer_, Fnd_Session_API.Get_Fnd_User());

   next_step_.next_step := to_number(question_id_) + 1;
   RETURN next_step_;   
END Post_Answer_With_Result___;

FUNCTION Generate_Survey_Set_Up___(
   survey_id_ IN VARCHAR2 ) RETURN Fnd_Dynamic_Assist_Setup_Rec
   survey_rec_ Fnd_Dynamic_Assist_Setup_Rec;
   SELECT survey_name, description INTO survey_rec_.label, survey_rec_.description 
   WHERE survey_id = survey_id_;

   survey_rec_.entity := 'TstSurveyAnswer';
   survey_rec_.init_meta_function := 'GenerateInitCommands(SurveyId=''${Param1}'')';
   survey_rec_.steps_meta_function := 'GenerateSurveySteps(SurveyId=''${Param1}'')';
   survey_rec_.finish_Meta_function := 'GenerateFinishCommands(SurveyId=''${Param1}'')';   

   SELECT count(*) INTO survey_rec_.number_of_steps FROM ${PROJECTION}_TST_SURVEY_QUESTION_VRT WHERE survey_id = survey_id_;

   RETURN survey_rec_;
END Generate_Survey_Set_Up___;

FUNCTION Get_Question_Count(
   count_ Number;
   SELECT count(*) INTO count_ FROM ${PROJECTION}_TST_SURVEY_QUESTION_VRT WHERE survey_id = survey_id_;
   RETURN count_;

FUNCTION Generate_Init_Commands___(
   survey_id_ IN VARCHAR2 ) RETURN Fnd_Dynamic_Command_Def_Arr
   init_command_arr_ Fnd_Dynamic_Command_Def_Arr := Fnd_Dynamic_Command_Def_Arr();
   init_cmd_ Fnd_Dynamic_Command_Def_Rec;
   init_cmd2_ Fnd_Dynamic_Command_Def_Rec;
  init_cmd_.method := 'set';
  init_cmd_.assign := 'SurveyId';
  init_cmd_.arg_name := 'value';
  init_cmd_.arg_value := survey_id_;
  init_command_arr_(1) := init_cmd_; 

  init_cmd2_.method := 'alert';  
  init_cmd2_.arg_name := 'msg';
  init_cmd2_.arg_value := 'Survey starts';
  init_command_arr_(2) := init_cmd2_;
  RETURN init_command_arr_;
END Generate_Init_Commands___;

FUNCTION Generate_Finish_Commands___(
   survey_id_ IN VARCHAR2 ) RETURN Fnd_Dynamic_Command_Def_Arr
   init_command_arr_ Fnd_Dynamic_Command_Def_Arr := Fnd_Dynamic_Command_Def_Arr();
   init_cmd_ Fnd_Dynamic_Command_Def_Rec;

  init_cmd_.method := 'alert';  
  init_cmd_.arg_name := 'msg';
  init_cmd_.arg_value := 'Survey finished';
  init_command_arr_(1) := init_cmd_;
  RETURN init_command_arr_;
END Generate_Finish_Commands___;