This chapter will guide you through the process of implementing basic functionality using the Genie JavaScript SDK. You will implement a login page, show an application menu driven by the process map in the server application, and hook up a data entry form to an activity and its associated fields and methods.
...
You can see empty “Chart of Accounts” page when you click on new menu.
...
Here we will explain all menus one by one with examples of "How data is fetched from WPF application to Web Application and saved back to WPF Application from Web application using Genie SDK?".
Vehicle Check
Vehicle Check is used as safety measure application in which driver has to enter vehicle code/ODO and also check for any issue. If driver see any issue, he must need to report that issue and replace vehicle by finding another vehicle and assigning to himself. Then. he can mark "Vehicle Check Done".
To build Vehicle Check page, we need to see traffic debug and XML request to identify activity name and style.
Image Removed
Code Block |
---|
|
<div class="row" data-ex-bind="activity" data-ex-activityname="ERP.TourRun" data-ex-activitystyle="VehicleCheck">
</div> |
We need to replicate fields in Web application as exist in WPF application after adding static header Vehicle code/rego.
To add static field Rego/License No; use data-ex-bind to "field", and data-ex-fieldid to "Vehicle.RegoLicenceNo".
Code Block |
---|
|
<div class="input-group" data-ex-bind="field" data-ex-fieldid="Vehicle.RegoLicenceNo">
<label data-ex-attribute="label" class="control-label"></label>
<span data-ex-attribute="value" class="form-control-static"></span>
</div> |
Image Removed
To add ODO input field; use data-ex-bind to "field" and data-ex-fieldid to "ODO.Start".
Code Block |
---|
|
<div class="input-group" data-ex-bind="field" data-ex-fieldid="ODO.Start">
<span data-ex-attribute="label" class="input-group-addon">ODO</span>
<input data-ex-attribute="value" type="number" class="form-control" min="0">
</div> |
Image Removed
We need to add three tabs Things to Take, Report Issue and Change Driver while making first tab Things to Take as active tab.
Code Block |
---|
|
<ul id="vehicleCheckTabs" class="nav nav-tabs" role="tablist">
<li role="presentation" class="active">
<a href="#things" id="things-tab" role="tab" data-toggle="tab">Things To Take</a>
</li>
<li role="presentation">
<a href="#report" role="tab" id="report-tab" data-toggle="tab">Report Isssue</a>
</li>
<li role="presentation">
<a href="#driverChange" role="tab" id="driverChange-tab" data-toggle="tab">Change Driver</a>
</li>
</ul> |
Image Removed
Now, we need to add contents/fields to each tab.
Code Block |
---|
|
<div id="vehicleCheckTabContent" class="tab-content">
</div> |
We need to display special instructions (if exist) in Things to Take tab. To bind with Special Instructions field; use data-ex-bind to"field" and data-ex-fieldid to "SpecialInstructions".
Code Block |
---|
|
<div id="vehicleCheckTabContent" class="tab-content">
<div role="tabpanel" class="tab-pane active in" id="things" data-ex-bind="field" data-ex-fieldid="SpecialInstructions">
<p style="padding-top: 10px; padding-bottom: 10px" class="col-xs-12" data-ex-attribute="value" data-ex-renderashtml="true"></p>
</div>
</div> |
In Report Issue tab, user can report any issue and can replace vehicle as well.
Code Block |
---|
|
<div id="vehicleCheckTabContent" class="tab-content">
<div role="tabpanel" class="tab-pane in" id="report">
</div>
</div> |
To report issue we need to create text field to enter issue and then button to report/save issue. To bind field data, use data-ex-fieldid to "Vehicle.Issues.Issue". To bind button to Save method, use type="submit", data-ex-contextobject='Vehicle.Issues', data-ex-bind="method", data-ex-method="Save".
Code Block |
---|
|
<div class="input-group" data-ex-bind="field" data-ex-fieldid="Vehicle.Issues.Issue">
<input id="issueToReport" x-webkit-speech type="text" class="form-control" placeholder="Enter Issue..." data-ex-attribute="value">
<span class="input-group-btn">
<button id="reportIssue" class="btn btn-default" type="submit" data-ex-contextobject='Vehicle.Issues' data-ex-bind="method" data-ex-method="Save">Report</button>
</span>
</div> |
Image Removed
Now, we need to list down all vehicles registration number, and show them in drop-down list once user press Get Vehicles button.
To fetch data from service, use data-ex-bind="method" data-ex-method="listReplacementVehicles".
Code Block |
---|
|
<button class="pull-right btn btn-primary btn-lg" style="margin: 0 5px;" data-ex-bind="method" data-ex-method="listReplacementVehicles">
Get Vehicles
</button>
|
...
Code Block |
---|
|
<div class="input-group">
<span class="input-group-addon">Select Replacement Vehicle</span>
<select class="form-control" data-ex-bind="datafield" data-ex-fieldid="UDefInt" data-ex-populatemethod="listReplacementVehicles" data-ex-autopopulate="0">
</select>
</div>
|
To apply vehicle change, user need to press Apply Vehicle Change. To apply this we need to bind method to "applyVehicleChange".
Code Block |
---|
|
<button class="pull-right btn btn-primary btn-lg" data-ex-bind="method" data-ex-method="applyVehicleChange">
Apply Vehicle Change
</button>
|
Now if you build and run, you can see Vehicle check page.
Image Removed
In last tab, Change Driver, user can assign vehicle using button Assign Me as Replacement with binding to method "assignMeAsReplacementDriver".
Code Block |
---|
|
<div id="vehicleCheckTabContent" class="tab-content">
<div role="tabpanel" class="tab-pane in" id="driverChange">
<button class="pull-right btn btn-primary btn-lg" data-ex-bind="method" data-ex-method="assignMeAsReplacementDriver">
Assign Me as Replacement
</button>
</div>
</div> |
Image Removed
Now, user can mark both fields Supporting Items Onboard and Vehicle Check Done.
Code Block |
---|
|
<div class="input-group" data-ex-bind="field" data-ex-fieldid="SupportingItemsOnboard">
<input id="SupportingItemsOnboard" type="checkbox" data-ex-attribute="value" />
<label for="SupportingItemsOnboard" class="form-control" data-ex-attribute="label">Supporting Items Onboard</label>
</div>
<div class="input-group" data-ex-bind="field" data-ex-fieldid="VehicleCheckDone">
<input id="vehicleCheckComplete" type="checkbox" data-ex-attribute="value" />
<label for="vehicleCheckComplete" class="form-control" data-ex-attribute="label">Vehicle Check Completed</label>
</div> |
Image Removed
Manifest
Manifest application is used to maintain passenger data in which driver on his vehicle pass on to some hotels and is supposed to pick passengers from that hotels. Passenger personal information is also maintained who take ride.
To build Manifest page, we need to see traffic debug and XML request to identify activity name and style.
Image Removed
Code Block |
---|
|
<div class="row" data-ex-bind="activity" data-ex-activityname="ERP.TourRun" data-ex-activitystyle="Manifest">
</div> |
Please note that Manifest app is still in-progress. But still we will explain the fields that are displayed in Manifest app. We will explain how these data fields are bound.
Image Removed
To add Destination field to Manifest app, use data-ex-bind="field" data-ex-fieldid="DestinationId".
Code Block |
---|
|
<div class="day-info" data-ex-bind="field" data-ex-fieldid="DestinationId">
Destination: <span data-ex-attribute="text"></span>
</div> |
To add Vehicle field to Manifest app, use data-ex-bind="field" data-ex- fieldid="Vehicle.RegoLicenceNo".
Code Block |
---|
|
<div class="day-info" data-ex-bind="field" data-ex- fieldid="Vehicle.RegoLicenceNo">
Vehicle: <span data-ex-attribute="value"></span>
</div> |
To add Total Pax field to Manifest app, use data-ex-bind="field" data-ex-fieldid="Pax".
Code Block |
---|
|
<div class="day-info" data-ex-bind="field" data-ex-fieldid="Pax">
Total Pax: <span data-ex-attribute="value"></span>
</div> |
Now we need to add checkbox input field of label Hide Pixed up Pax , and bind field id to "HideCompletedChildren".
Code Block |
---|
|
<div class="input-group" data-ex-bind="field" data-ex-fieldid="HideCompletedChildren">
<input id="vehicleCheckComplete" type="checkbox" data-ex-attribute="value" />
<label for="vehicleCheckComplete" class="form-control" data-ex-attribute="label">Hide Pixed up Pax</label>
</div> |
To get list of hotels, we need to fetch data using data-ex-bind="data" data-ex-populatemethod="listHotelPickups" data-ex-autopopulate="1", and display data in table.
Code Block |
---|
|
<div class="table-responsive">
<table class="table" id="hotelPickupList" data-ex-bind="data" data-ex-populatemethod="listHotelPickups" data-ex-autopopulate="1"></table>
</div> |
Now we driver can press Leave City button once pickup is complete.
Code Block |
---|
|
<button id="leavingCity" type="button" data-ex-bind="method" data-ex-method="pickupsComplete" class="btn btn-lg btn-primary">
Leaving City
</button> |
Then notes can be added using Notes field with binding to "DriverNotes".
Code Block |
---|
|
<div data-ex-bind="field" data-ex-fieldid="DriverNotes">
<h3>Notes</h3>
<textarea data-ex-attribute="value" style="width: 100%; height: 50px; resize: none;"></textarea>
<button class="btn btn-primary">Save</button>
</div> |
Return Manifest
Return Manifest application is opposite to Manifest application. In Manifest, passengers were picked up from hotels but in Return Manifest passengers are dropped off back to their places.
To build Return Manifest page, we need to see traffic debug and XML request to identify activity name and style.
Image Removed
Code Block |
---|
|
<div class="row" data-ex-bind="activity" data-ex-activityname="ERP.TourRun" data-ex-activitystyle="ReturnManifest">
</div> |
Please note that Return Manifest app is still in-progress. But still we will explain the fields that are displayed in Return Manifest app. We will explain how these data fields are bound.
Image Removed
To get list of drop-off locations, we need to fetch data using bindings as follows and display data in table.
Code Block |
---|
|
<div class="table-responsive">
<table class="table" id="finalDropoffList" data-ex-bind="data" data-ex-populatemethod="listFinalDropoffs"></table>
</div> |
To hide drop-off location, we can add checkbox Hide Dropped Off so user can hide or show drop-off location.
Code Block |
---|
|
<div data-ex-bind="field" data-ex-fieldid="HideCompletedChildren">
<input id="vehicleCheckComplete" type="checkbox" data-ex-attribute="value" />
<label for="vehicleCheckComplete" class="form-control" data-ex-attribute="label">Hide Dropped Off</label>
</div> |
Then driver can finish day by pressing button Finished for day and entering ODO meter reading.
Code Block |
---|
|
<div data-ex-bind="field" data-ex-fieldid="HideCompletedChildren">
<input id="vehicleCheckComplete" type="checkbox" data-ex-attribute="value" />
<label for="vehicleCheckComplete" class="form-control" data-ex-attribute="label">Hide Dropped Off</label>
</div>
<div data-ex-bind="field" data-ex-fieldid="ODO.Finish">
<span data-ex-attribute="label" class="input-group-addon"></span>
<input data-ex-attribute="value" type="number" class="form-control" min="0">
</div> |
Confirm Manifest
As Manifest application is used to maintain passenger data in which driver on his vehicle pass on to some hotels and is supposed to pick passengers from that hotels. Passenger personal information is also maintained who take ride. In Return Manifest passengers are dropped off back to their places.
Confirm Manifest is just used to confirm once correct information is made, otherwise Manifest will be rejected. All other fields are same.
Image Removed
Code Block |
---|
|
<div>
<a href="#" id="confirmManifest" data-ex-bind="method" data-ex-method="confirmManifestAndAvailability">
Confirm Manifest
</a>
<a href="#" data-ex-bind="method" data-ex-method="rejectManifestAndAvailability">
Reject Manifest
</a>
</div> |
Menu app is used for Meal selections. Who would be supplier? How many guests are there? What are the selections of menu items? What is the estimated time of arrival?
To build Menu page, we need to see traffic debug and XML request to identify activity name and style.
Image Removed
Code Block |
---|
|
<div class="row" data-ex-bind="activity" data-ex-activityname="ERP.TourRun" data-ex-activitystyle="MealMenu">
</div> |
Please note that Menu app is still in-progress. But still we will explain the fields that are displayed in Menu app. We will explain how these data fields are bound.
Image Removed
To fetch data for all menu items, we need to build request and bind fields and display data in table as follows:
Code Block |
---|
|
<div>
<table class="table" id="mealMenuSelections" data-ex-bind="data" data-ex-populatemethod="listMenuSelections"></table>
</div> |
...
Code Block |
---|
|
<div>
<table class="table mealMenuSelectionSummary" id="mealMenuSelectionSummary" data-ex-contextobject="WorkMealMenu" data-ex-bind="data" data-ex-populatemethod="publishSelectionsSummary">
</table>
</div> |
To add Notes field to Menu app, use data-ex-bind="field" data-ex-fieldid="WorkMealMenu.Notes".
Code Block |
---|
|
<di data-ex-bind="field" data-ex-fieldid="WorkMealMenu.Notes">
<h3>Notes</h3>
<textarea style="width: 100%; height: 50px;" data-ex-attribute="value"></textarea>
</di> |
To add ETA field to Menu app, use data-ex-bind="field" data-ex-fieldid="WorkMealMenu.ETA".
Code Block |
---|
|
<div data-ex-bind="field" data-ex-fieldid="WorkMealMenu.ETA">
<span>ETA</span>
<input id="mealMenuEta" tabindex="1" data-ex-attribute="value" type="number" class="form-control" />
</div> |
To add Send Email button to Menu app, specify type="button" data-ex-bind="method" data-ex-method="sendSelectionsEmail".
Code Block |
---|
|
<button id="passengerNoShowButton" type="button" data-ex-bind="method" data-ex-method="sendSelectionsEmail" class="btn btn-lg btn-primary">
Send Email
</button> |
Roster
Roster application shows a list of drivers in order they have to perform duties for specific date range.
To build Roster page, we need to see traffic debug and XML request to identify activity name and style.
Code Block |
---|
|
<ESA>
<CreateActivity name="ERP.Person" style="PortalRoster" suppressFields="1">
<Field id="CurrentBranchId" masked="0" />
<Field id="QueryDateRange.From" masked="0" />
<Field id="QueryDateRange.To" masked="0" />
<DataPublication autoPopulate="0" id="driverroster" populateMethod="listDriverRoster" />
<DataPublication autoPopulate="once" id="CurrentBranchComboBox" populateMethod="listBranches" queryMode="single" />
</CreateActivity>
</ESA> |
Code Block |
---|
|
<div class="row" data-ex-bind="activity" data-ex-activityname="ERP.TourRun" data-ex-activitystyle="PortalRoster">
</div> |
In Roster app, we simply need two fields; From Date and To Date to enter From and End date respectively. We also need to have List Roster button so when user press it, all drivers will be listed for specified date range.
Image Removed
To pass From and To date to service, we need to bind these fields.
From date is bound to field "QueryDateRange.From" while To date is bound to "QueryDateRange.To". And "datepicker" adapter is used to show calendar to select date.
Code Block |
---|
|
<div data-ex-bind="field" data-ex-fieldid="QueryDateRange.From">
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i> From</span>
<input type="text" data-ex-attribute="value" data-ex-adapter="datepicker" class="form-control">
</div>
<div data-ex-bind="field" data-ex-fieldid="QueryDateRange.To">
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i> To</span>
<input type="text" data-ex-attribute="value" data-ex-adapter="datepicker" class="form-control">
</div> |
To get data from service we added button List Roster when pressed request is made to service so we would have all drivers available.
Code Block |
---|
|
<button id="listDriverRoster" type="button" data-ex-bind="method" data-ex-method="listDriverRoster">
List Roster
</button> |
To display data returned from service, we need to display in table.
Code Block |
---|
|
<table id="portalRoster" data-ex-bind="data" data-ex-populatemethod="listDriverRoster"></table> |
Image Removed
Cash Count
Cash Count application is used to collect and count cash for Journal batches, find the discrepancy if exist, and reconcile cash based on cash collected and spent.
To build Cash Count page, we need to see traffic debug and XML request to identify activity name and style.
Code Block |
---|
|
<ESA>
<CreateActivity name="ERP.JournalBatch" style="Driver" suppressFields="1">
<Field id="CreatorId" masked="0" />
<Field id="JournalFilter" masked="0" />
<Field id="CurrentBranchId" masked="0" />
<Field id="Status" masked="0" />
</CreateActivity>
</ESA> |
Code Block |
---|
|
<div class="row" data-ex-bind="activity" data-ex-activityname="ERP.JournalBatch" data-ex-activitystyle="Driver">
</div> |
Now, we need to get list of journal batches, so user can select any batch and reconcile. We can get data using method "listMyBatchesToReconcile" using data field "PersistentId".
When list of batches are available, then user can select any batch using drop-down list that can be added as follows:
Code Block |
---|
|
<div data-ex-bind="datafield" data-ex-fieldid="PersistentId" data-ex-populatemethod="listMyBatchesToReconcile">
<label for="PersistentIdField">Run:</label>
<select id="PersistentIdField" class="form-control"></select>
</div> |
...
Once you select batch from Journal batches list then can see its status. If Journal batches have different Statuses. A cash batch may be counted for example.
We can display status fields and batch status as follows:
Code Block |
---|
|
<div id="statusField" data-ex-bind="field" data-fieldid="Status">
<label data-ex-attribute="label"></label>
<p data-ex-attribute="text"></p>
</div> |
...
We can also see cash discrepancy using data-fieldid="CashDiscrepancy".
Code Block |
---|
|
<div id="cashDiscrepancyField" data-ex-bind="field" data-fieldid="CashDiscrepancy">
<label data-ex-attribute="label"></label>
<p data-ex-attribute="value" class="form-control-static pull-right"></p>
</div> |
...
Now, we need to get count of each bill of $100, $50, $20, $10, $5, $1.
Code Block |
---|
|
<div data-ex-bind="field" data-fieldid="BillCount100.Plan">
<label for="count100Field">$100</label>
<input id="count100Field" tabindex="4" data-ex-attribute="value" type="number" class="form-control" />
</div>
<div data-ex-bind="field" data-fieldid="BillCount50.Plan">
<label for="count50Field">$50</label>
<input id="count50Field" tabindex="4" data-ex-attribute="value" type="number" class="form-control" />
</div>
<div data-ex-bind="field" data-fieldid="BillCount20.Plan">
<label for="count20Field">$20</label>
<input id="count20Field" tabindex="4" data-ex-attribute="value" type="number" class="form-control" />
</div>
<div data-ex-bind="field" data-fieldid="BillCount10.Plan">
<label for="count10Field">$10</label>
<input id="count10Field" tabindex="4" data-ex-attribute="value" type="number" class="form-control" />
</div>
<div data-ex-bind="field" data-fieldid="BillCount5.Plan">
<label for="count5Field">$5</label>
<input id="count5Field" tabindex="4" data-ex-attribute="value" type="number" class="form-control" />
</div>
<div data-ex-bind="field" data-fieldid="CoinCount200.Plan">
<label for="count2Field">$2</label>
<input id="count2Field" tabindex="4" data-ex-attribute="value" type="number" class="form-control" />
</div>
<div data-ex-bind="field" data-fieldid="CoinCount100.Plan">
<label for="count1Field">$1</label>
<input id="count1Field" tabindex="4" data-ex-attribute="value" type="number" class="form-control" />
</div> |
Image Removed
Here is the Total field which is calculated automatically based on number count of $100, $50, $20, $10, $5, $1.
Image Removed
Code Block |
---|
|
<div data-ex-bind="field" data-fieldid="TotalBillsAndCoins.Plan">
<label for="totalBillsAndCoinsField">Total:</label>
<input id="totalBillsAndCoinsField" data-ex-attribute="value" type="text"/>
</div> |
Now we need to reconcile batches based on cash collected and spent.
Image Removed
Code Block |
---|
|
<div data-ex-bind="field" data-fieldid="TotalCash">
<label for="totalCashField">Cash Collected:</label>
<input id="totalCashField" data-ex-attribute="value" type="text"/>
</div>
<div data-ex-bind="field" data-fieldid="TotalSpent">
<label for="totalSpentField">Cash Spent:</label>
<input id="totalSpentField" data-ex-attribute="value" type="text" />
</div> |
Once reconciliation is done, user can mark it by pressing Save button.
Code Block |
---|
|
<button id="saveButton" tabindex="8" data-ex-bind="method" data-ex-method="MarkCounted">
Save
</button> |
Image Removed
Chart of Accounts
When user clicks new menu “Chart of Accounts”, program must display similar structure as displayed below containing tree-view and respective fields. For this project, only “Name” field was required to be displayed. So when user double clicks any leaf-node, program must raise a request to get data of that node from service, and then name of the clicked node must be displayed in “Name” field, then user can make any change to the field, and then changes must be saved so user can view that changes in WPF application.
Image Removed
To build Chart of Accounts page, we need to see the response in traffic debug how tree-view data is returned from service. You will see tree-view data is organized as follows:
Image Removed
Code Block |
---|
|
<div class="row" data-ex-bind="activity" data-ex-activityname="ERP.GLAccount">
</div> |
You can easily see which data variable “lvChartOfAccounts” you need to bind in your html page to get this all data. So, now you need to make request as follows:
Image Removed
Image Removed
You can debug in browser to see data returned from server when you click on “Chart of Accounts” menu.
Image Removed
Now, you have to build tree-view in JS once data is returned from service. For that, I have added “TreeViewAdapter.js” and referenced in html page as follows:
Image Removed
As we requested data from service using data-ex-bind="data", with back-end view as “DataPublicationView” and model as “DataPublication”, so we have to find which event triggers when data is returned. So I have found that event triggered when data published is “onDataPublished”.
Image Removed
For that event, I have written event handler. And I also found which variable of “DataPublication” model will return all data and that is “$rawXml”.
Image Removed
As you can see from response that all data is encapsulated in Rows tag, so first we need to find “Rows” tag.
Image Removed
Image Removed
Now, we need to loop on Rows children to parse each row and differentiate parent and child items and organize in such a form that each node can have “Attributes” and “Items”. Attributes can have “id”, “value” etc. Items can have further nodes consisting of Attributes and Items. I have also included “ItemsLength” which tells items count. In case of leaf node, “itemsLength” would be zero.
Image Removed
Rows can be parsed as follows:
Image Removed
Further children rows can be parsed using following recursive function.
Image Removed
Once data is formed in tree structure, then we need to display data using html template. For that I have defined two templates: one for parent item and other for child item/leaf node consisting of “li” items with action and label.
Image Removed
To render data, “renderParentItems” function is called on data.
Image Removed
In renderParentItems function, we loop on items and see if itemsLength is greater than zero then use parent template, and also called renderChildItems; otherwise use child template to render node.
Image Removed
Now, if you build and run application, you can see treeview.
Image Removed
Now, the challenge is if you need to find selected item, and get id and type of selected item so that request can be made to genie service to get data for specific node.
For that I have written following code which unselect already selected item, and select current clicked item.
Image Removed
Then I have written click event which triggered when leaf node is selected, then you can get id and type of selected item to pass model function and get data of selected node.
Image Removed
Now, we need to add “Name” field in html page so we can see data returned from service. Also we need to add “Save” button so that changes can be saved using “Save” method.
Image Removed
Image Removed
Image Removed
You can see data changed in Name field was saved and can be viewed in WPF application.
Image Removed