All functions will be under "Patterns.Web".
This pattern is a simple UIBasicShell. It displays a single field: GoogleMap for GoogleMap. This field has a Control Name of "gmap:MainArea:template=WebGoogleMaps:default". This template will center on whatever positioning string is input into it. Please note that the size/positioning of the field in the panel is how it will display on your WebClient panel.
This is a simple page template with an IMPL name of "IncidentWebPage". All WebClient functions will inherit from this. This adds references the CSS file and Google Map API.
This is a custom template that allows functions that use the ~DetailPopup to display Plex messages. This template also works on non ~DetailPopup functions.
This is the pattern function that all of our WebClient panels will use. It inherits from ~WebShell, WebAlert, and IncidentWebPage.
This is a custom page template that we will use for our "My Reports" page. It contains some custom attach points and html.
This is a custom page template that we will use for our "Login" page. It contains some custom attach points and html.
This function in inherits from a custom page template, "Patterns.Web.WebHeaderPage". This gives us a different html layout and a few extra attach points that we use.
Panel Setup
In this panel, we are displaying the following fields:
LoginEmail | for | DetailP |
Control Name: UsrDta:LoginArea:seq=1 Label Control Name: UsrLbl:UsrDta.Label | ||
Password | for | DetailP |
Control Name: PWDta:LoginArea:seq=2 Label Control Name: PWLbl:PWDta.Label | ||
LoginEmail | for | CookieP |
Control Name: EmailCookie:MainArea:template=WebDojoCookie Label is Hidden. | ||
Password | for | CookieP |
Control Name: PasswordCookie:MainArea:template=WebDojoCookie Label is Hidden. | ||
YesNo | for | CookieP |
Control Name: SaveUser:LoginArea:seq=3 Event: Modified = SaveOptionChanged | ||
Login Button | ||
Event: Pressed = Login Control Name: LoginBtn:MainArea:seq=4 | ||
Register Button | ||
Event: Pressed = Register Control Name: RegisterBtn MainArea:seq=5 |
Notes: Both the CookieP and CookieP fields have event mapped to Modified and Updated. These fields do not actually show up on the panel. The events are triggered from the WebDojoCookie template. This will be explained further later on.
Action Diagram
Initialize
We initialize all of DetailP to Blank. We also are setting the "Login Valid?" and "Cookie Modified?" flags to No. These will be used later.
Subroutines
Sub Call Main Menu: | This is where we call the initial function after the user logs in. We are currently calling the "MyReports" panel. |
Sub Validate Password: | This is where validate the entered password compared to the one saved to the database. |
Sub Login: | We start by validating the Login information. If the Login is valid, then we check to see if the user wants to save the login information to local storage, but it has not been saved yet. If this is the case, we set the CookieP fields and set the "CookieModified?" flag to Yes. This flag will prevent us from calling the next function until after the Cookie has been saved to local storage. This will be explained more later. The LoginEmail is also saved to the ObClient file. So, if we want to reference it later, we can. Finally, we call the "Main Menu" function if we are not currently saving the Cookie to local storage. |
Events
Login: | This just calls our Login Subroutine |
Register: | This calls our Register panel, which we will mention later in the document. If the user Registers correctly, we will also automatically log them in using their created information. |
SaveOptionChanged: | If the checkbox value is Yes, then we are setting the CookieP fields. If it is set to No, then we will clear the CookieP fields. Our templates with handle the adding/removing of the cookie from local storage. This will be explained further later. |
CookieLoaded: | This event is triggered when the Cookie template loads a Cookie from local storage. It will take the information from the cookie and set it to the DetailP. |
CookieSaved: | This event is triggered when the Cookie template saves the cookie to local storage. In our code, if the login information has already been validated, then we want to call the "Main Menu" function. |
Custom Templates
This function makes use of the WebDojoCookie template in CustomTemplate. This causes the field to be a non-visible element in the dom. Any time a "Put" is done on a field using this template, the field information will be saved to the Local Storage and will trigger the Updated event for the field. Also, when the page is loaded, if the local storage element is found, then it will set the field value and trigger the Modified event for the field. The actual javascript code to do all of this is in the "assigncookie.js" file, which needs to be in the "js" folder of WebContent.
This function uses the ~DetailPopup template.
Panel
In this panel, we are displaying the User.Fetch view for DetailP. It also displays a Register button, which has its Pressed event mapped to "Register".
Action Diagram
This field outputs the registered LoginEmail and Password, as well as a flag showing the user registered.
We initialize all of the Output to Blank and the Registered flag to No.
Subroutines
Sub Validate DetailP: | This is where validate that all of the DetailP has been entered. |
Sub Create Record: | This is where we create the User record, set the Output, and exit the function. |
Events
Register: | We call the Validate subroutine and, if valid, call the create record subroutine. |
This function in inherits from a custom page template, "Patterns.Web.WebTitleArea". This gives us a different html layout and a few extra attach points that we use.
Panel Setup
In this panel, we are displaying the following fields, which are being populated in the BlockFetchSet:
ThumbnailURL | for | GridP |
IncidentStatusDescription | for | GridP |
DateString | for | GridP |
GridP has a the following Control Name: "Grid1P:MainArea:template=WebCustomGrid:tplGenerator=myReportsMenu:class=myReportsGrid:default ". This uses a custom template and TplGenerator to make the Plex grid look very different from a normal Plex grid. We will explain this a little later in the document.
The panel also contains the following buttons:
Report Button |
Event: Pressed = Report Control Name: ReportBtn:ToolBarAreaLeft |
View Details Button |
Event: Pressed = View Details Control Name: ViewDetBtn:ToolBarAreaLeft |
Logout Button |
Event: Pressed = Logout Control Name: LogoutBtn:ToolBarAreaRight |
Action Diagram
We have code for the following events:
Logout: | This calls the Login function of the application. |
Report: | This calls the "Report" function (mentioned later), then reloads the grid. |
View Details: | This calls the "IncidentDetails" (mentioned later) for the currently selected grid row. |
Custom Templates
We are using the "WebCustomGrid" control template for this function. This will take the Tpl that you specify in the control name, and use it to create our grid object. The Tpl that we are using, "myReportsMenu", is setup in the "IncidentWeb/WebContent/js/custom.js" file. You can customize this however you would like, but there are a few requirement and rules.
These functions are used to create Incident records. An image can be attached and uploaded to server. This uses the Upload Servlet in the workspace to accomplish this. For more information in setting this up, please refer to our documentation on the File Upload Servlet.
Referencing an External Server
When the files are uploaded with the Upload Servlet, they are stored in a location relative to the Web Server. The problem with this is that if you deploy a new WAR file, all uploaded files stored here would be lost. To solve this, we will copy the files from this location to one outside of the workspace. In our case, we are using "C:\Uploads". For the WebServer to be able to access these files, we need to add a reference to this folder in the "server.xml" file. Please refer to this file and you will see the following line:
"C:/Uploads" path="incidentmobile/photos"/>"C:/Uploads" path="IncidentWeb/photos"/>
This will allow you to access the files in this folder using the "incidentmobile/photos
" and "IncidentWeb/photos
" paths. You can see evidence of this in the code setting the ThumbnailURL in the BlockFetchSet being used by the My Reports functions.
This function uses the ~DetailPopup template.
Panel
This panel displays the following fields:
IncidentType | for | DetailP |
Control Type: Combobox | ||
IncidentDescription | for | DetailP |
Multiline: Yes Scrolling: Vertical | ||
ImageLocation | for | DetailP |
Control Name: UploadFile:OtherFormsArea:template=UploadFileEdit:default | ||
Select Location Button | ||
Event: Pressed = Select Location |
Note: ImageLocation uses the UploadFileEdit template. This will turn the field into a file selector. It will store the File Name selected in the field. The location of the object in the panel is based on the top of the panel, so you will have do some trial and error to get the field positioned right on the screen.
Action Diagram
Initialize
We initialize the DetailP and "Image Selected?" flag. We call the subroutine to load the Incident Type Combobox. We also fetch the User record for later reference.
Subroutines
Sub Validate Submit: | This is subroutine validates that all the information has been entered. It also checks if a location has been selected by the "SelectLocation" function. If no image was selected, the user is warned, but allowed to continue without one. |
Sub Save Report: | This is where we create the Incident record. If an image was selected, we will copy the file to the permanent folder, create a thumbnail version of the image, and create the Incident Image record. The function is then closed. |
Sub Load IncidentType Combobox: | This is subroutine that populates the Incident Type Combobox based on the records in the Incident Type table. |
Sub UploadComplete: | This subroutine validates the file type selected. Valid types are image files (jpg, gif, png, and bmp). If valid, the "Image Selected?" flag is set to Yes. |
Sub Select Location: | This subroutine calls the "Select Location" function. It will warn the user if a GeoLocation has already been selected. |
Events
Submit: | This subroutine validates the details. If it passes validation, then it calls the Save Report subroutine. |
Upload Complete: | This event is triggered after the file is selected and uploaded to the server. It then calls the Upload Complete subroutine. |
SelectLocation: | This subroutine just calls the Select Location subroutine. |
This function uses the ~DetailPopup and "Patterns.Web.GoogleMap" templates.
Panel
In this panel, we are displaying the User.Fetch view for DetailP. It also displays the following field:
ImageName | for | DetailP |
Control Name: IncidentImg:MainArea:template=WebImage:default |
Please note that ImageName and GoogleMap (a field that comes from the " Patterns.Web.GoogleMap" template) both use the literal size and positioning on the WebClient panel. So, make sure their field is a large as you need to display in the panel.
Action Diagram
This field outputs the registered LoginEmail and Password, as well as a flag showing the user registered.
Initialize
We fetch all the Incident record information to display. We also fetch the User record, since we need the Cell Number to locate the attached Incident Image. We then attempt to fetch the Incident Image. If none exists, then we set it to the default value. Next, we hide the CloseDate field is it does not contain a valid value. And finally, we set the GeoLocation to the GoogleMap field.
These functions both use the Google Map API to convert a search string into a GeoLocation. For example, if you enter " 7000 North Mopac Expressway Austin, TX". The function will use the custom templates to give the Latitude and Longitude of that location. These functions both have the Latitude and Longitude as Input and Output.
This function uses the ~DetailPopup template.
Panel
In this panel, we are displaying the following fields:
LocationString | for | DetailP |
Full Address | for | DetailP |
Control Name: FullAddress:MainArea:template=WebAddressLocator Events: Updated = AddressConverted Label is hidden. | ||
OK Button | ||
Events: Pressed = ConvertAddress |
Action Diagram
Initialize
We initialize the Output to what was Input. So, if the user cancels their change, then the values will not be overwritten.
Events
ConvertAddress: | We get the LocationString entered by the user and Set/Put the Full Address. Putting the Full Address will cause the template to calculate the Latitude/Longitude. We do not want to exit the function until the calculation has finished. |
AddressConverted: | This event is triggered once the Full Address has been calculated. So we break up the Latitude/Longitude string, set the output, then terminate. |