Вы находитесь на странице: 1из 11

Ofbiz Support Usage Guide

Objective 1
Step 1 – Create the New Page Container Module 1
Step 2 – Create the New Page Components Contained Within the Page Container Module 2
Step 3 – Wire up MainFormComponent in Page Container Routing Module 2
Step 4 – Add our new page container Module and associated Routing Module to the SPA 3
Step 5 – Building MainFormComponent (Part 1) 3
Step 6 – Building MainFormComponent (Part 2) 6
Step 7 - Adding the Material Dialog 7
Step 9 - Building the Material Lookup Form 8
Step 10 - Using OfbizSupportModule feature ag-auto-grid to display the results 9
Step 11 - Passing the partyId selected in the Dialog Back to MainFormComponent 11

Objective
Create a simplified version of the 'find' form found in ofbiz '/ordermgr/control/findorders' with just 1 input field the
partyId input a Dialog popup search on it, using material components.

In fact the view found at '/ordermgr/control/findorders' is backed by the “findOrders” service which means with ofbiz-
auto-form component you could render the whole form in bootstrap or material and customize it in a single directive
element. But since adding a Dialog popup search box is a feature which is not yet implemented in the ofbiz-auto-form
component, this guide explains the manual form building process.

The search results in the Dialog uses the ag-auto-grid component directive, imported with ofbiz-support.module, to do
the lookup and display the results. We are using 2-way binding just to dynamically set the conditions on the ag-auto-
grid component directive according to inputs into the forms.

Step 1 – Create the New Page Container Module


Enter the angular-ofbiz/src/app/demo/ subdirectory in the terminal and type angular-cli command:
ng g module form-demo-page --spec false --routing
Here the name of our new page is form-demo-page, this is called kebab case and is the default expected by cli to name
directories and files, while the ts class within them are given associated names in camel case. Here we are also
suppressing spec because we don't want to create tests at this point. The --routing option creates a routing module for
this page component, which is required in order for our new to show up as a menu item in our side navigation.

The cli will create the page “feature” module with it's own routing module and then also show the line
WARNING Module is generated but not provided, it must be provided to be used
What this means is that the new modules are not yet part of the rest of the application. In order for a menu item for them
to appear they need to be imported into the application root module and of course contain components which we will
create next.
At this point however you can see that the cli has created a directory with 2 ts classes one in each file. The module and
the routing module for this new page container

Step 2 – Create the New Page Components Contained Within the Page
Container Module

Inline with our objective we need to create 2 components.


The first for the main form and the second for the contents of
the Dialog.
In the terminal cd into the page container module directory
cd form-demo-page
Now type the cli commands to create the components
ng g component main-form --spec false && ng g component
dialog-content-form --spec false
You will see angular-cli automatically create the directories,
files, classes and update the declarations property on the
NgModule decorator in page container module ie:
FormDemoPageModule class in the form-demo-
page.module.ts file.

Step 3 – Wire up MainFormComponent in Page Container Routing Module


Since the style of angular development is to build functionality while it is running so we can debug as we go. The
application if not already started in developer mode should be started now from the project root folder with the cli
command:
ng serve --open
This will start the spa in developer mode serving from angular-cli node server on localhost:4200 and with the --open
option also open the url in your default browser (chrome is highly recommended with its developer tools being superior
to all others).
The anguar-cli ng serve also watches your project source files, including typescript files which it continuously auto
compiles on the fly and on save refreshes the browser page so your changes or any new errors are reflected
immediately.

Now we want to provide routing for the MainFormComponent, so we can browse to in in our app and stay abreast of
changes we make as we build it.
So in form-demo-page-routing.module.ts file we are going to add a route to the 'const routes' that was created by the cli
Step 4 – Add our new page container Module and associated Routing Module to
the SPA
Now in order to be able to navigate to this route via our apps sidenav menu we need to add our new page container's
module and the routing module created in step 1 to the application root module.

So in src/app/app.module.ts add import statements along with the 2 new Modules to the NgModule decorators import
property.

Now we should be able to browse to out new component by selecting the 'Form Demo' menu item that has appeared in
out side navigation.

That is the default content created by the cli. In angular wiring things up always precedes template and component logic
creation, which takes place in tandem with the application running.

Step 5 – Building MainFormComponent (Part 1)


First we need to add import both the FormsModule, since we will be using angular core forms features, along with the
OfbizSupportModule since we are going to call an ofbiz service, into FormDemoPageModule

So here we create a simple bootstrap form using two-way


binding on an untyped formInput object that will hold our
values used in the service call and
a clear button to clear the form input and also set the class
property, named ordersResult that will hold the
ServiceResults back to null.

We are going to place our ag-auto-grid component


directive in an *ngIf block in our template and the
condition for that *ngIf will be checking if the ordersResult property is not null;

This is necessary because we are using the inputs from to call the 'findOrders' service and return the entity list in the
ServiceResults, we are then doing to pass the json equivalent of List<GenericValue> into ag-grid for display purposes.

This is a direct implementation of ag-grid with all the usual configuration, not using the ag-auto-grid component which
handles much automatically using entity metadata.

So to use ag-grid directly we need to import its module and associate the components which will use it within our
FormDemoPageModule

Ok so here is part one of our template


and our MainFormComponent class
and the rendered form, where we can enter some values and click find or clear to see the binding at work.

Step 6 – Building MainFormComponent (Part 2)


In this step we are going to call our service within the find method.
So in order to use OfbizHttpService which is
supplied by the OfbizSupportModule which we
have already imported into our
FormDemoPageModule, we need to import it into
the component class, then inject it into the
constructor and finally within our find method
actually call the service, by passing a ServiceCall
object, then second argument to the ServiceCall
constructor is whether authentication should be
used or not, here it is set to true, because
findOrders service defined in ofbiz
application/order/servicedef requires
authentication. OfbizHttpService uses angular
core http class which uses rxjs streams for async
processing, so calling subscribe method is what
actually triggers the http request to the ofbiz
backend.

For now we are just printing the result to the


browser console so we can see what json is in the
result and how we are going to use it to display in
the grid.

Exercise - the chance to get your feet wet and build something

service result with an orderList size of zero

At this point you can click the find button and see the OrderHeader results printed to the console, as seen above. From
this entity structure you can complete 'gridoptions' and 'columnDefs' properties in the component class using the
example found on https://www.ag-grid.com/example-angular-rich-grid/#gsc.tab=0 as a reference. Then once that is
completed add this.ordersResult = result.orderList
under console.log("result: " + JSON.stringify(result)); to display the results.

Step 7 - Adding the Material Dialog


Next we need to update the MainFormComponent template form so that we have a search button on the party id form
input

Next we import the MaterialCommonModule into our FormDemoPageModule and update


MainFormComponent just with a quick demo dialog.

Here we are also declaring


DialogOverviewExample-
Dialog component and adding
it to entryComponents, which
is required when passing a
component as an object.

Here we are importing MdDialog specifically


and passing our entryComponent in as content

Step 9 - Building the Material Lookup Form

So now in the ModalContentFormComponent we are going to create the first part of the dialog content, for the lookup
form using material form directives. I am not
going to go through that process step by step. But
basically wiring it up is the same as with
DialogOverviewExampleDialog except the
entryComponent is
ModalContentFormComponent.

Here is how it looks when completed

Step 10 - Using
OfbizSupportModule feature ag-auto-grid to display the results

Here we are are not going through the process described in the Exercise, but rather using an OfbizSupportModule
feature ag-auto-grid which makes the task of showing lookup results very quick and easy.

In ModalContentFormComponent we have a find() method which sets a boolean which is used in an *ngIf directive
where the ag-auto-grid component directive is. The conditions input on the ag-auto-grid element is constructed using
the bound properties of the form inputs.

This is the easiest way although we could also you an rxjs event channel here and a child component to hold the grid.
Since we are not going that route we also need a clear button that will clear the fields and set the boolean back to false
which will remove the grid from the template.
In yellow we
see the 2-way data binding between our dialog component template and component class.
[(ngModel)] is what is known as a “banna box” and represents a binding both from template to class and class to
template. We are using the class to setup the starting select options in the template and the class to set them back to their
starting state in the clear() method. We are also using the template to populate the formInput object in the class so that
we can use thoes values elsewhere in the template.

In purple we see a 1-way event binding on the button element (click). () indicate a binding from the template to the
class. The clear() method sets this.submitted back to false which hides the auto grid. It also sets this.formInput which as
mentioned is double bound back to it's starting state.

In blue we also have a 1-way event binding on the button element (click). All the submit() method does is set
this.submitted to true which we can see in green on the template, angular detects this change and renders the ag-auto-
grid component directive using values from the form to specify conditions.

Finally in red we see output from ag-auto-grid which is triggered within the implementation when a row is selected (it
should be noted on ag-auto-grid a row can only be selected if the [rowId] option is provided). The event is emitted from
within ag-auto-grid and it carries the data from the selected row. Here in the ModalContentFormComponent we are
catching that event and passing it into the selected() method in the component class.

Step 11 - Passing the partyId selected in the Dialog Back to


MainFormComponent

We can see in the red section of the ModalContentFormComponent class shown, how we are selecting just the partyId
out of the selected row which we received via an event and closing the dialog with this value as an argument.

Now here we can the search() method in MainFormComponent

We are setting this.formInput.partyId to the result value, since this.formInput.partyId also has a 2-way binding doing
this sets the input value.

Вам также может понравиться