Detail.controller.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. sap.ui.define([
  2. "./BaseController",
  3. "sap/ui/model/json/JSONModel",
  4. "../model/formatter",
  5. "sap/m/library"
  6. ], function(BaseController, JSONModel, formatter, mobileLibrary) {
  7. "use strict";
  8. // shortcut for sap.m.URLHelper
  9. var URLHelper = mobileLibrary.URLHelper;
  10. function _calculateOrderTotal (fPreviousTotal, oCurrentContext) {
  11. var fItemTotal = oCurrentContext.getObject().Quantity * oCurrentContext.getObject().UnitPrice;
  12. return fPreviousTotal + fItemTotal;
  13. }
  14. return BaseController.extend("sap.ui.demo.orderbrowser.controller.Detail", {
  15. formatter: formatter,
  16. /* =========================================================== */
  17. /* lifecycle methods */
  18. /* =========================================================== */
  19. onInit : function () {
  20. // Model used to manipulate control states. The chosen values make sure,
  21. // detail page is busy indication immediately so there is no break in
  22. // between the busy indication for loading the view's meta data
  23. this._aValidKeys = ["shipping", "processor"];
  24. var oViewModel = new JSONModel({
  25. busy : false,
  26. delay : 0,
  27. lineItemListTitle : this.getResourceBundle().getText("detailLineItemTableHeading"),
  28. // Set fixed currency on view model (as the OData service does not provide a currency).
  29. currency : "EUR",
  30. // the sum of all items of this order
  31. totalOrderAmount: 0,
  32. selectedTab: ""
  33. });
  34. this.getRouter().getRoute("object").attachPatternMatched(this._onObjectMatched, this);
  35. this.setModel(oViewModel, "detailView");
  36. this.getOwnerComponent().getModel().metadataLoaded().then(this._onMetadataLoaded.bind(this));
  37. },
  38. /* =========================================================== */
  39. /* event handlers */
  40. /* =========================================================== */
  41. /**
  42. * Event handler when the share by E-Mail button has been clicked
  43. * @public
  44. */
  45. onSendEmailPress : function () {
  46. var oViewModel = this.getModel("detailView");
  47. URLHelper.triggerEmail(
  48. null,
  49. oViewModel.getProperty("/shareSendEmailSubject"),
  50. oViewModel.getProperty("/shareSendEmailMessage")
  51. );
  52. },
  53. /**
  54. * Updates the item count within the line item table's header
  55. * @param {object} oEvent an event containing the total number of items in the list
  56. * @private
  57. */
  58. onListUpdateFinished : function (oEvent) {
  59. var sTitle,
  60. fOrderTotal = 0,
  61. iTotalItems = oEvent.getParameter("total"),
  62. oViewModel = this.getModel("detailView"),
  63. oItemsBinding = oEvent.getSource().getBinding("items"),
  64. aItemsContext;
  65. // only update the counter if the length is final
  66. if (oItemsBinding.isLengthFinal()) {
  67. if (iTotalItems) {
  68. sTitle = this.getResourceBundle().getText("detailLineItemTableHeadingCount", [iTotalItems]);
  69. } else {
  70. //Display 'Line Items' instead of 'Line items (0)'
  71. sTitle = this.getResourceBundle().getText("detailLineItemTableHeading");
  72. }
  73. oViewModel.setProperty("/lineItemListTitle", sTitle);
  74. aItemsContext = oItemsBinding.getContexts();
  75. fOrderTotal = aItemsContext.reduce(_calculateOrderTotal, 0);
  76. oViewModel.setProperty("/totalOrderAmount", fOrderTotal);
  77. }
  78. },
  79. /* =========================================================== */
  80. /* begin: internal methods */
  81. /* =========================================================== */
  82. /**
  83. * Binds the view to the object path and expands the aggregated line items.
  84. * @function
  85. * @param {sap.ui.base.Event} oEvent pattern match event in route 'object'
  86. * @private
  87. */
  88. _onObjectMatched : function (oEvent) {
  89. var oArguments = oEvent.getParameter("arguments");
  90. this._sObjectId = oArguments.objectId;
  91. // Don't show two columns when in full screen mode
  92. if (this.getModel("appView").getProperty("/layout") !== "MidColumnFullScreen") {
  93. this.getModel("appView").setProperty("/layout", "TwoColumnsMidExpanded");
  94. }
  95. this.getModel().metadataLoaded().then( function() {
  96. var sObjectPath = this.getModel().createKey("Orders", {
  97. OrderID : this._sObjectId
  98. });
  99. this._bindView("/" + sObjectPath);
  100. }.bind(this));
  101. var oQuery = oArguments["?query"];
  102. if (oQuery && this._aValidKeys.indexOf(oQuery.tab) >= 0){
  103. this.getView().getModel("detailView").setProperty("/selectedTab", oQuery.tab);
  104. this.getRouter().getTargets().display(oQuery.tab);
  105. } else {
  106. this.getRouter().navTo("object", {
  107. objectId: this._sObjectId,
  108. query: {
  109. tab: "shipping"
  110. }
  111. }, true);
  112. }
  113. },
  114. /**
  115. * Binds the view to the object path. Makes sure that detail view displays
  116. * a busy indicator while data for the corresponding element binding is loaded.
  117. * @function
  118. * @param {string} sObjectPath path to the object to be bound to the view.
  119. * @private
  120. */
  121. _bindView : function (sObjectPath) {
  122. // Set busy indicator during view binding
  123. var oViewModel = this.getModel("detailView");
  124. // If the view was not bound yet its not busy, only if the binding requests data it is set to busy again
  125. oViewModel.setProperty("/busy", false);
  126. this.getView().bindElement({
  127. path : sObjectPath,
  128. parameters: {
  129. expand: "Customer,Order_Details/Product,Employee"
  130. },
  131. events: {
  132. change : this._onBindingChange.bind(this),
  133. dataRequested : function () {
  134. oViewModel.setProperty("/busy", true);
  135. },
  136. dataReceived: function () {
  137. oViewModel.setProperty("/busy", false);
  138. }
  139. }
  140. });
  141. },
  142. _onBindingChange : function () {
  143. var oView = this.getView(),
  144. oElementBinding = oView.getElementBinding();
  145. // No data for the binding
  146. if (!oElementBinding.getBoundContext()) {
  147. this.getRouter().getTargets().display("detailObjectNotFound");
  148. // if object could not be found, the selection in the master list
  149. // does not make sense anymore.
  150. this.getOwnerComponent().oListSelector.clearMasterListSelection();
  151. return;
  152. }
  153. var sPath = oElementBinding.getPath(),
  154. oResourceBundle = this.getResourceBundle(),
  155. oObject = oView.getModel().getObject(sPath),
  156. sObjectId = oObject.OrderID,
  157. sObjectName = oObject.OrderID,
  158. oViewModel = this.getModel("detailView");
  159. this.getOwnerComponent().oListSelector.selectAListItem(sPath);
  160. oViewModel.setProperty("/shareSendEmailSubject",
  161. oResourceBundle.getText("shareSendEmailObjectSubject", [sObjectId]));
  162. oViewModel.setProperty("/shareSendEmailMessage",
  163. oResourceBundle.getText("shareSendEmailObjectMessage", [sObjectName, sObjectId, location.href, oObject.ShipName, oObject.EmployeeID, oObject.CustomerID]));
  164. },
  165. _onMetadataLoaded : function () {
  166. // Store original busy indicator delay for the detail view
  167. var iOriginalViewBusyDelay = this.getView().getBusyIndicatorDelay(),
  168. oViewModel = this.getModel("detailView"),
  169. oLineItemTable = this.byId("lineItemsList"),
  170. iOriginalLineItemTableBusyDelay = oLineItemTable.getBusyIndicatorDelay();
  171. // Make sure busy indicator is displayed immediately when
  172. // detail view is displayed for the first time
  173. oViewModel.setProperty("/delay", 0);
  174. oViewModel.setProperty("/lineItemTableDelay", 0);
  175. oLineItemTable.attachEventOnce("updateFinished", function() {
  176. // Restore original busy indicator delay for line item table
  177. oViewModel.setProperty("/lineItemTableDelay", iOriginalLineItemTableBusyDelay);
  178. });
  179. // Binding the view will set it to not busy - so the view is always busy if it is not bound
  180. oViewModel.setProperty("/busy", true);
  181. // Restore original busy indicator delay for the detail view
  182. oViewModel.setProperty("/delay", iOriginalViewBusyDelay);
  183. },
  184. onTabSelect : function(oEvent){
  185. var sSelectedTab = oEvent.getParameter("selectedKey");
  186. this.getRouter().navTo("object", {
  187. objectId: this._sObjectId,
  188. query: {
  189. tab: sSelectedTab
  190. }
  191. }, true);// true without history
  192. },
  193. _onHandleTelephonePress : function (oEvent){
  194. var sNumber = oEvent.getSource().getText();
  195. URLHelper.triggerTel(sNumber);
  196. },
  197. /**
  198. * Set the full screen mode to false and navigate to master page
  199. */
  200. onCloseDetailPress: function () {
  201. this.getModel("appView").setProperty("/actionButtonsInfo/midColumn/fullScreen", false);
  202. // No item should be selected on master after detail page is closed
  203. this.getOwnerComponent().oListSelector.clearMasterListSelection();
  204. this.getRouter().navTo("master");
  205. },
  206. /**
  207. * Toggle between full and non full screen mode.
  208. */
  209. toggleFullScreen: function () {
  210. var bFullScreen = this.getModel("appView").getProperty("/actionButtonsInfo/midColumn/fullScreen");
  211. this.getModel("appView").setProperty("/actionButtonsInfo/midColumn/fullScreen", !bFullScreen);
  212. if (!bFullScreen) {
  213. // store current layout and go full screen
  214. this.getModel("appView").setProperty("/previousLayout", this.getModel("appView").getProperty("/layout"));
  215. this.getModel("appView").setProperty("/layout", "MidColumnFullScreen");
  216. } else {
  217. // reset to previous layout
  218. this.getModel("appView").setProperty("/layout", this.getModel("appView").getProperty("/previousLayout"));
  219. }
  220. }
  221. });
  222. });