Release notes for R1/Amsterdam/1.3.0
[portal.git] / docs / tutorials / portal-sdk / your-angularjs-app.rst
1 Your AngularJS app
2 =========================
3  
4 Now that we've established a database connection, it's time to work on the web side of your app. To start, we'll create some files in :code:`sdk/ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/myapp/myfirstpage`.
5
6 myfirstpage.html
7 ----------------
8
9 This is your landing page. Its purpose is to pull in all the JavaScript and CSS that your app might need as well as to set up your AngularJS app (:code:`app.js`) and your app's controller (:code:`controller.js`), data-services (:code:`data-service.js`), and routing information (:code:`route.js`) --- more on these in a moment. There is likely much that can be removed from this file (it is boilerplate copied from a sample Portal SDK app), but to save yourself headaches at first, just cut and paste all of it into the :code:`sdk/ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/myapp/myfirstpage/myfirstpage.html` you created earlier in, redundancies and all:
10
11 .. code-block:: html
12
13   <!DOCTYPE html>
14   <!-- Single-page application for EPSDK-App using DS2 look and feel. -->
15   <html>
16     <head>
17       <meta charset="ISO-8859-1">
18       <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
19       
20       <title>Welcome</title>
21     
22       <!-- B2b Library -->
23       <link rel="stylesheet" type="text/css" href="app/fusion/external/b2b/css/b2b-angular/b2b-angular.css">
24       <link rel="stylesheet" type="text/css" href="app/fusion/external/b2b/css/b2b-angular/font_icons.css">
25         
26       <!-- icons in open source -->
27       <link rel="stylesheet" type="text/css" href="app/fusion/external/ds2/css/digital-ng-library/ionicons.css">
28       <link rel="stylesheet" type="text/css" href="app/fusion/external/ds2/css/digital-ng-library/ecomp-ionicons.css">
29       
30       <link rel="stylesheet" type="text/css" href="app/fusion/external/angular-bootstrap/ui-bootstrap-csp.css">
31       <link rel="stylesheet" type="text/css" href="app/fusion/external/angular-gridster/dist/angular-gridster.min.css">
32       <link rel="stylesheet" type="text/css" href="static/fusion/sample/css/scribble.css" />
33       <link rel="stylesheet" type="text/css" href="static/fusion/sample/css/welcome.css" />
34                                       
35       <link rel="stylesheet" type="text/css" href="app/fusion/styles/ecomp.css">
36       
37       <!-- Common scripts -->  
38       <script src="app/fusion/external/angular-1.4.8/angular.min.js"></script>
39       <script src="app/fusion/external/angular-1.4.8/angular-messages.js"></script>
40       <script src="app/fusion/external/angular-1.4.8/angular-touch.js"></script>
41       <script src="app/fusion/external/angular-1.4.8/angular-sanitize.js"></script>  
42       <script src="app/fusion/external/angular-1.4.8/angular-route.min.js"></script>
43       <script src="app/fusion/external/angular-1.4.8/angular-cookies.min.js"></script>
44       <script src="app/fusion/external/jquery/dist/jquery.min.js"></script>
45       <script src="app/fusion/external/javascript-detect-element-resize/jquery.resize.js"></script>
46       <script src="app/fusion/external/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
47       <script src="app/fusion/external/angular-gridster/dist/angular-gridster.min.js"></script>
48           
49       <!-- EPSDK App scripts and common services -->  
50       <!-- B2b Library -->
51       <script src="app/fusion/external/b2b/js/b2b-angular/b2b-library.min.js"></script>
52       <script src="app/fusion/scripts/DS2-services/ds2-modal/modalService.js"></script>
53       <script src="app/fusion/scripts/myapp/myfirstpage/app.js"></script>  
54           
55       <script src="app/fusion/scripts/DS2-services/userInfoServiceDS2.js"></script>   
56       <script src="app/fusion/scripts/DS2-services/headerServiceDS2.js"></script>
57       <script src="app/fusion/scripts/DS2-services/leftMenuServiceDS2.js"></script>
58       <script src="app/fusion/scripts/DS2-services/manifestService.js"></script>
59         
60       <script src="app/fusion/scripts/DS2-directives/footer.js"></script>
61       <script src="app/fusion/scripts/DS2-directives/ds2Header.js"></script>
62       <script src="app/fusion/scripts/DS2-directives/ds2LeftMenu.js"></script>
63       <script src="app/fusion/scripts/DS2-directives/b2b-leftnav-ext.js"></script> 
64       <script src= "app/fusion/scripts/DS2-services/userInfoServiceDS2.js"></script>  
65       
66       <!-- Page specific items -->
67       <script src="app/fusion/scripts/myapp/myfirstpage/controller.js"></script>
68       <script src="app/fusion/scripts/myapp/myfirstpage/route.js"></script>  
69       <script src="app/fusion/scripts/myapp/myfirstpage/data-service.js"></script>  
70       
71       <style>
72         .controls {
73           margin-bottom: 20px;
74         }
75         .page-header {
76           margin-top: 20px;
77         }
78         ul {
79           list-style: none;
80         }
81         .box {
82           height: 100%;
83           border: 1px solid #ccc;
84           background-color: #fff;
85           position: relative;
86           overflow: hidden;
87         }
88         .box-header {
89           background-color: #eee;
90           padding: 0px 0px 0px 0px;
91           margin-bottom: -25px;
92           cursor: move;
93           position: relative;
94         }
95         .box-header h3 {
96           margin-top: 0px;
97           display: inline-block;
98         }
99         .box-content {
100           padding: 10px;
101           display:block;
102           height: 100%;
103           position: relative;
104           overflow-x:auto;
105           overflow-y:auto;    
106         }
107         .box-header-btns {
108           top: 15px;
109           right: 10px;
110           cursor: pointer;
111           position: absolute;
112         }
113         .gridster {
114           border: none;
115           position:relative;    
116         }
117         .box-content .box-content-frame{
118         }
119         .box table{
120           border:none;
121           display:block;
122         }
123         .box table tr{
124           line-height:20px;
125         }
126         .box table th{
127           border:none;
128           line-height:20px;
129         }
130         .menu-container{
131           margin-top:0px
132         }
133         .handle-e {
134           width:3px;
135         }
136       </style>
137     </head>
138     <body class="appBody" ng-app="abs">
139       <!-- commented the header for now to avoid duplicate headers on portal -->
140       <div ds2-Header class="header-container" ></div>
141       <div ds2-menu id="menuContainer" class="menu-container"></div>
142       <div ng-view id="rightContentProfile" class="content-container"></div>  
143       <div ds2-Footer class="footer-container"></div>
144    </body>
145   </html>
146
147 app.js
148 ------
149
150 :code:`sdk/ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/myapp/myfirstpage/app.js` contains a single line:
151
152 .. code-block:: javascript
153
154   var appDS2=angular.module("abs", ['ngRoute', 'ngMessages','modalServices', 'ngCookies', 'b2b.att','gridster','ui.bootstrap','ui.bootstrap.modal']);
155
156 Don't worry too much about the particulars here. Just know that the list of strings are dependencies. You might add or remove some later.
157
158 controller.js
159 -------------
160
161 The controller is where most of the action happens. The controller is complex, but there is one basic thing that needs clarifying. In AngularJS, :code:`$scope` essentially says, "This should be visible inside the associated :ref:`template`." You'll gradually come to understand other aspects of the controller as you work with it.
162
163 Copy and paste the following into :code:`sdk/ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/myapp/myfirstpage/controller.js`:
164
165 .. code-block:: javascript
166
167   appDS2
168     .controller('myFirstPageController', function($scope, $routeParams, $location, $interval, $http, $q, $modal, $log, ManifestService, dataService) {
169       /**********************************************
170        * FUNCTIONS
171        **********************************************/
172   
173       $scope.init = function () {
174         // Set up and initialize a state object. This object will contain information about the state of
175         // the application as the user interacts with it.
176         $scope.state = {
177           // Holds a message string for testing
178           message: "Hello from myFirstPageController",
179         }
180       }
181     
182       /**********************************************
183        * Setup and initialize the app on load
184        **********************************************/
185
186       $scope.init();
187
188     }); // end .controller
189
190 data-service.js
191 ---------------
192
193 :code:`data-service.js` is the bridge between the Java side of your app and the web side. The dataService makes http requests to :code:`MyAppController.java`. Once a response is received (it will not block, waiting for a response, because you want your app to continue working while waiting), it executes the :code:`then` portion of the code, which simply returns the result back to wherever it was called from.
194
195 We'll see it in action soon. For now copy and paste the following into :code:`sdk/ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/myapp/myfirstpage/data-service.js`:
196
197 .. code-block:: javascript
198
199   appDS2.factory('dataService', function ($http, $q, $log) {
200     return {
201       // Service to return chart data
202       getChartData: function(direction) {
203         return $http.get("get_chart_data/" + direction + "/").then(function(response) {
204           if (typeof response.data === 'object' || typeof response.data === 'string') {
205             return response.data;
206           }
207           else {
208             return $q.reject(response.data);
209           }
210         }, function(response) {
211           return $q.reject(response.data);
212         })
213       }
214     };
215   });
216
217 route.js
218 --------
219
220 :code:`route.js` tells AngularJS how to map specific kinds of incoming requests to specific pages and controllers. AngularJS uses the 'location' hashtag to pass parameters to the client as seen in the commented :code:`when` block example below.
221
222 Copy and paste the following into :code:`sdk/ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/myapp/myfirstpage/route.js`:
223
224 .. code-block:: javascript
225
226   appDS2.config(function($routeProvider) {
227     $routeProvider
228  
229     // Example route that maps a specific URL to another page and
230     // controller.
231     // 
232     // This would respond to:
233     //    http://localhost:8080/epsdk-app-os#/date1/2017-08-01/date2/2017-08-07/
234     //
235     //.when('/date1/:date1/date2/:date2/', {
236     //  templateUrl: 'app/fusion/scripts/myapp/myfirstpage/someotherpage.html',
237     //  controller : "anotherController"
238     //})
239   
240     .otherwise({
241       templateUrl: 'app/fusion/scripts/myapp/myfirstpage/template.html',
242       controller : "myFirstPageController"
243     });
244   });
245
246 .. _template:
247
248 template.html
249 -------------
250
251 The AngularJS template holds all the HTML and AngularJS directives that are presented to the user inside the ONAP Portal SDK boilerplate navigation. It is referenced in the :code:`route.js` file. Copy and paste the following into :code:`sdk/ecomp-sdk/epsdk-app-os/src/main/webapp/app/fusion/scripts/myapp/myfirstpage/template.html`:
252
253 .. code-block:: html
254
255   <div id="page-content" class="content" style="padding: 25px;">
256     <p>{{state.message}}</p>
257   </div>
258
259 Now, compile, install, and login.
260
261 Adding your new page to the SDK navigation
262 ------------------------------------------
263
264 First, click on :code:`Menus` in the :code:`Admin` navigation menu:
265
266 .. image:: img/menus.png
267         :width: 320px
268
269 Now, click the :code:`Add Menu Item` button at the top of the page:
270
271 .. image:: img/addmenu.png
272         :width: 200px
273
274 Finally, fill out the form in the following way.
275
276 .. note:: "myfirstpage" is a reference to the name we defined in :ref:`definitions.xml`.
277
278 .. image:: img/newmenuitem.png
279         :width: 640px
280
281 To reload the navigation, click :code:`Home` in the Portal SDK navigation menu. You should see your new menu item at the top. If all went well, you should see "Hello from myFirstPageController" in the content area to the right of the navigation menu.
282