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 Step-by-Step"

< Scout‎ | Tutorial‎ | 3.7
(Intro paragraph)
m (Create New Scout Project)
(44 intermediate revisions by 9 users not shown)
Line 1: Line 1:
{{ScoutPage|cat=Tutorial}}
+
{{ScoutPage|cat=Tutorial 3.7}}
 +
'''Mini CRM Tutorial'''
  
This little tutorial will show you how to create your first little application.
+
With this tutorial, you'll create a little example application with {{ScoutLink|SDK|name=Scout SDK}}, where you can enter and edit companies.
It uses a very small sample database provided for download.
+
The data is selected from the database and shown on the client, allowing users
+
to browse it, search it and edit it.
+
  
== Installation / Set Up ==
+
== Requirements ==
 +
This tutorial assumes that you have installed Scout SDK as described in {{ScoutLink|HowTo|Install Scout SDK|Download and Install Scout SDK}}. Click [[{{BASEPAGENAME}}/Project From Existing Workspace|here]] to download the workspace.
  
You need to get the '''Scout SDK''' and a '''demo database''' to work through this tutorial. {{ScoutLink|Tutorial|Installation and Setup‎|Learn more}}
+
== Create New Scout Project ==
 +
Creating new scout projects is described
 +
[[{{BASEPAGENAME}}/Minicrm/New_Eclipse_Scout_Project|here]]. That page also shows how to launch the server and the client.
  
== Setup a New Eclipse Scout Project ==
+
== Get example Database ==
 +
Follow the instructions on [[{{BASEPAGENAME}}/Minicrm/Get_example_database|this page]] to get our small Apache Derby example database.
  
Switch to the Scout Perspective and '''create a new Scout Project'''. {{ScoutLink|Tutorial|Setup a New Eclipse Scout Project|Learn More}}
+
== Set up SQL Service ==
 +
Now we need to tell the application how to contact the database. How this works is described  [[{{BASEPAGENAME}}/Minicrm/Set_up_SQL_Service|here]].
  
== Setup a SQL Service ==
+
== Write the first Page ==
 
+
A standard Eclipse Scout application consists of pages in a tree structure. A page typically shows data in some sort of table. If you write an application, you need to start with a page. [[{{BASEPAGENAME}}/Minicrm/Write_the_first_page|Learn more]]
We'll use [http://db.apache.org/derby/ Apache Derby] for this tutorial. We need to tell the framework how to contact it. {{ScoutLink|Tutorial|Setup a SQL Service|Learn More}}
+
 
+
== Write The First Page ==  
+
 
+
A standard Eclipse Scout application consists of '''pages''' in a tree structure. A page typically shows data in some sort of table. If you write an application, you need to start with a page. {{ScoutLink|Tutorial|Write The First Page|Learn more}}
+
  
 
You should have a tiny Eclipse Scout application running at the end of this step!
 
You should have a tiny Eclipse Scout application running at the end of this step!
  
== Add a search form to the table page ==
+
You will end up with the following tree structure for your application:
 
+
We created a page with a table listing all the companies in the database. Add a search form that allows users to limit the number of rows returned. {{ScoutLink|Tutorial|Add a search form|Learn more}}
+
 
+
== Edit companies: Build a form ==
+
=== 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...''<br/>[[Image:Newform.jpg|left]]<br clear="all"/><br/>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.<br/>[[Image:Newformwizard.jpg|left]]<br clear="all"/><br/>When you click next, you will see that there are also permissions and a process service for this form created, both we will discuss later.<br/><br/>[[Image:InnerFormClasses.jpg|left]]<br clear="all"><br/>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''.<br/>[[Image:Newformfield.jpg|left]]<br clear="all"/>On the New Form Field wizard you first have to choose a template for the field. First we want to add a Field for the company's name, therefor choose ''String Field''. Click next and enter the name of the field (''Name'') and then click finish.<br/>[[Image:Fieldtemplates.jpg|left]]<br clear="all"/>Now proceed in the same way and add a field for the ''Short Name'' and a ''Ok'' Button (template: '''''OK Button''''') and a ''Cancel'' Button (template: '''''Cancel Button'''''). For  the two buttons you can leave the names empty since they are already provided by their templates. Buttonnames usually have an ampersand. This is used for the keyboard shortcut.
+
 
+
=== 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 ProcessService contains four methods. If you check from where they are called, you will notice that the callers are a two ''FormHandler''s: A ''NewHandler'' and a ''ModifyHandler'', two inner classes of ''CompanyForm'' of type ''AbstractFormHandler''. You can see them as well in the Scout project explorer: If you open the node ''CompanyForm'', there is a node ''Handlers''. <br/><br/>
+
FormHandlers are used to start a form in a different 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
+
# execPostLoad: After the form was loaded, changes to fields inside this method results in marking the form as ''Save needed / Changed''
+
# execCheckFields: Executed before execValidate but after ''AbstractForm.execCheckFields()''. Returning false cancels the processing.
+
# execValidate: Executed after ''AbstractForm.execValidate()''.
+
# execStore: After this method call, the form is in the state ''Saved / Unchanged''. Executed before ''AbstractForm.execStored()''.
+
# execDiscard
+
# execFinally
+
  
Please consult the javadoc of these methods to lookup what they are used for. If you check which methods of the ''CompanyProcessService'' class are called from within the generated FormHandlers inside the ''CompanyForm'', you will see that the ''ModifyHandler'' calls the method ''load'' to load the data in the form and ''store'' when the form is closed and its (modified) data is to be stored (e.g. the ''Ok-Button'' has been pressed). While the ''NewHandler'' calls the method ''prepareCreate'' before showing the form and ''create'' when the form is stored in order to insert a new Company entry.<br/>
+
Standard Outline
Furthermore you can see here that the beforehand generated Permissions are now automatically checked here. These checks have been added in the same manner on the client side as well in order to guarantee that a form is disabled when it is opened by someone that doesn't have the permission to update a company entry.
+
  │
 +
  └─Company Table Page
  
=== Load the data for the form ===
+
Very simple indeed!
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.<br/>[[Image:Updateformdata.jpg|left]]<br clear="all"/><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 ===  
+
== Add a search 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.
+
We created a page with a table listing all the companies in the database. Add a search form that allows users to limit the number of rows returned.
<source lang="java">
+
[[{{BASEPAGENAME}}/Minicrm/Add_a_search_form|Learn more]]
    @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 ===
+
== Add a form to edit the data ==
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...''.<br/>[[Image:Newmenu.jpg|left]]<br clear="all"/>Enter a name for your form, and in the field ''Form to start'' specify your ''CompanyForm'' and click finish.<br/>[[Image:Editcompanymenu.jpg|left]]<br clear="all"/>
+
In order to edit the data in our page, we need to create a context menu to call a form, create the form and the process service it needs to actually select, insert, update (and possibly delete) the data. [[{{BASEPAGENAME}}/Minicrm/Add_a_form_to_edit_the_data|Learn more]]
  
=== Update the company with the new values ===
+
== Write the second page ==
Now we need to edit the ''store'' method in the ''CompanyProcessService'' and add the sql statement for the update.
+
  
<source lang="java">
+
We wrote the company table page, now let's write a top-level person table page. Once we have that, we want to '''reuse the table page''' by also using it as a child page for a company. [[{{BASEPAGENAME}}/Minicrm/Write_the_second_page|Learn more]]
      @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 ===
+
You will end up with the following tree structure for your application:
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()){
+
Standard Outline
          reloadPage();
+
  │
        }
+
  ├─Company Table Page
      }
+
  │  │
</source>
+
  │  └─Person Table Page
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.
+
  │
 +
  └─Person Table Page
  
<!--== Extend your form: Add support for adding new companies ==
+
== Reorganize the tree ==
=== Implement the other methods in the CompanyProcessService ===
+
=== Add a New Company Menu ===
+
=== Add a PersonTablePage with SearchForm === 
+
=== Add a PersonForm with ProcessService ===  
+
  
== Modify the Form ==
+
We want to add an additional nodes under the ''companies table page''. This will require us to add a '''page with nodes''' and [[{{BASEPAGENAME}}/Minicrm/Reorganize_the_tree|reorganize the tree a bit]].
# Validation
+
# Formatting
+
# Changing Background or Foreground
+
  
== Extend the Form ==
+
When we're done, the result should look as follows:
# Smartfield
+
# HtmlField
+
# Button
+
  
 +
Standard Outline
 +
  │
 +
  ├─Company Table Page
 +
  │  │
 +
  │  └─Company Details Node Page ← <font style="background-color: yellow">new</font>
 +
  │    │
 +
  │    └─Person Table Page
 +
  │
 +
  └─Person Table Page
  
== Expand the Tree ==
+
== Code Types ==  
# NodePage
+
Each Code Types provides a list of values in order to fill up elements like Smart Fields or List Boxes.
  
== Bing Webservice ==
+
In a next step we want to divide the companies into two groups: suppliers and customers. When the company is type of customer, a Smart Field with ratings between A and D should appear. Let's create two Code Types and add some behaviour to the CompanyForm and ProcessServices. [[{{BASEPAGENAME}}/Minicrm/Code_Types|Learn more]]
  
== Shared Context ==
+
== Lookup Calls and Lookup Services ==  
# Scope
+
# execLoad
+
# Add variables
+
  
== Deployment ==
+
In the previous chapter we have seen how to fill smartfields with an enumerated list of codes that were based on a code type. However, sometimes you need a smartfield (or listbox) with dynamically calculated entries that are based on the data in your database (e.g. a smartfield that allows selecting a person or company). This chapter shows how to accomplish this by implementing a so called Lookup Call and a corresponding Lookup Service. [[{{BASEPAGENAME}}/Minicrm/Lookup_Calls_and_Lookup_Services|Learn more]]
-->
+

Revision as of 05:31, 13 April 2012

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

With this tutorial, you'll create a little example application with The Scout documentation has been moved to https://eclipsescout.github.io/., where you can enter and edit companies.

Requirements

This tutorial assumes that you have installed Scout SDK as described in The Scout documentation has been moved to https://eclipsescout.github.io/.. Click here to download the workspace.

Create New Scout Project

Creating new scout projects is described here. That page also shows how to launch the server and the client.

Get example Database

Follow the instructions on this page to get our small Apache Derby example database.

Set up SQL Service

Now we need to tell the application how to contact the database. How this works is described here.

Write the first Page

A standard Eclipse Scout application consists of pages in a tree structure. A page typically shows data in some sort of table. If you write an application, you need to start with a page. Learn more

You should have a tiny Eclipse Scout application running at the end of this step!

You will end up with the following tree structure for your application:

Standard Outline
 │
 └─Company Table Page

Very simple indeed!

Add a search form

We created a page with a table listing all the companies in the database. Add a search form that allows users to limit the number of rows returned. Learn more

Add a form to edit the data

In order to edit the data in our page, we need to create a context menu to call a form, create the form and the process service it needs to actually select, insert, update (and possibly delete) the data. Learn more

Write the second page

We wrote the company table page, now let's write a top-level person table page. Once we have that, we want to reuse the table page by also using it as a child page for a company. Learn more

You will end up with the following tree structure for your application:

Standard Outline
 │
 ├─Company Table Page
 │  │
 │  └─Person Table Page
 │
 └─Person Table Page

Reorganize the tree

We want to add an additional nodes under the companies table page. This will require us to add a page with nodes and reorganize the tree a bit.

When we're done, the result should look as follows:

Standard Outline
 │
 ├─Company Table Page
 │  │
 │  └─Company Details Node Page ← new
 │     │
 │     └─Person Table Page
 │
 └─Person Table Page

Code Types

Each Code Types provides a list of values in order to fill up elements like Smart Fields or List Boxes.

In a next step we want to divide the companies into two groups: suppliers and customers. When the company is type of customer, a Smart Field with ratings between A and D should appear. Let's create two Code Types and add some behaviour to the CompanyForm and ProcessServices. Learn more

Lookup Calls and Lookup Services

In the previous chapter we have seen how to fill smartfields with an enumerated list of codes that were based on a code type. However, sometimes you need a smartfield (or listbox) with dynamically calculated entries that are based on the data in your database (e.g. a smartfield that allows selecting a person or company). This chapter shows how to accomplish this by implementing a so called Lookup Call and a corresponding Lookup Service. Learn more

Back to the top