Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Scout/Tutorial/3.7/Minicrm/Add a form to edit the data"

< Scout‎ | Tutorial‎ | 3.7
m (Modify the form's ProcessService)
(Replaced content with "The Scout documentation has been moved to https://eclipsescout.github.io/.")
 
(45 intermediate revisions by 7 users not shown)
Line 1: Line 1:
{{note|Scout Tutorial|This page belongs to the {{ScoutLink|Tutorial|Minicrm Step-by-Step|Minicrm Step-by-Step Tutorial}}. It explains how to add a form to a table page such that you can edit the data on the database. You need to {{ScoutLink|Tutorial|Write The First Page|have a table page in your application}} in order to continue.}}
+
The Scout documentation has been moved to https://eclipsescout.github.io/.
 
+
We need to create a '''form''' containing various '''fields''', we need to have a '''process service''' that allows us to select, insert, and update data on the database, and we need a '''context menu''' to call the form, possibly passing along an id (the ''primary key'') to the form if we want to edit a particular row.
+
 
+
== Create a form ==
+
 
+
We now build a form to add and edit companies. Expand the node client of your Scout project, scroll down to the node ''Forms'', right click on it and select '''New Form...'''
+
 
+
[[Image:Newform.jpg]]
+
 
+
As name for the form choose ''Company''. As you can see on the New Form Wizard a '''form ID''' called ''CompanyNr'' will automatically be created. This ID is later needed to pass the primary key of the company you want to display the data for in the form.
+
 
+
[[Image:Newformwizard.jpg]]
+
 
+
When you click ''Next'', you'll see permissions and a process service will also be created for this form. We'll discuss these later.
+
 
+
[[Image:InnerFormClasses.jpg]]
+
 
+
Click ''Finish'' to create the form.
+
 
+
When you now expand the tree below your ''CompanyForm'' you can see a '''MainBox'''. This is the mandatory root element for every form. Inside this ''MainBox'' you can now add fields as you wish by right clicking on it and choosing '''New Form Field'''.
+
 
+
[[Image:Newformfield.jpg]]
+
 
+
On the ''New Form Field'' wizard you need to choose a template for the field. First, we want to add a field for the company's name, therefore choose '''String Field'''. Click ''Next'' and enter the name of the field ("Name") and then click ''Finish''.
+
 
+
[[Image:Fieldtemplates.jpg]]
+
 
+
Now proceed in the same way and add a field for the ''Short Name''.
+
 
+
You should already have an '''Ok''' button ('''OK Button''' template) and a '''Cancel''' button (''Cancel Button'' template). The two buttons don't need a name since they'll get appropriate names from their template.
+
 
+
{{note|Ampersand in Field Names|Button names usually contain an ampersand. This is used for a '''keyboard shortcut'''. Thus, &Ok means that Alt-O will activate the Ok button.}}
+
 
+
== Modify the form's ProcessService ==
+
 
+
Go to the server node of your Scout project, open the node '''Process Service''' and expand it. Double click on the entry '''CompanyProcessService''' in order to open it.
+
 
+
<source lang="java">
+
public class CompanyProcessService extends AbstractService implements ICompanyProcessService{
+
 
+
  public CompanyFormData prepareCreate(CompanyFormData formData) throws ProcessingException{
+
    if(!ACCESS.check(new CreateCompanyPermission())){
+
      throw new VetoException(Texts.get("AuthorizationFailed"));
+
    }
+
    // TODO business logic here
+
    return formData;
+
  }
+
 
+
  public CompanyFormData create(CompanyFormData formData) throws ProcessingException{
+
    if(!ACCESS.check(new CreateCompanyPermission())){
+
      throw new VetoException(Texts.get("AuthorizationFailed"));
+
    }
+
    // TODO business logic here
+
    return formData;
+
  }
+
 
+
  public CompanyFormData load(CompanyFormData formData) throws ProcessingException{
+
    if(!ACCESS.check(new ReadCompanyPermission())){
+
      throw new VetoException(Texts.get("AuthorizationFailed"));
+
    }
+
    // TODO business logic here
+
    return formData;
+
  }
+
 
+
  public CompanyFormData store(CompanyFormData formData) throws ProcessingException{
+
    if(!ACCESS.check(new UpdateCompanyPermission())){
+
      throw new VetoException(Texts.get("AuthorizationFailed"));
+
    }
+
    // TODO business logic here
+
    return formData;
+
  }
+
}
+
</source>
+
 
+
As you can see, the generated ''process service'' contains ''four methods''. If you check from where they are called (Ctrl+Shift+G), you will notice that the callers are two ''form handlers'': a '''NewHandler''' and a '''ModifyHandler'''.
+
 
+
These two handlers are '''inner classes''' of the ''company form''. You can see them in the Scout SDK as well: expand the ''CompanyForm'' node and you'll find the ''Handlers'' node right there.
+
 
+
'''Form handlers''' are used to start a form in a particular ''mode''. For instance, if you want to use your form to add a new company, you want to bring it up empty. On the other hand, if you want to use it to edit an already existing company, you want to bring it up already containing the company's values.
+
 
+
A FormHandler's methods are are executed in a specified order. With that, you can control a form's processing at different moments or with the form in different state:
+
 
+
# execLoad: Loads form state before it is made visible
+
# execPostLoad: After the form is loaded, changes to fields inside this method result in marking the form as ''changed'' and thus requiring a ''save''.
+
# execCheckFields: Executed before execValidate but after ''AbstractForm.execCheckFields()''. Returning false cancels processing.
+
# execValidate: Executed after ''AbstractForm.execValidate()''.
+
# execStore: After this method call, the form is in the ''unchanged'' state with no ''save'' required. Executed before ''AbstractForm.execStored()''.
+
# execDiscard
+
# execFinally
+
 
+
Please '''consult the javadoc of these methods''' for details.
+
 
+
Here's how our ''CompanyProcessService'' methods are called:
+
 
+
{| style="margin: 1ex"
+
!Handler
+
!opening
+
!closing
+
|-
+
|ModifyHandler
+
|load
+
|store
+
|-
+
|NewHandler
+
|prepareCreate
+
|create
+
|}
+
 
+
Furthermore you can see in the source code generated that '''Permissions are checked'''. These checks exist on both the client and on the server side. On the client side, these are simple convenience checks to prevent the user from changing fields if they cannot be saved.
+
We need similar checks on the server side to handle service calls from outside the client.
+
The process service could potentially be used by an interface, for example.
+
 
+
== Load the data for the form ==
+
As a first thing you may want to enable the editing of an existing company entry. Therefore go to the ''load'' method and select the data to be displayed in the form using the SQL method ''SQL.selectInto''. In the INTO part of your SQL statement you can specify the the corresponding form data fields by typing ''''':<name of formdata field>''''' (as before when you added constraints to your SELECT statement). You'll notice that when you start typing : and then press ''CTRL-Space'', there is a Content assistance which provides for the available form data fields. If you find that there is a form data field missing, maybe your FormData is not up to date. You can update a FormData anytime by calling ''Update Form Data'' by right clicking on the corresponding Form. In the where-part of your statement you have to specify the company's primary key. This is contained in a field ''companyNr'', as this was the name of the Form ID we specified before and is now contained in the FormData object as well.
+
 
+
[[Image:Updateformdata.jpg]]
+
 
+
<source lang="java">
+
SQL.selectInto(
+
"SELECT SHORT_NAME, "+
+
"      NAME " +
+
"FROM  COMPANY " +
+
"WHERE  COMPANY_NR = :companyNr " +
+
"INTO  :shortname," +
+
"      :name"
+
,formData);</source>
+
 
+
== From Form to FormData to Form ==
+
Forms provide an import and export method, respectively. Therefore loading data into and storing them from a form into a form data is just a single method call. This has already been automatically added by Scout in the FormHandler methods.
+
<source lang="java">
+
    @Override
+
    public void execLoad() throws ProcessingException{
+
      ICompanyProcessService service = SERVICES.getService(ICompanyProcessService.class);
+
      CompanyFormData formData = new CompanyFormData();
+
      exportFormData(formData);
+
      formData = service.load(formData);
+
      importFormData(formData);
+
      setEnabledPermission(new UpdateCompanyPermission());
+
    }
+
</source>
+
 
+
== Start the Form ==
+
Now the last thing to do is to actually call the form and to open it. In order to do that we need a menu on the ''CompanyTablePage''. Go to your ''CompanyTablePage'' expand it twice, click on the node ''Menu'', right click and choose ''New Menu...''.
+
 
+
[[Image:Newmenu.jpg]]
+
 
+
Enter a name for your form, and in the field ''Form to start'' specify your ''CompanyForm'' and click finish.
+
 
+
[[Image:Editcompanymenu.jpg]]
+
 
+
 
+
 
+
== Update the company with the new values ==
+
Now we need to edit the ''store'' method in the ''CompanyProcessService'' and add the sql statement for the update.
+
 
+
<source lang="java">
+
      @Override
+
      public void store(CompanyFormData formData)  throws ProcessingException {
+
      if(!ACCESS.check(new UpdateCompanyPermission())){
+
          throw new VetoException(Texts.get("AuthorizationFailed"));
+
      }
+
   
+
      SQL.update(
+
          "UPDATE COMPANY SET" +
+
          "      SHORT_NAME = :shortname, " +
+
          "      NAME = :name " +
+
          "WHERE  COMPANY_NR = :companyNr", formData);
+
   
+
      return formData;
+
      }
+
</source>
+
 
+
== Pass the primary key and reload page ==
+
 
+
If you open the generated ''EditCompanyMenu'' you see that there has been generated code inside a method ''execAction''. This code actually opens the form. What is missing here is the forwarding of the ''companyNr''. The ''companyNr'' is inside the table in the ''CompanyNrColumn'' in the row the user currently selected. To get that value simply rewrite the code like this:
+
 
+
<source lang="java">
+
      @Override
+
      public void execAction()  throws ProcessingException {
+
        CompanyForm form = new CompanyForm();
+
        form.setCompanyNr(getCompanyNrColumn().getSelectedValue());
+
        form.startModify();
+
        form.waitFor();
+
 
+
        if (form.isFormStored()){
+
          reloadPage();
+
        }
+
      }
+
</source>
+
 
+
The method startModify starts the modify handler. The ''waitFor'' interrupts the execution at this point, until the form is closed again. With ''isFormStored'' we check wether the user has closed the form by pressing the ''OK-Button'' (form values are stored) or by pressing the ''Cancel-Button'' (form values are discarded). In the first case we reload the current table the see the changes instantly.
+

Latest revision as of 07:24, 18 March 2024

The Scout documentation has been moved to https://eclipsescout.github.io/.

Back to the top