2017 June Release

Defining a virtual applicationPermanent link for this heading

Use cases and menu use cases can be implemented as virtual applications.

If at any point your use case needs to present a user interface – such as a form or a dialog box – you are required to implement it as a virtual application. This is also the case when you invoke another use case requiring user interaction from your use case.

A virtual application is composed of expressions and dialogs. Dialogs allow you to display a form or form page, and have a set of branches.

When a use case is implemented as virtual application, the Fabasoft app.ducx compiler generates an instance of object class Application (FSCVAPP@1.1001:Application) for the virtual application, usually with the same reference as specified for the use case. Moreover, an instance of object class Application View (FSCVAPP@1.1001:ApplicationView) is generated for each dialog defined.

The application keyword denotes the definition of a virtual application. An application block can contain declarations of global variables, an expression block, multiple inline definitions of dialogs and generic assignments. Each dialog must be defined within its own dialog block embedded in the application block. In order to be displayed, a dialog must be called explicitly from within the expression block using the detachment operator ->.

Global variables must be declared before the expression block by denoting data type and the variable name followed by a semicolon. Once declared, global variables are available within the scope of the entire virtual application including all its dialogs. For example, if you need to increase a counter as your virtual application is processed you should to declare a global variable for the counter.

In addition to global variables, you can also reference global fields that are available throughout your virtual application. Global field must be declared before the expression block. The keyword field must be used for declaring a global field. It must be followed by its reference and a semicolon.

Note: You may only reference fields that have been defined in a fields block using the Fabasoft app.ducx object model language.

Syntax

usecase reference(parameter, ...) {
  variant objectclass {
    application {
      // Virtual applications can consist of global variable declarations,
      // global fields, expression blocks and dialogs that can be defined

      // inline

      datatype variable;
      field reference;
      ...
      expression {
        ...
      }
      overlaysize = overlaysizevalue;

      dialog reference dialogmodifiers {
        // Initialization expression that is executed before the dialog
        // is displayed

        expression {
          ...
        }
        form = form;
        target = target;
        value = valuetype;
        autoload = booleanvalue;
        autostore = booleanvalue;
        autolock = booleanvalue;
        catcherrors = booleanvalue;
        overlaysize = overlaysizevalue;
        branch identifier branchmodifiers {
          caption = captionstring;
          description = descriptionstring;
          symbol = symbol;
          visible = expression {
            ...
          }
          expression {
            ...
          }
          applytofield<view, identopt> = {
           { form, field }
          }
        }
        ...
        behaviors {
          behavior {
            condition = expression {
              ...
            }
            applytofield<view, identopt> = {
              { form, field },
              ...
            }
          }
          ...
        }
      }
    }
  }
}


Applications can only be called in the expressions of other applcations or branches, either directly or indirectly by using the detach operator.

Implementing a usecase with an virtual applicationPermanent link for this heading

A virtual application is implemented as a list of statements written in app.ducx expression language.

As usual, the cooobj variable holds the current object on which the use case is invoked. cootx and coort are also available for accessing the current transaction and the Fabasoft Folio Runtime.

Parameters of a virtual applicationPermanent link for this heading

The parameters expected by the virtual application can be specified in two ways:

The application uses the parameter list of the use case.

The application specifies a parameter list explicitly.

They are instantly available in the expression code like variables.

In the example, a use case for adding a new entry to the list of order positions of an order is implemented as a virtual application. The parameters product and quantity – that must be supplied when the use case is invoked – are instantly available as variables in the expression block. Moreover, the detachment operator, which will be discussed later in this chapter, is used to invoke an existing use case for editing the properties of the order.

Example

usecases APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;

  usecase AddPositionToOrder(Product product, integer quantity) {
    variant Order {
      application {
        expression {
          cooobj.ObjectLock(true, true);
          OrderPosition position = OrderPosition();
          position.product = product;
          position.quantity = quantity;
          cooobj.orderpositions += position;
          cooobj->COOATTREDIT@1.1:EditObjectAttributes();
        }
      }
    }
  }
}

Invoking use cases, virtual applications and dialogsPermanent link for this heading

Expressions that are hosted within a virtual application or within a dialog can make use of the detachment operator -> in order to invoke another use case, a virtual application, or a dialog.

Note: Instead of statically specifying the use case, virtual application or dialog, you can use square brackets for dynamic evaluation of the use case, virtual application or dialog to be invoked.

Example

// static invocation of a use case
cooobj->COODESK@1.1:OpenObject();

// dynamic invocation of a use case
UseCase uc = #COODESK@1.1:OpenObject;
cooobj->[uc]();

Invoking a dialogPermanent link for this heading

For invoking a dialog, the detachment operator -> must be followed by the reference of the dialog to be displayed. A dialog does not have any parameters. Supplying parameters when invoking a dialog leads to a runtime error.

Using the detachment operator, you can invoke any of the dialogs defined in the application block of your virtual application. You can also invoke dialogs that have been defined in other applications for reasons of reusability. However, reusing dialogs is strongly discouraged since unlike use cases and virtual applications they are not self-contained units with a defined interface.

Example

usecases APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;

  menu usecase CreateOrderWizard on selected {
    variant ContactPerson {
      application {
        integer currentstep; // Global variable for storing step index
        Order neworder;      // Global variable for storing the new order
        expression {
          currentstep = 1;
          ->WizardStep1;
        }
        dialog WizardStep1 {
          ...
        }
        dialog WizardStep2 {
          ...
        }
        dialog WizardStep3 {
          ...
        }
      }
    }
  }
}

Invoking a virtual applicationPermanent link for this heading

A virtual application can be invoked with the detachment operator -> followed by the reference of the virtual application and the list of parameters enclosed in parentheses. Parameters may not be omitted. Thus, all parameters defined in the parameter list of the virtual application to be invoked must be specified. However, you can use null if you do not want to provide a value for an optional parameter.

Note: You should favor invoking a use case instead of a virtual application, whenever possible (see chapter "Invoking another use case”).

The following example demonstrates invoking the virtual application FSCVENV@1.1001:EditObjectAttributeApp.

Example

usecases APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;

  menu usecase EditInvoice on selected {
    variant Order {
      application {
        expression {
          Invoice invoice = cooobj.orderinvoice;
          if (invoice != null) {
            ->FSCVENV@1.1001:EditObjectAttributeApp(invoice, cooobj, null,
              #orderinvoice, null, false, null, false);
          }
          else {
            throw coort.SetError(#NoInvoiceFound, null);
          }
        }
      }
    }
  }
}

Invoking another use casePermanent link for this heading

When invoking another use case from a virtual application, you have to specify an object on which the use case is to be called. The object must be followed by the detachment operator, the reference of the use case to be called, and the list of parameters enclosed in parentheses.

Example

usecases APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;

  usecase OpenInvoice() {
    variant Order {
      application {
        expression {
          Invoice invoice = cooobj.orderinvoice;
          if (invoice != null) {
            invoice->COODESK@1.1:OpenObject();
          }
          else {
            throw coort.SetError(#NoInvoiceFound, null);
          }
        }
      }
    }
  }
}

Special variables in virtual applicationsPermanent link for this heading

When a virtual application or a dialog is invoked, the Fabasoft vApp engine – depending on the context – makes available a set of special variables in the local scope this. As already stated, some of these variables will only be available in certain situations, e.g. when the user executes a branch. These special variables are described in the next table.

Variable

Description

sys_object

The variable sys_object stores the current object or the container object when a menu is invoked.

sys_action

The variable sys_action stores the use case or action that is executed.

sys_view

The variable sys_view stores the currently selected property when a menu or a branch is executed.

sys_selobjects

The variable sys_selobjects stores the list of objects selected in the list associated with the executed branch.

sys_selindices

The variable sys_selindices stores the list of indices selected in the list associated with the executed branch.

sys_branchvalue

The variable sys_branchvalue stores the current value of the data field associated with the executed branch.

sys_branchattr

The variable sys_branchattr stores the full path to the property of the data field associated with the executed branch.

Table 23: Special variables in virtual applications

Example

usecases APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;
  import FSCFOLIO@1.1001;

  menu usecase ShipSelectedOrders on selected {
    variant ContactPerson {
      application {
        expression {
          ->SelectOrder;
        }
        dialog SelectOrder {
          form = SelectOrders;
          target = cooobj;
          cancelbranch;
          nextbranch {
            expression {
              if (sys_selobjects > 0) {
                sys_selobjects-> ShipOrder();
              }
              else {
                throw coort.SetError(#NoObjectsSelected, null);
              }
            }
          }
        }
      }
    }
  }
}

Virtual application context actionsPermanent link for this heading

The action FSCVAPP@1.1001:GetVAPPInformation returns a dictionary in the first parameter, which contains the keys listed in the next table.

Note: Only for internal use.

Key

Description

application

The application key stores the virtual application that is currently running.

dispatcher

The dispatcher key stores the application dispatcher used.

op

topappview

The topappview key stores the topmost application view.

topappviewisexplore

The topappviewisexplore key stores whether the topmost application view is in explore mode.

servertype

The servertype key allows you to determine the type of web server used. For example, the value “IIS” is stored for Microsoft Internet Information Services.

serverplatform

The serverplatform key stores an identifier of the server operating system.

fxflags

replicationdir

isportlet

The isportlet key stores whether it is a portlet.

isplugininst

The isplugininst key stores whether the Fabasoft Folio Client is installed.

Table 24: Virtual application context dictionary

The action FSCVAPP@1.1001:GetContext allows you to access the virtual application context interface exposing the GetServerVariable and GetFormVariable methods.

Example

usecases APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;

  usecase GetvAppInfos() {
    variant Object {
      application {
        expression {
          vappctx = coouser.FSCVAPP@1.1001:GetContext();
          if (vappctx != null) {
            cookies = vappctx.GetServerVariable("HTTP_COOKIE");
            querystring = vappctx.GetServerVariable("QUERY_STRING");
            useragent = vappctx.GetServerVariable("HTTP_USER_AGENT");
            remoteuser = vappctx.GetServerVariable("REMOTE_USER");
            remoteaddress = vappctx.GetServerVariable("REMOTE_ADDR");
            formvar_firstname = vappctx.GetFormVariable("firstname");
            formvar_surname = vappctx.GetFormVariable("surname");
            %%TRACE("Local variables", this);
          }
        }
      }
    }
  }
}


The following example demonstrates how to post an HTML form to a virtual application (assuming a default installation of the Fabasoft Folio Web Services on a host named “folioweb”).

In the ax parameter, the address of the virtual application must be provided (for the example, assume that COO.200.200.1.1000 is the address of the GetvAppInfos virtual application from the previous example). The return URL that is invoked after submitting the HTML form must be provided in the ru parameter.

To close a window or overlay the cm parameter can be used: cm=1 (close window), cm=2 (close overlay).

Note: For the HTML field values to become available in the virtual application context, the URL parameter xhr=s must be added to the virtual application URL.

Example

<html>
  <body>
    <form action="http://folioweb/fsc/fscasp/content/bin/fscvext.dll?
      ax=COO.
200.200.1.1000&ru=http%3A%2F%2Fwww.fabasoft.com&xhr=s" method="post">
      <label for="firstname">First Name: </label>
      <input type="text" name="firstname"><br>
      <label for="surname">Surname: </label>
      <input type="text" name="surname"><br>
      <input type="submit" value="Send"> <input type="reset">
    </form>
  </body>
</html>

Direct assignments to a virtual applicationPermanent link for this heading

Defining overlay sizePermanent link for this heading

The overlay size for an application can be defined by using a generic assignment of the enumeration type FSCVAPP@1.1001:OverlaySize to the property FSCVAPP@1.1001:overlaysize. This setting is used for all dialogs in the virtual application except a dialog has an own definition.

Extending a virtual applicationPermanent link for this heading

A virtual application can be extended with dialogs in context of a use case and variant. Use the using keyword followed by the reference of a virtual application and curly braces. By default this reference is formed by concatenating the variant name and the use case name.

Syntax

using <reference of application> {
  dialog reference {
    ...
  }
}

In the following example the virtual application for the menu use case “EditInvoice” that is defined for variant “Order” gets extended by the “EditOrder” dialog.

Example

using OrderEditInvoice {
  dialog EditOrder {
    form = expression {
      if (coort.GetCurrentUserRoleGroup() == #SysAdm) {
        return #FormEditOrderAdmin;
      }
      else {
        return #FormEditOrderUser;
      }
    }
  }
}

Defining a dialogPermanent link for this heading

A dialog is defined within a dialog block nested within the application block of your use case. You can define multiple dialogs within an application block.

Note: The dialog blocks must not precede the expression block within an application block. The expression block must be the first block within an application block.

For a comprehensive example illustrating the definition of a dialog, please refer to the end of this section.

Assigning a formPermanent link for this heading

You can use the form keyword to assign a form or form page to a dialog, which is shown when the dialog is invoked.

Note: Referencing an instance of object class View (FSCVIEW@1.1001:View) or Tabbed View (FSCVIEW@1.1001:TabbedView) is not supported any more.

The form to be assigned to a dialog can also be dynamically calculated using app.ducx expression language. When an app.ducx expression is used, it must return the form, form page or view to be displayed on the dialog.

Example

usecases APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;

  menu usecase EditOrder on selected {
    variant Order {
      application {
        expression {
          ->EditOrder
        }
        dialog EditOrder {
         form = expression {
          
if (coort.GetCurrentUserRoleGroup() == #SysAdm) {
            
return #FormEditOrderAdmin;
           }
           else {
            
return #FormEditOrderUser;
           }
         }
         overlaysize = OVERLAYSIZE_LARGE;
        }
      }
    }
  }
}

Choosing the view modePermanent link for this heading

A dialog has two view modes: edit mode and read-only mode. When in edit mode, users are allowed to enter values into the fields displayed on the form. Otherwise, fields are not editable in the user interface.

By default, each dialog defined is displayed in edit mode. If you want to define a read-only dialog, the readonly dialog modifier suffix must be denoted following the dialog’s reference.

Example

usecases APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;

  menu usecase ViewInvoice on selected {
    variant Invoice {
      application {
        expression {
          ->ViewInvoice
        }
        dialog ViewInvoice readonly {
          ...
        }
      }
    }
  }
}

Enabling query modePermanent link for this heading

A dialog has two view types: value mode and query mode. Query mode is a special mode for creating query forms. To enable query mode, the value keyword must be set to VALUETYPE_QUERY.

When in query mode, a dialog must be initialized with a query following the app.ducx Query Language syntax. This query must be passed to the dialog in the sys_query system variable. The user can then use the dialog to enter additional query conditions, and the resulting query is returned in the sys_query system variable.

Assigning a target objectPermanent link for this heading

For each dialog, you can assign a target object on which it is operating. The Fabasoft Folio vApp Engine provides a mechanism for automatically loading and storing property values from and to the target object. The target keyword is used to assign a target object to a dialog. Usually, the name of a variable holding the desired target object is specified as the target. Additionally the target can be defined as app.ducx expression.

If no explicit target is defined, the target is the value of cooobj of the calling application.

The targetwindow keyword can be used to define the target window of the virtual application (TARGETWINDOW_SAME, TARGETWINDOW_NEW, TARGETWINDOW_OVERLAY). The default value is TARGETWINDOW_OVERLAY. If a virtual application calls another virtual application and so on, the value from the last called virtual application that has defined a target window is used.

The transaction keyword defines whether the virtual application is executed in a new transaction context (TRANSACTION_SAME, TRANSACTION_NEW, TRANSACTION_NEWEXPLORE). The default value is TRANSACTION_SAME (in some special cases the default value may differ).

Automatic loading and storing of field valuesPermanent link for this heading

By default, property values are read from the database and displayed in the corresponding fields on the form when a dialog is invoked.

When the user leaves the dialog by executing a branch, changes by the user are automatically saved – provided that the branch expression discussed later does not throw an exception.

This feature, however, requires that a target object is assigned to a dialog using the target keyword.

Fabasoft app.ducx allows you to suppress automatic loading of field values by setting autoload to false for a dialog. Conversely, the autostore keyword can be used to disable storing field values when leaving a dialog.

For instance, autostore should be set to false for a dialog that is set to read-only view mode as it would not make sense to write back values to the target object that cannot be changed in the user interface anyway.

Defining overlay sizePermanent link for this heading

The overlay size for a dialog can be defined by using a generic assignment of the enumeration type FSCVAPP@1.1001:OverlaySize to the property FSCVAPP@1.1001:overlaysize.

Defining a confirm dialogPermanent link for this heading

A confirm dialog is used to confirm an action executed by the user, to allow the user to choose from different options (e.g. whether he wants to delete an object or whether a version should be created) or to show error messages or warnings. These dialogs are shown in a special way (as small overlays with the branches at the bottom). The pagemode property is used to define a dialog as confirm dialog.

Example

usecases APPDUCXSAMPLE@200.200
{
  ...
  dialog ConfirmOrder {
    target = orderobj;
    pagemode = PAGEMODE_CONFIRM;
   form = FormConfirmOrder;
    ...
  }
}

Defining the title, a heading and a description of a dialogPermanent link for this heading

In general you may display a title, a heading and a short description on a dialog. The title should name the current use case so that the user is able to see the purpose of the current action. A good approach is to use the name of the menu item by which the use case was triggered. The title is also part of the HTML title tag.

In the heading you should prompt the user to execute something (e.g. “Choose the versions you want to delete”), ask a question (e.g. “Which version of “My Doc” do you want to view?”), or describe the action in more detail. If possible the heading should fit into one line but it must differ from the title. You may include the name of the object into the heading. On multi-page dialogs tabs will be displayed instead of the heading.

The description provides additional hints and instructions to the user if these are necessary for filling out the data or for finishing the use case.

On a confirm dialog you only have a title and a description. Confirm dialogs do not consist of multiple pages.

If the form of a dialog is assign by a dynamic binding the dialog title may be determined by the property formcaption of the form. Otherwise the multilingual name (mlname) of the dialog is used.

The heading of a dialog is determined by the property formpagelabel of the form page. If it is empty no heading is shown.

The description of a dialog is determined by the property formpagedescription of the form page. If formpagedescription is not set, the property description of the dialog is used.

You may use placeholder with inline expression code to generate the strings for these properties dynamically. A placeholder is delimited by “<~” and “~>”. Everything between the delimiters will be interpreted as expression. The expression must return a string.

Example

usecases APPDUCXSAMPLE@200.200
{
  ...
  dialog DialogApproveInvoice {
    target = orderobj;
    description = {}
   form = FormApproveInvoice;
    ...
  }
}

userinterface APPDUCXSAMPLE@200.200
{
  ...
  form FormApproveInvoice {
    formpage PageInvoiceData {
      ...
  }
}

// mlnames.lang file:
DialogApproveInvoice.mlname = "Approve Invoice"
PageInvoiceData.formpagelabel = "Do you want to accept the invoice
   \"<~ cooobj.objname ~>\"?"
DialogApproveInvoice.description = "Check the data below and choose button
   <~ #APPDUCXSAMPLE@200.200:StrAcceptButton.Print() ~> if everything is correct."

Defining dialog behaviorsPermanent link for this heading

Behaviors allow you to customize the look and feel of a dialog or the fields on the form page displayed by the dialog.

Behavior definitions must be contained in a behaviors block nested within a dialog block. The behaviors keyword must be followed by curly braces.

Within the behaviors block, the keyword representing the corresponding behavior must be denoted, followed by curly braces. The same definition block can be used for multiple behaviors. In this case, the behavior keywords must be separated by commas. The next table shows a list of supported behaviors along with the respective keywords that must be used.

Additionally to the listed keywords all behaviors defined in the enumeration type Hint (FSCVAPP@1.1001:HintType) can be used. Instead of the keyword the Reference Name (e.g. VIEWHINT_FLAT) denotes the behavior.

Behavior

Description

genericform

The genericform behavior is used to specify a pattern to match an action that selects a form; the pattern may start with "explore:" to match an explore form. When applied to a field, genericform determines whether the generic built-in functionality for displaying the field – such as tooltips and context menus – should be enabled.

symbol

The symbol behavior is used to specify whether a row symbol should be displayed for the entries of lists.

selection

The selection behavior is used to specify whether the selection of one or more rows should be enabled for lists.

required

The required behavior is used to specify whether a field requires the user to enter a value.

editcondition

The editcondition behavior is used to specify a condition that must evaluate to true in order to make a field editable. If the condition returns false, the selected field is displayed in read-only mode.

viewcondition

The viewcondition behavior is used to specify a condition that must evaluate to true in order to make a field visible. If the condition returns false, the selected field is not displayed on the user interface.

reference

The reference behavior is used to specify that component object references should be displayed instead of the object names in the object name column of object lists.

exploremode

The exploremode behavior is used to specify that object lists should be displayed on separate pages on the user interface.

simple

The simple behavior is used to enable the simple view.

showmultifunctionbar

The showmultifunctionbar behavior is used to enable or disable the multifunctional bar. By default, the multifunctional bar is enabled.

menus

The menus behavior is used to enable or disable menu bars for a dialog. By default, menus are enabled.

contextmenus

The contextmenus behavior is used to enable or disable context menus for a dialog. By default, context menus are enabled.

sort

The sort behavior is used to enable or disable sorting for object lists and compound lists. By default, sorting is enabled.

create

The create behavior is used to enable or disable creating new instances for object pointer properties and object lists.

search

The search behavior is used to enable or disable search functionality for object pointer properties and object lists.

Table 25: Behaviors

Each behavior can be applied to one or more fields of a form page or the dialog itself. An applytofield initialization block must be used to apply a behavior block to a specific field or to a list of fields. applytofield is a compound property, but in many cases only the identopt property of the compound property is used. Therefore the value for identopt can be assigned directly to applytofield (e.g. applytofield = "objname";). Please be aware that identopt is the short reference of the field.

Furthermore, the condition keyword can be used to define a condition in app.ducx expression language. When a condition block is defined within a behavior block, the behavior is only applied if the expression returns true.

Defining branchesPermanent link for this heading

When described in an oversimplified manner, a branch just defines a button and a handler that is invoked when the button is clicked. In Fabasoft terminology, “clicking the button” is referred to as “executing the branch”.

The branch keyword must be used for defining a branch, followed by a unique branch identifier (which is also referred to as the programming name) and curly braces. Multiple branch blocks can be nested within a dialog.

Assigning branch modifiersPermanent link for this heading

The branch identifier can be followed by optional branch modifiers. The next table shows a list of supported branch modifiers. If multiple branch modifiers are assigned to a branch, they must be separated by whitespaces.

Modifier

Description

leave

If the leave branch modifier is provided, the Fabasoft Folio vApp Engine continues processing the virtual application with the statement following the statement invoking the current dialog. If the leave branch modifier is omitted, the user is taken back to the current dialog after the branch has been executed successfully.

default

The default branch modifier should be applied to the default branch. There can only be one default branch for each dialog.

hyperlink

The hyperlink branch modifier allows you to attach a branch to a value displayed by a field on the form. The field’s value will then behave like a hyperlink, so a user can click on the value to activate the branch. A hyperlink branch does not have a caption.

skipnull

The skipnull branch modifier allows a user to invoke a branch even though no value was provided for one or more required fields on the form. When the skipnull branch modifier is omitted, a user is not able to invoke a branch before values are provided for all required fields.

Table 26: Branch modifiers

Assigning symbol, caption and description textPermanent link for this heading

A symbol can be assigned to a branch using the symbol keyword. Please refer to chapter “Defining symbols” for detailed information on how to define a new symbol.

The caption text displayed on a branch is usually loaded from a String (COOSYSTEM@1.1:String) object, which can be assigned to a branch using the caption keyword. Likewise, the description keyword is used to assign a description string to a branch, which is displayed when the user hovers the mouse over the branch. Please consult chapter “Defining strings” for information on how to define new strings.

Ignoring field valuesPermanent link for this heading

By default, the Fabasoft Folio vApp Engine does not execute a branch handler expression if not all required fields on the current form actually contain a value. Instead, an error message is displayed requesting the user to supply values for all required fields.

In order to force the Fabasoft Folio vApp Engine not to check whether required fields contain a value, you can use the skipnull branch modifier.

You will typically use skipnull in Cancel branches for aborting the execution of a virtual application.

Dynamically hiding a branchPermanent link for this heading

The visible keyword allows you to define an app.ducx expression for evaluating whether a branch should be displayed. If the expression returns true, the branch is displayed, otherwise it is hidden.

Attaching a branch to a fieldPermanent link for this heading

A branch can be attached to a field displayed on the form. An applytofield block must be used for attaching a branch to a field. applytofield is a compound property, but in many cases only the identopt property of the compound property is used. Therefore the value for identopt can be assigned directly to applytofield (e.g. applytofield = "objname";).

If a branch is attached to an object list or a compound list, it is displayed above the field. If it is attached to property containing a scalar value, it is displayed on the left-hand side next to the field.

Branches can also be attached to properties that are part of a compound property displayed on the form.

The hyperlink branch modifier allows you to attach the branch to the value displayed by a field. If it is omitted, the branch will be displayed next to the field value.

Defining the branch handler expressionPermanent link for this heading

You can use app.ducx expression language to implement a branch handler. The branch handler expression is defined in an expression block nested within the branch block.

You can use the detachment operator for invoking another dialog, or for executing another virtual application or a use case. For further information on how to use the detachment operator, please refer to chapter “Invoking use cases, virtual applications and dialogs”.

Predefined branchesPermanent link for this heading

The majority of all dialogs contain two common branches: a “Next” branch for proceeding to the next page, and a “Cancel” branch for aborting the execution of the current virtual application. Therefore, Fabasoft app.ducx provides special keywords for these two common cases in form of predefined branches:

  • The keyword nextbranch allows you define a “Next” branch for proceeding to the next dialog and continuing the execution of a virtual application. A nextbranch is implicitly assigned caption FSCVENV@1.1001:StrNext and symbol COODESK@1.1:SymbolNext. Moreover, the leave and the default branch modifier are also automatically assigned to a nextbranch.
  • The keyword cancelbranch allows you define a “Cancel” branch for aborting the execution of a virtual application. A cancelbranch is set to ignore any user input and is implicitly assigned caption FSCVENV@1.1001:StrCancel and symbol COODESK@1.1:SymbolCancel. Moreover, the default branch expression coouser.Cancel() is implicitly assigned to a cancelbranch.

The default branch handler expression, caption, and symbol of both nextbranch and cancelbranch can be overridden using the expression, caption, and symbol keywords.

Example

usecases APPDUCXSAMPLE@200.200
{
  import COOSYSTEM@1.1;
  import FSCVAPP@1.1001;
  import FSCVENV@1.1001;

  menu usecase EditInvoice on selected {
    variant Order {
      application {
        boolean invoiceprinted;
        Invoice invoice;
        expression {
          invoice = cooobj.orderinvoice;
          if (invoice != null) {
            invoiceprinted = false;
            invoice.ObjectLock(true, true);
            ->EditInvoiceDialog;
            if (invoiceprinted) {
              invoice->MailInvoice();
            }
          }
          else {
            throw coort.SetError(#NoInvoiceFound, null);
          }
        }
        dialog EditInvoiceDialog {
          form = PageInvoice;
          target = invoice;
          branch printinvoice {
            symbol = SymbolPrinter;
            caption = StrPrintInvoice;
            visible = expression {
              invoice.CheckGetAccess(cootx, #content)
            }
            expression {
              try {
                invoice->PrintInvoice();
                invoiceprinted = true;
              }
              catch (@error) {
                if (coort.GetErrorMessage(@error) != #COOSTERR_CANCEL) {
                  throw @error;
                }
              }
            }
          }
          nextbranch;
          behaviors {
            required {
              applytofield = "objname";
            }
            
editcondition {
              
condition = expression {
                Invoice invoice;
                
invoice.invoicepaymentdate == null
              }
              applytofield = "invoicestate";
            }
            required, editcondition, create {
              
condition = expression{
                
coort.GetCurrentUserRolePosition() == #SysAdm
              }
              applytofield = "invoiceorder";
            }
          }
        }
      }
    }
  }
}

Extending a dialogPermanent link for this heading

Use the using keyword followed by the reference of the generated virtual application (for the combination of variant and use case) and curly braces. The reference is formed by concatenating the variant name and the use case name. The virtual application contains the dialog that should be extended. To extend a dialog with a branch, use the extend dialog keywords followed by the dialog reference and curly braces.

Syntax

using <reference of variant><reference of use case> {
  extend dialog reference {
    ...
  }
}


Cloud profile note: The extension of dialogs that belong to another non-friend software component is not allowed.

In the following example the “EditInvoiceDialog” of the menu use case “EditInvoice” that is defined for variant “Order” gets extended by a cancel branch.

Example

using OrderEditInvoice {
  extend dialog EditInvoiceDialog {
    cancelbranch;
  }
}

Implementing a stand alone virtual applicationPermanent link for this heading

By using the keyword application it is possible to create a cirtual application without use case. All features described for applications used as implementations for use cases are available. This is implemented for backward compatibility and generally should not be used.

Example

application ShowUserSettings () {
  epression {

    UserEnvironment ue = cooenv;

    EditObjectAttributesApp(ue);

  }
}