Merge "Added an archetype odl-model-project"
[controller.git] / opendaylight / web / devices / src / main / resources / js / page.js
1 /* 
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved. 
3  * 
4  * This program and the accompanying materials are made available under the 
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution, 
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 //PAGE Devices
10 one.f = {};
11
12 // specify dashlets and layouts
13
14 one.f.dashlet = {
15     nodesLearnt : {
16         id : 'nodesLearnt',
17         name : 'Nodes Learnt'
18     },
19     staticRouteConfig : {
20         id : 'staticRouteConfig',
21         name : 'Static Route Configuration'
22     },
23     subnetGatewayConfig : {
24         id : 'subnetGatewayConfig',
25         name : 'Subnet Gateway Configuration'
26     },
27     spanPortConfig : {
28         id : 'spanPortConfig',
29         name : 'SPAN Port Configuration'
30     }
31 };
32
33 one.f.menu = {
34     left : {
35         top : [
36             one.f.dashlet.nodesLearnt
37         ],
38         bottom : [
39             one.f.dashlet.staticRouteConfig
40         ]
41     },
42     right : {
43         top : [],
44         bottom : [
45             one.f.dashlet.subnetGatewayConfig,
46             one.f.dashlet.spanPortConfig
47         ]
48     }
49 };
50
51 /**Devices Modules */
52 one.f.switchmanager = {
53     rootUrl: "controller/web/devices",
54     createTable: function(columnNames, body) {
55         var tableAttributes = ["table-striped", "table-bordered", "table-condensed"];
56         var $table = one.lib.dashlet.table.table(tableAttributes);
57         var tableHeaders = columnNames;
58         var $thead = one.lib.dashlet.table.header(tableHeaders);
59         var $tbody = one.lib.dashlet.table.body(body, tableHeaders);
60         $table.append($thead)
61         .append($tbody);
62         return $table;
63     },
64     validateName: function(name) {
65         return (name.length < 256);
66     }
67 };
68
69 one.f.switchmanager.nodesLearnt = {
70     id: {
71         dashlet: {
72             popout: "one_f_switchmanager_nodesLearnt_id_dashlet_popout",
73             datagrid: "one_f_switchmanager_nodesLearnt_id_dashlet_datagrid"
74         },
75         modal: {
76             modal: "one_f_switchmanager_nodesLearnt_id_modal_modal",
77             configure: "one_f_switchmanager_nodesLearnt_id_modal_configure",
78             ports: "one_f_switchmanager_nodesLearnt_id_modal_ports",
79             save: "one_f_switchmanager_nodesLearnt_id_modal_save",
80             datagrid: "one_f_switchmanager_nodesLearnt_id_modal_datagrid",
81             portsDatagrid: "one_f_switchmanager_nodesLearnt_id_modal_portsDatagrid",
82             form: {
83                 nodeId: "one_f_switchmanager_nodesLearnt_id_modal_form_nodeid",
84                 nodeName : "one_f_switchmanager_nodesLearnt_id_modal_form_nodename",
85                 portStatus : "one_f_switchmanager_nodesLearnt_id_modal_form_portstatus",
86                 tier: "one_f_switchmanager_nodesLearnt_id_modal_form_tier",
87                 operationMode: "one_f_switchmanager_nodesLearnt_id_modal_form_opmode"
88             }
89         }
90     },
91     dashlet: function($dashlet) {
92         var url = one.f.switchmanager.rootUrl + "/nodesLearnt";
93         one.lib.dashlet.empty($dashlet);
94         $dashlet.append(one.lib.dashlet.header(one.f.dashlet.nodesLearnt.name));
95
96         one.f.switchmanager.nodesLearnt.ajax.main(url, function(content) {
97             var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.nodesLearnt.id.dashlet.datagrid, {
98                 searchable: true,
99                 filterable: false,
100                 pagination: true,
101                 flexibleRowsPerPage: true
102                 }, "table-striped table-condensed");
103             $dashlet.append($gridHTML);
104             var dataSource = one.f.switchmanager.nodesLearnt.data.gridDataSource.abridged(content);
105             $("#" + one.f.switchmanager.nodesLearnt.id.dashlet.datagrid).datagrid({dataSource: dataSource}).on("loaded", function() {
106                 $(this).find("tbody a").click(one.f.switchmanager.nodesLearnt.modal.initialize.updateNode);
107             });
108             
109             $("#" + one.f.switchmanager.nodesLearnt.id.dashlet.datagrid).datagrid({dataSource: dataSource}).on("loaded", function() {
110                 $(this).find("tbody span").click(function(){
111                     one.f.switchmanager.nodesLearnt.modal.initialize.displayPorts($(this));
112                 });
113             });
114             
115         });
116     },
117     ajax : {
118         main : function(url, callback) {
119             $.getJSON(url, function(data) {
120                 callback(data);
121             });
122         }
123     },
124     modal : {
125         initialize: {
126             updateNode: function(evt) {
127                 one.f.switchmanager.nodesLearnt.ajax.main(one.f.switchmanager.rootUrl + "/tiers", function(tiers) {
128
129                     var nodeId = decodeURIComponent(evt.target.id);
130                     var h3;
131                     var footer = [];
132                     var $body = one.f.switchmanager.nodesLearnt.modal.body.updateNode(nodeId, JSON.parse(decodeURIComponent(evt.target.getAttribute("switchDetails"))), tiers);
133                     if (evt.target.getAttribute("privilege") == 'WRITE'){
134                         h3 = "Update Node Information";
135                         footer = one.f.switchmanager.nodesLearnt.modal.footer.updateNode();
136                     } else { //disable node edit
137                         $body.find('*').attr('disabled', 'disabled');
138                         h3 = 'Node Information';
139                     }
140                     
141                     var $modal = one.lib.modal.spawn(one.f.switchmanager.nodesLearnt.id.modal.configure, h3, "", footer);
142                     // bind save button
143                     $('#' + one.f.switchmanager.nodesLearnt.id.modal.save, $modal).click(function() {
144                         one.f.switchmanager.nodesLearnt.modal.save($modal);
145                     });
146
147                     // inject body (nodePorts)
148                     one.lib.modal.inject.body($modal, $body);
149                     $modal.modal();
150                 });
151             },
152             popout: function() {
153                 var h3 = "Nodes Learnt";
154                 var footer = one.f.switchmanager.nodesLearnt.modal.footer.popout();
155                 var $modal = one.lib.modal.spawn(one.f.switchmanager.nodesLearnt.id.modal.modal, h3, "", footer);
156                 var $body = one.f.switchmanager.nodesLearnt.modal.body.popout($modal);
157                 return $modal;
158             },
159             displayPorts: function(ports) {
160                 var content = JSON.parse(decodeURIComponent(ports.attr("ports")));
161                 
162                 var h3 = ((ports.attr("nodeName") == "None")? ports.attr("nodeId") : ports.attr("nodeName"))
163                 var footer = [];
164                 var $modal = one.lib.modal.spawn(one.f.switchmanager.nodesLearnt.id.modal.ports, h3, "", footer);
165                 
166                 var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.nodesLearnt.id.modal.portsDatagrid, {
167                     searchable: true,
168                     filterable: false,
169                     pagination: true,
170                     flexibleRowsPerPage: true,
171                     popout: true
172                     }, "table-striped table-condensed");
173                 one.lib.modal.inject.body($modal, $gridHTML);
174                 $modal.on("shown", function() {
175                     var dataSource = one.f.switchmanager.nodesLearnt.data.gridDataSource.displayPorts(content);
176                     $("#" + one.f.switchmanager.nodesLearnt.id.modal.portsDatagrid).datagrid({
177                         dataSource: dataSource,
178                         stretchHeight: false
179                     });
180                 });
181                 $modal.modal();
182             }
183         },
184         body: {
185             updateNode: function(nodeId, switchDetails, tiers) {
186                 var $form = $(document.createElement('form'));
187                 var $fieldset = $(document.createElement('fieldset'));
188                 // node ID. not editable.
189                 var $label = one.lib.form.label("Node ID");
190                 var $input = one.lib.form.input("node id");
191                 $input.attr('id', one.f.switchmanager.nodesLearnt.id.modal.form.nodeId);
192                 $input.attr("disabled", true);
193                 $input.attr("value", nodeId);
194                 $fieldset.append($label).append($input);
195                 // node name
196                 var $label = one.lib.form.label("Node Name");
197                 var $input = one.lib.form.input("Node Name");
198                 $input.attr('id', one.f.switchmanager.nodesLearnt.id.modal.form.nodeName);
199                 if(switchDetails["nodeName"] != null) {
200                     $input.attr('value', switchDetails["nodeName"]);
201                 }
202                 $fieldset.append($label).append($input);
203                 // node tier
204                 var $label = one.lib.form.label("Tier");
205                 var $select = one.lib.form.select.create(tiers);
206                 $select.attr('id', one.f.switchmanager.nodesLearnt.id.modal.form.tier);
207                 $select.val(switchDetails["tier"]);
208                 $fieldset.append($label).append($select);
209                 // operation mode
210                 var $label = one.lib.form.label("Operation Mode");
211                 var $select = one.lib.form.select.create(
212                         ["Allow reactive forwarding", "Proactive forwarding only"]);
213                 $select.attr('id', one.f.switchmanager.nodesLearnt.id.modal.form.operationMode);
214                 if ((one.main.registry != undefined) && (one.main.registry.container != 'default')) {
215                     $select.attr("disabled", true);
216                 }
217                 $select.val(switchDetails["mode"]);
218                 $fieldset.append($label).append($select);
219                 $form.append($fieldset);
220                 return $form;
221             },
222             popout: function($modal) {
223                 var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.nodesLearnt.id.modal.datagrid, {
224                         searchable: true,
225                         filterable: false,
226                         pagination: true,
227                         flexibleRowsPerPage: true,
228                         popout: true
229                         }, "table-striped table-condensed");
230                 one.lib.modal.inject.body($modal, $gridHTML);
231                 // attach to shown event of modal 
232                 $modal.on("shown", function() {
233                     var url = one.f.switchmanager.rootUrl + "/nodesLearnt";
234                     one.f.switchmanager.nodesLearnt.ajax.main(url, function(content) {
235                         var dataSource = one.f.switchmanager.nodesLearnt.data.gridDataSource.popout(content);
236                         $("#" + one.f.switchmanager.nodesLearnt.id.modal.datagrid).datagrid({
237                             dataSource: dataSource,
238                             stretchHeight: false
239                         })
240                         .on("loaded", function() {
241                             $("#" + one.f.switchmanager.nodesLearnt.id.modal.datagrid).find("tbody span").click(function(){
242                                 one.f.switchmanager.nodesLearnt.modal.initialize.displayPorts($(this));
243                             });
244                         });
245                     });
246                 });
247             }
248         },
249         save: function($modal) {
250             var result = {};
251             result['nodeName'] = $('#' + one.f.switchmanager.nodesLearnt.id.modal.form.nodeName, $modal).val();
252             if(!one.f.switchmanager.validateName(result['nodeName'])) {
253                 alert("Node name can contain upto 255 characters");
254                 return;
255             }
256             result['nodeId'] = $('#' + one.f.switchmanager.nodesLearnt.id.modal.form.nodeId, $modal).val();
257             result['tier'] = $('#' + one.f.switchmanager.nodesLearnt.id.modal.form.tier, $modal).val();
258             result['operationMode'] = $('#' + one.f.switchmanager.nodesLearnt.id.modal.form.operationMode, $modal).val();
259             one.f.switchmanager.nodesLearnt.modal.ajax(result, 
260                 function(response) {
261                     if(response.status == true) {
262                         $modal.modal('hide');
263                         one.topology.update(); // refresh visual topology with new name
264                         // TODO: Identify dashlet by inserting a nodesLearnt div 
265                         // in the dashlet() instead
266                         one.f.switchmanager.nodesLearnt.dashlet($("#left-top .dashlet"));
267                     } else {
268                         alert(response.message);
269                     }
270                     
271                 });
272         },
273         ajax: function(requestData, callback) {
274             $.getJSON(one.f.switchmanager.rootUrl + "/nodesLearnt/update", requestData, function(response) {
275                 callback(response);
276             });
277         },
278         footer: {
279             updateNode: function() {
280                 var footer = [];
281                 var saveButton = one.lib.dashlet.button.single("Save", one.f.switchmanager.nodesLearnt.id.modal.save, "btn-success", "");
282                 var $saveButton = one.lib.dashlet.button.button(saveButton);
283                 footer.push($saveButton);
284
285                 return footer;
286             },
287             popout: function() {
288                 // TODO: Maybe put a close button in the footer?
289                 return [];
290             }
291         }
292     },
293     // data functions
294     data : {
295         gridDataSource: {
296             abridged: function(data) {
297                 var source = new StaticDataSource({
298                     columns: [
299                         {
300                             property: 'nodeName',
301                             label: 'Node Name',
302                             sortable: true
303                         },
304                         {
305                             property: 'nodeId',
306                             label: 'Node ID',
307                             sortable: true
308                         },
309                         {
310                             property: 'ports',
311                             label: 'Ports',
312                             sortable: true
313                         }
314                     ],
315                     data: data.nodeData,
316                     formatter: function(items) {
317                     $.each(items, function (index, item) {
318                         var nodeName = item.nodeName;
319                         var nodeNameEntry = item.nodeName ? item.nodeName : "Click to update";
320                         item.nodeName = '<a href="#" id="' + item.nodeId + '" switchDetails=' + encodeURIComponent(JSON.stringify(item)) + 
321                         ' privilege=' + data.privilege + '>' + nodeNameEntry + '</a>';
322                         
323                         var ports = item.ports;
324                         item.ports = '<span class="nodePorts" style="cursor:pointer;color: #08c" ports='+encodeURIComponent(JSON.stringify(item.ports)) + ' nodeId=' + item.nodeId 
325                             + ' nodeName=' + nodeName  
326                             + '>' + ports.match(/<\/span>/g).length+'</span>';
327                     }); 
328                     },
329                     delay: 0
330                 });
331                 return source;
332
333             },
334             popout: function(data) {
335                 var source = new StaticDataSource({
336                     columns: [
337                         {
338                             property: 'nodeName',
339                             label: 'Node Name',
340                             sortable: true
341                         },
342                         {
343                             property: 'nodeId',
344                             label: 'Node ID',
345                             sortable: true
346                         },
347                         {
348                             property: 'tierName',
349                             label: 'Tier Name',
350                             sortable: true
351                         },
352                         {
353                             property: 'mac',
354                             label: 'MAC',
355                             sortable: true
356                         },
357                         {
358                             property: 'ports',
359                             label: 'Ports',
360                             sortable: true
361                         }
362                     ],
363                     data: data.nodeData,
364                     formatter: function(items) {
365                         $.each(items, function (index, item) {
366                             var ports = item.ports;
367                             item.ports = '<span class="nodePorts" style="cursor: pointer;color: #08c" ports='+encodeURIComponent(JSON.stringify(item.ports)) + ' nodeId=' + item.nodeId 
368                                 + ' nodeName=' + item.nodeName  
369                                 + '>' + ports.match(/<\/span>/g).length+'</span>';
370                         }); 
371                     },
372                     delay: 0
373                 });
374                 return source;
375             },
376             displayPorts: function(content){
377                 var data=[];
378                 var start=0;;
379                 var finish=content.indexOf("<br>",start);
380                 while(finish != -1){
381                     data.push({"ports":content.substring(start,finish)});
382                     start=finish+4
383                     finish=content.indexOf("<br>",start);
384                 }
385                 var source = new StaticDataSource({
386                     columns: [
387                         {
388                             property: 'ports',
389                             label: 'Ports',
390                             sortable: true
391                         }
392                     ],
393                     data:data,
394                     delay: 0
395                 });
396                 
397                 return source;
398             }
399         },
400         abridged : function(data) {
401             var result = [];
402             $.each(data.nodeData, function(key, value) {
403                 var tr = {};
404                 var entry = [];
405                 var nodeNameEntry = value["nodeName"] ? value["nodeName"] : "Click to update";
406
407                 // TODO: Move anchor tag creation to one.lib.form.
408                 var aTag;
409                 aTag = document.createElement("a");
410                 aTag.privilege = data.privilege;
411                 aTag.addEventListener("click", one.f.switchmanager.nodesLearnt.modal.initialize.updateNode);
412                 aTag.addEventListener("mouseover", function(evt) {
413                     evt.target.style.cursor = "pointer";
414                 }, false);
415                 aTag.setAttribute("id", encodeURIComponent(value["nodeId"]));
416                 aTag.switchDetails = value;
417                 aTag.innerHTML = nodeNameEntry;
418                 entry.push(aTag);
419                 entry.push(value["nodeId"]);
420                 entry.push(value["ports"]);
421                 tr.entry = entry;
422                 result.push(tr);
423             });
424             return result;
425         },
426         popout : function(data) {
427             var result = [];
428             $.each(data.nodeData, function(key, value) {
429                 var tr = {};
430                 // fill up all the td's
431                 var entry = [];
432                 var nodenameentry = value["nodeName"] ? value["nodeName"] : "No name provided";
433                 entry.push(nodenameentry);
434                 entry.push(value["nodeId"]);
435                 entry.push(value["tierName"]);
436                 entry.push(value["mac"]);
437                 entry.push(value["ports"]);
438                 tr.entry = entry;
439                 result.push(tr);
440             });
441             return result;
442         }
443     }
444 };
445
446 one.f.switchmanager.subnetGatewayConfig = {
447     id: {
448         dashlet: {
449             addIPAddress: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_addIP",
450             addPorts: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_addPorts",
451             removeIPAddress: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_removeIP",
452             datagrid: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_datagrid",
453             selectAll: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_selectAll"
454         }, 
455         modal: {
456             modal: "one_f_switchmanager_subnetGatewayConfig_id_modal_modal",
457             save: "one_f_switchmanager_subnetGatewayConfig_id_modal_save",
458             form: {
459                 name : "one_f_switchmanager_subnetGatewayConfig_id_modal_form_gatewayname",
460                 gatewayIPAddress : "one_f_switchmanager_subnetGatewayConfig_id_modal_form_gatewayipaddress",
461                 nodeId: "one_f_switchmanager_subnetGatewayConfig_id_modal_form_nodeid",
462                 ports: "one_f_switchmanager_subnetGatewayConfig_id_modal_form_ports"
463             }
464         }
465     },
466     // device ajax calls
467     dashlet: function($dashlet) {
468         one.lib.dashlet.empty($dashlet);
469         $dashlet.append(one.lib.dashlet.header(one.f.dashlet.subnetGatewayConfig.name));
470         // Add gateway IP Address button
471         var url = one.f.switchmanager.rootUrl + "/subnets";
472         one.f.switchmanager.subnetGatewayConfig.ajax.main(url, {}, function(content) {
473
474             if (content.privilege === 'WRITE') {
475                 var button = one.lib.dashlet.button.single("Add Gateway IP Address",
476                     one.f.switchmanager.subnetGatewayConfig.id.dashlet.addIPAddress, "btn-primary", "btn-mini");
477                 var $button = one.lib.dashlet.button.button(button);
478                 $button.click(function() {
479                     var $modal = one.f.switchmanager.subnetGatewayConfig.modal.initialize.gateway();
480                     $modal.modal();
481                 });
482                 $dashlet.append($button);
483
484                 // Delete gateway ip address button
485                 var button = one.lib.dashlet.button.single("Delete Gateway IP Address(es)",
486                     one.f.switchmanager.subnetGatewayConfig.id.dashlet.removeIPAddress, "btn-primary", "btn-mini");
487                 var $button = one.lib.dashlet.button.button(button);
488                 $button.click(function() {
489                     var requestData = {};
490                     var gatewaysToDelete = [];
491                     var checkedCheckBoxes = $("#" + one.f.switchmanager.subnetGatewayConfig.id.dashlet.datagrid).find("tbody input:checked")
492                     checkedCheckBoxes.each(function(index, value) {
493                         gatewaysToDelete.push(checkedCheckBoxes[index].id);
494                     });
495                     if (gatewaysToDelete.length > 0) {
496                         requestData["gatewaysToDelete"] = gatewaysToDelete.toString();
497                         var url = one.f.switchmanager.rootUrl + "/subnetGateway/delete";
498                         one.f.switchmanager.subnetGatewayConfig.ajax.main(url, requestData, function(response) {
499                             if (response.status == true) {
500                                 // refresh dashlet by passing dashlet div as param 
501                                 one.lib.alert("Subnet Gateway(s) successfully removed");
502                             } else {
503                                 one.lib.alert(response.message);
504                             }
505                             one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
506                         });
507                     }
508                 });
509                 $dashlet.append($button);
510
511                 // Add Ports button
512                 var button = one.lib.dashlet.button.single("Add Ports",
513                     one.f.switchmanager.subnetGatewayConfig.id.dashlet.addPorts, "btn-primary", "btn-mini");
514                 var $button = one.lib.dashlet.button.button(button);
515                 $button.click(function() {
516                     var $modal = one.f.switchmanager.subnetGatewayConfig.modal.initialize.ports();
517                     $modal.modal();
518                 });
519                 $dashlet.append($button);
520             }
521             var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.subnetGatewayConfig.id.dashlet.datagrid, {
522                 searchable: true,
523                 filterable: false,
524                 pagination: true,
525                 flexibleRowsPerPage: true
526                 }, "table-striped table-condensed");
527             $dashlet.append($gridHTML);
528             var dataSource = one.f.switchmanager.subnetGatewayConfig.data.devicesgrid(content);
529             $("#" + one.f.switchmanager.subnetGatewayConfig.id.dashlet.datagrid).datagrid({dataSource: dataSource})
530             .on("loaded", function() {
531                 $("#"+one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll).click(function() {
532                     $("#" + one.f.switchmanager.subnetGatewayConfig.id.dashlet.datagrid).find(':checkbox').prop('checked',
533                         $("#"+one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll).is(':checked'));
534                 });
535                 $(".subnetGatewayConfig").click(function(){
536                     if (!$('.subnetGatewayConfig[type=checkbox]:not(:checked)').length) {
537                         $("#"+one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll)
538                             .prop("checked",
539                           true);
540                     } else {
541                         $("#"+one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll)
542                             .prop("checked",
543                          false);
544                     }
545                     event.stopPropagation();
546                 });
547              });
548         });
549     },
550     ajax : {
551         main : function(url, requestData, callback) {
552             $.getJSON(url, requestData, function(data) {
553                 callback(data);
554             });
555         }
556     },
557     registry: {},
558     modal : {
559         initialize: {
560             gateway: function() {
561                 var h3 = "Add Gateway IP Address";
562                 var footer = one.f.switchmanager.subnetGatewayConfig.modal.footer();
563                 var $modal = one.lib.modal.spawn(one.f.switchmanager.subnetGatewayConfig.id.modal.modal, h3, "", footer);
564                 // bind save button
565                 $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.save, $modal).click(function() {
566                     one.f.switchmanager.subnetGatewayConfig.modal.save.gateway($modal);
567                 });
568                 var $body = one.f.switchmanager.subnetGatewayConfig.modal.body.gateway();
569                 one.lib.modal.inject.body($modal, $body);
570                 return $modal;
571             },
572             ports: function() {
573                 var h3 = "Add Ports";
574                 var footer = one.f.switchmanager.subnetGatewayConfig.modal.footer();
575                 var $modal = one.lib.modal.spawn(one.f.switchmanager.subnetGatewayConfig.id.modal.modal, h3, "", footer);
576                 // bind save button
577                 $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.save, $modal).click(function() {
578                     one.f.switchmanager.subnetGatewayConfig.modal.save.ports($modal);
579                 });
580                 
581                 // TODO: Change to subnetGateway instead.
582                 one.f.switchmanager.spanPortConfig.modal.ajax.nodes(function(nodes, nodeports) {
583                     var $body = one.f.switchmanager.subnetGatewayConfig.modal.body.ports(nodes, nodeports);
584                     one.lib.modal.inject.body($modal, $body);
585                 });
586                 return $modal;
587             }
588         },
589         save: {
590             gateway: function($modal) {
591                 var result = {};
592                 result['gatewayName'] = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.name, $modal).val();
593                 if(!one.f.switchmanager.validateName(result['gatewayName'])) {
594                     alert("Gateway name can contain upto 255 characters");
595                     return;
596                 }
597                 result['gatewayIPAddress'] = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.gatewayIPAddress, $modal).val();
598                 one.f.switchmanager.subnetGatewayConfig.modal.ajax.gateway(result, 
599                     function(response) {
600                         if(response.status == true) {
601                             $modal.modal('hide');
602                             one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
603                         } else {
604                             alert(response.message);
605                         }
606                     });
607             },
608             ports: function($modal) {
609                 var result = {};
610                 var gatewayRegistryIndex = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.name, $modal).val();
611                 result['portsName'] = one.f.switchmanager.subnetGatewayConfig.registry.gateways[gatewayRegistryIndex];
612                 result['nodeId'] = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.nodeId, $modal).val();
613                 result['ports'] = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.ports, $modal).val();
614                 if(!result['portsName'] || result['portsName'] == "") {
615                     alert("No gateway chosen. Cannot add port");
616                     return;
617                 }
618                 if(!result['nodeId'] || result['nodeId'] == "") {
619                     alert("Please select a node.");
620                     return;
621                 }
622                 if(!result['ports'] || result['ports'] == "") {
623                     alert("Please choose a port.");
624                     return;
625                 }
626                 one.f.switchmanager.subnetGatewayConfig.modal.ajax.ports(result, 
627                     function(response) {
628                         if(response.status == true) {
629                             $modal.modal('hide');
630                             one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
631                         } else {
632                             alert(response.message);
633                         }
634                     });
635             }
636         },
637         body: {
638             gateway: function() {
639                 var $form = $(document.createElement('form'));
640                 var $fieldset = $(document.createElement('fieldset'));
641                 // gateway name
642                 var $label = one.lib.form.label("Name");
643                 var $input = one.lib.form.input("Name");
644                 $input.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.name);
645                 $fieldset.append($label).append($input);
646                 // gateway IP Mask 
647                 var $label = one.lib.form.label("Gateway IP Address/Mask");
648                 var $input = one.lib.form.input("Gateway IP Address/Mask");
649                 $input.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.gatewayIPAddress);
650                 $fieldset.append($label).append($input);
651                 
652                 $form.append($fieldset);
653                 return $form;
654             },
655             ports: function(nodes, nodeports) {
656                 var $form = $(document.createElement('form'));
657                 var $fieldset = $(document.createElement('fieldset'));
658                 // gateways drop down
659                 var $label = one.lib.form.label("Gateway Name");
660                 var $select = one.lib.form.select.create(one.f.switchmanager.subnetGatewayConfig.registry.gateways);
661                 $select.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.name);
662                 $select.val($select.find("option:first").val());
663                 $fieldset.append($label).append($select);
664
665                 // node ID
666                 var $label = one.lib.form.label("Node ID");
667                 var $select = one.lib.form.select.create(nodes);
668                 $select.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.nodeId);
669                 one.lib.form.select.prepend($select, { '' : 'Please Select a Node' });
670                 $select.val($select.find("option:first").val());
671                 $fieldset.append($label).append($select);
672
673                 // bind onchange
674                 $select.change(function() {
675                     // retrieve port value
676                     var node = $(this).find('option:selected').attr('value');
677                     one.f.switchmanager.subnetGatewayConfig.registry['currentNode'] = node;
678                     var $ports = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.ports);
679                     var ports = nodeports[node];
680                     one.lib.form.select.inject($ports, ports);
681                     one.lib.form.select.prepend($ports, { '' : 'Please Select a Port' });
682                     $ports.val($ports.find("option:first").val());
683                 });
684
685                 // ports
686                 var $label = one.lib.form.label("Select Port");
687                 var $select = one.lib.form.select.create();
688                 $select.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.ports);
689                 $fieldset.append($label).append($select);
690                 
691                 $form.append($fieldset);
692                 return $form;
693             }
694         },
695         ajax: {
696             gateway: function(requestData, callback) {
697                 $.getJSON(one.f.switchmanager.rootUrl + "/subnetGateway/add", requestData, function(data) {
698                     callback(data);
699             });
700             },
701             ports: function(requestData, callback) {
702                 $.getJSON(one.f.switchmanager.rootUrl + "/subnetGateway/ports/add", requestData, function(data) {
703                     callback(data);
704             });
705             }
706         },
707         footer : function() {
708             var footer = [];
709             var saveButton = one.lib.dashlet.button.single("Save", one.f.switchmanager.subnetGatewayConfig.id.modal.save, "btn-success", "");
710             var $saveButton = one.lib.dashlet.button.button(saveButton);
711             footer.push($saveButton);
712             return footer;
713         }
714     },
715     // data functions
716     data : {
717         devicesgrid: function(data) {
718             one.f.switchmanager.subnetGatewayConfig.registry.gateways = [];
719             var source = new StaticDataSource({
720                     columns: [
721                         {
722                             property: 'selector',
723                             label: "<input type='checkbox'  id='"
724                                 +one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll+"'/>",
725                             sortable: false
726                         },
727                         {
728                             property: 'name',
729                             label: 'Name',
730                             sortable: true
731                         },
732                         {
733                             property: 'subnet',
734                             label: 'Gateway IP Address/Mask',
735                             sortable: true
736                         },
737                         {
738                             property: 'nodePorts',
739                             label: 'Node/Ports',
740                             sortable: false
741                         }
742                     ],
743                     data: data.nodeData,
744                     formatter: function(items) {
745                         $.each(items, function(index, tableRow) {
746                             tableRow["selector"] = '<input type="checkbox" class="subnetGatewayConfig" id=' 
747                                 + tableRow["name"] + '></input>';
748                             var json = tableRow["nodePorts"];
749                             var nodePorts = JSON.parse(json);
750                             var nodePortHtml = "<div>";
751                             $.each(nodePorts, function(index, nodePort) {
752                                 var nodePortID = nodePort["nodeId"] + "/" + nodePort["nodePortId"]; 
753                                 nodePortHtml += nodePort["nodeName"] + " / " + nodePort["nodePortName"];
754                                 nodePortHtml += "&nbsp;";
755                                 nodePortHtml += '<a href="#" id=' + encodeURIComponent(nodePortID) + 
756                                     ' gatewayName=' + tableRow["name"] + 
757                                     ' onclick="javascript:one.f.switchmanager.subnetGatewayConfig.actions.deleteNodePort(this);">Delete</a>';
758                                 nodePortHtml += "<br/>";
759                             });
760                             nodePortHtml += "</div>";
761                             tableRow["nodePorts"] = nodePortHtml;
762                         });
763
764                     },
765                     delay: 0
766                 });
767                 // populate the registry with subnet names
768                 one.f.switchmanager.subnetGatewayConfig.registry.gateways = [];
769                 $.each(data.nodeData, function(key, value) {
770                     one.f.switchmanager.subnetGatewayConfig.registry.gateways.push(value["name"]);
771                 });
772                 return source;          
773         },
774         devices : function(data) {
775             var result = [];
776             one.f.switchmanager.subnetGatewayConfig.registry.gateways = [];
777             $.each(data.nodeData, function(key, value) {
778                 var tr = {};
779                 // fill up all the td's
780                 var subnetConfigObject = $.parseJSON(value["json"]);
781                 var nodePorts = subnetConfigObject.nodePorts;
782                 var $nodePortsContainer = $(document.createElement("div"));
783                 
784                 for(var i = 0; i < nodePorts.length; i++) {
785                     var nodePort = nodePorts[i];
786                     $nodePortsContainer.append(nodePort + " ");
787                     // add delete anchor tag to delete ports
788                     var aTag = document.createElement("a");
789                     aTag.setAttribute("id", encodeURIComponent(nodePort));
790                     aTag.gatewayName = value["name"];
791                     aTag.addEventListener("click", function(evt) {
792                         var htmlPortAnchor = evt.target;
793                         var requestData = {};
794                         requestData["gatewayName"] = evt.target.gatewayName;
795                         requestData["nodePort"] = decodeURIComponent(evt.target.id);
796                         // make ajax call to delete port
797                         var url = one.f.switchmanager.rootUrl + "/subnetGateway/ports/delete";
798                         one.f.switchmanager.subnetGatewayConfig.ajax.main(url, requestData, function(response) {
799                             if(response.status == true) {
800                                 // refresh dashlet by passing dashlet div as param
801                                 one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
802                             } else {
803                                 alert(response.message);
804                             }
805                         });
806                         
807                     });
808                     aTag.addEventListener("mouseover", function(evt) {
809                         evt.target.style.cursor = "pointer";
810                     }, false);
811                     aTag.innerHTML = "Delete";
812                     $nodePortsContainer.append(aTag);
813                     $nodePortsContainer.append("<br/>");
814                 }
815
816                 // store gateways in the registry so that they can be used in the add ports popup
817                 one.f.switchmanager.subnetGatewayConfig.registry.gateways.push(value["name"]);
818                 var entry = [];
819                 var checkbox = document.createElement("input");
820                 checkbox.setAttribute("type", "checkbox");
821                 checkbox.setAttribute("id", value["name"]);
822                 entry.push(checkbox);
823                 entry.push(value["name"]);
824                 entry.push(value["subnet"]);
825                 entry.push($nodePortsContainer);
826                 tr.entry = entry;
827                 result.push(tr);
828             });
829             return result;
830         }
831     },
832     actions: {
833         deleteNodePort: function(htmlPortAnchor) {
834             var requestData = {};
835             requestData["gatewayName"] = htmlPortAnchor.getAttribute("gatewayName");
836             requestData["nodePort"] = decodeURIComponent(htmlPortAnchor.id);
837             // make ajax call to delete port
838             var url = one.f.switchmanager.rootUrl + "/subnetGateway/ports/delete";
839             one.f.switchmanager.subnetGatewayConfig.ajax.main(url, requestData, function(response) {
840                 if(response.status == true) {
841                     // refresh dashlet by passing dashlet div as param
842                     one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
843                 } else {
844                     alert(response.message);
845                 }
846             });
847         }
848     }
849 }
850
851 one.f.switchmanager.staticRouteConfig = {
852     id: {
853         dashlet: {
854             add: "one_f_switchmanager_staticRouteConfig_id_dashlet_add",
855             remove: "one_f_switchmanager_staticRouteConfig_id_dashlet_remove",
856             datagrid: "one_f_switchmanager_staticRouteConfig_id_dashlet_datagrid",
857             selectAll: "one_f_switchmanager_staticRouteConfig_id_dashlet_selectAll"
858         }, 
859         modal: {
860             modal: "one_f_switchmanager_staticRouteConfig_id_modal_modal",
861             save: "one_f_switchmanager_staticRouteConfig_id_modal_save",
862             form: {
863                 routeName : "one_f_switchmanager_staticRouteConfig_id_modal_form_routename",
864                 staticRoute : "one_f_switchmanager_staticRouteConfig_id_modal_form_staticroute",
865                 nextHop : "one_f_switchmanager_staticRouteConfig_id_modal_form_nexthop",
866             }
867         }
868     },
869     dashlet: function($dashlet) {
870         one.lib.dashlet.empty($dashlet);
871         var url = one.f.switchmanager.rootUrl + "/staticRoutes";
872         one.f.switchmanager.staticRouteConfig.ajax.main(url, {}, function(content) {
873
874             if (content.privilege === 'WRITE') {
875                 // Add static route button
876                 var button = one.lib.dashlet.button.single("Add Static Route", one.f.switchmanager.staticRouteConfig.id.dashlet.add, "btn-primary", "btn-mini");
877                 var $button = one.lib.dashlet.button.button(button);
878                 $button.click(function() {
879                     var $modal = one.f.switchmanager.staticRouteConfig.modal.initialize();
880                     $modal.modal();
881                 });
882                 $dashlet.append(one.lib.dashlet.header(one.f.dashlet.staticRouteConfig.name));
883                 $dashlet.append($button);
884
885                 // Delete static route button
886                 var button = one.lib.dashlet.button.single("Delete Static Route(s)", one.f.switchmanager.staticRouteConfig.id.dashlet.remove, "btn-primary", "btn-mini");
887                 var $button = one.lib.dashlet.button.button(button);
888                 $button.click(function() {
889                     var requestData = {};
890                     var routesToDelete = [];
891                     //var checkedCheckBoxes = $("input:checked", $(this).closest(".dashlet").find("table"));
892                     var checkedCheckBoxes = $("#" + one.f.switchmanager.staticRouteConfig.id.dashlet.datagrid).find("tbody input:checked");
893                     checkedCheckBoxes.each(function(index, value) {
894                         routesToDelete.push(checkedCheckBoxes[index].id);
895                     });
896                     if (routesToDelete.length > 0) {
897                         requestData["routesToDelete"] = routesToDelete.toString();
898                         var url = one.f.switchmanager.rootUrl + "/staticRoute/delete";
899                         one.f.switchmanager.staticRouteConfig.ajax.main(url, requestData, function(response) {
900                             if (response.status == true) {
901                                 // refresh dashlet by passing dashlet div as param 
902                                 one.lib.alert("Static Routes(s) successfully removed");
903                             } else {
904                                 one.lib.alert(response.message);
905                             }
906                             one.f.switchmanager.staticRouteConfig.dashlet($("#left-bottom .dashlet"));
907                         });
908                     }
909                 });
910                 $dashlet.append($button);
911             }
912             var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.staticRouteConfig.id.dashlet.datagrid, {
913                 searchable: true,
914                 filterable: false,
915                 pagination: true,
916                 flexibleRowsPerPage: true
917                 }, "table-striped table-condensed");
918             $dashlet.append($gridHTML);
919             var dataSource = one.f.switchmanager.staticRouteConfig.data.staticRouteConfigGrid(content);
920             $("#" + one.f.switchmanager.staticRouteConfig.id.dashlet.datagrid).datagrid({dataSource: dataSource})
921             .on("loaded", function() {
922                 $("#"+one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll).click(function() {
923                     $("#" + one.f.switchmanager.staticRouteConfig.id.dashlet.datagrid).find(':checkbox').prop('checked',
924                         $("#"+one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll).is(':checked'));
925                 });
926                 $(".staticRoute").click(function(){
927                     if (!$('.staticRoute[type=checkbox]:not(:checked)').length) {
928                         $("#"+one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll)
929                             .prop("checked",
930                           true);
931                     } else {
932                         $("#"+one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll)
933                             .prop("checked",
934                          false);
935                     }
936                     event.stopPropagation();
937                 });
938              });
939         });
940     },
941     // device ajax calls
942     ajax : {
943         main : function(url, requestData, callback) {
944             $.getJSON(url, requestData, function(data) {
945                 callback(data);
946             });
947         }
948     },
949     registry: {},
950     modal : {
951         initialize: function() {
952             var h3 = "Add Static Route";
953             var footer = one.f.switchmanager.staticRouteConfig.modal.footer();
954             var $modal = one.lib.modal.spawn(one.f.switchmanager.staticRouteConfig.id.modal.modal, h3, "", footer);
955             // bind save button
956             $('#' + one.f.switchmanager.staticRouteConfig.id.modal.save, $modal).click(function() {
957                 one.f.switchmanager.staticRouteConfig.modal.save($modal);
958             });
959             var $body = one.f.switchmanager.staticRouteConfig.modal.body();
960             one.lib.modal.inject.body($modal, $body);
961             return $modal;
962         },
963         save: function($modal) {
964             var result = {};
965             result['routeName'] = $('#' + one.f.switchmanager.staticRouteConfig.id.modal.form.routeName, $modal).val();
966             result['staticRoute'] = $('#' + one.f.switchmanager.staticRouteConfig.id.modal.form.staticRoute, $modal).val();
967             result['nextHop'] = $('#' + one.f.switchmanager.staticRouteConfig.id.modal.form.nextHop, $modal).val();
968             one.f.switchmanager.staticRouteConfig.modal.ajax.staticRouteConfig(result, function(response) {
969                     if(response.status == true) {
970                         $modal.modal('hide');
971                         // refresh dashlet by passing dashlet div as param
972                         one.f.switchmanager.staticRouteConfig.dashlet($("#left-bottom .dashlet"));
973                     } else {
974                         // TODO: Show error message in a error message label instead.
975                         alert(response.message);
976                     }
977                 });
978         },
979         body: function() {
980             var $form = $(document.createElement('form'));
981             var $fieldset = $(document.createElement('fieldset'));
982             // static route name
983             var $label = one.lib.form.label("Name");
984             var $input = one.lib.form.input("Name");
985             $input.attr('id', one.f.switchmanager.staticRouteConfig.id.modal.form.routeName);
986             $fieldset.append($label).append($input);
987             // static route IP Mask 
988             var $label = one.lib.form.label("Static Route");
989             var $input = one.lib.form.input("Static Route");
990             $input.attr('id', one.f.switchmanager.staticRouteConfig.id.modal.form.staticRoute);
991             $fieldset.append($label).append($input);
992             // static route IP Mask 
993             var $label = one.lib.form.label("Next Hop");
994             var $input = one.lib.form.input("Next Hop");
995             $input.attr('id', one.f.switchmanager.staticRouteConfig.id.modal.form.nextHop);
996             $fieldset.append($label).append($input);
997             // return
998             $form.append($fieldset);
999             return $form;
1000         },
1001         ajax: {
1002             staticRouteConfig: function(requestData, callback) {
1003                 $.getJSON(one.f.switchmanager.rootUrl + "/staticRoute/add", requestData, function(data) {
1004                     callback(data);
1005                 });
1006             }
1007         },
1008         data : {
1009             
1010         },
1011         footer : function() {
1012             var footer = [];
1013             var saveButton = one.lib.dashlet.button.single("Save", one.f.switchmanager.staticRouteConfig.id.modal.save, "btn-success", "");
1014             var $saveButton = one.lib.dashlet.button.button(saveButton);
1015             footer.push($saveButton);
1016             return footer;
1017         }
1018     },
1019     // data functions
1020     data : {
1021         staticRouteConfigGrid: function(data) {
1022             var source = new StaticDataSource({
1023                     columns: [
1024                         {
1025                             property: 'selector',
1026                             label: "<input type='checkbox'  id='"
1027                                 +one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll+"'/>",
1028                             sortable: false
1029                         },
1030                         {
1031                             property: 'name',
1032                             label: 'Name',
1033                             sortable: true
1034                         },
1035                         {
1036                             property: 'staticRoute',
1037                             label: 'Static Route',
1038                             sortable: true
1039                         },
1040                         {
1041                             property: 'nextHop',
1042                             label: 'Next Hop Address',
1043                             sortable: true
1044                         }
1045                     ],
1046                     data: data.nodeData,
1047                     formatter: function(items) {
1048                         $.each(items, function(index, item) {
1049                             item["selector"] = '<input type="checkbox" class="staticRoute" id=' + item["name"] + '></input>';
1050                         });
1051
1052                     },
1053                     delay: 0
1054                 });
1055             return source;              
1056         },
1057         staticRouteConfig : function(data) {
1058             var result = [];
1059             $.each(data.nodeData, function(key, value) {
1060                 var tr = {};
1061                 // fill up all the td's
1062                 var entry = [];
1063                 var checkbox = document.createElement("input");
1064                 checkbox.setAttribute("type", "checkbox");
1065                 checkbox.setAttribute("id", value["name"]);
1066                 entry.push(checkbox);
1067                 entry.push(value["name"]);
1068                 entry.push(value["staticRoute"]);
1069                 entry.push(value["nextHop"]);
1070                 tr.entry = entry;
1071                 result.push(tr);
1072             });
1073             return result;
1074         }
1075     }
1076 }
1077
1078 one.f.switchmanager.spanPortConfig = {
1079     id: {
1080         dashlet: {
1081             add: "one_f_switchmanager_spanPortConfig_id_dashlet_add",
1082             remove: "one_f_switchmanager_spanPortConfig_id_dashlet_remove",
1083             datagrid: "one_f_switchmanager_spanPortConfig_id_dashlet_datagrid",
1084             selectAllFlows: "one_f_switchmanager_spanPortConfig_id_dashlet_selectAllFlows"
1085         }, 
1086         modal: {
1087             modal: "one_f_switchmanager_spanPortConfig_id_modal_modal",
1088             save: "one_f_switchmanager_spanPortConfig_id_modal_save",
1089             form: {
1090                 name : "one_f_switchmanager_spanPortConfig_id_modal_form_name",
1091                 nodes : "one_f_switchmanager_spanPortConfig_id_modal_form_nodes",
1092                 port : "one_f_switchmanager_spanPortConfig_id_modal_form_port",
1093             }
1094         }
1095     },
1096     dashlet: function($dashlet) {
1097         one.lib.dashlet.empty($dashlet);
1098         
1099         //populate table in dashlet
1100         var url = one.f.switchmanager.rootUrl + "/spanPorts";
1101         one.f.switchmanager.spanPortConfig.ajax.main(url, {}, function(content) {
1102
1103             if (content.privilege === 'WRITE') {
1104
1105                 // Add span port button
1106                 var button = one.lib.dashlet.button.single("Add SPAN Port", one.f.switchmanager.spanPortConfig.id.dashlet.add, "btn-primary", "btn-mini");
1107                 var $button = one.lib.dashlet.button.button(button);
1108
1109                 $button.click(function() {
1110                     var $modal = one.f.switchmanager.spanPortConfig.modal.initialize();
1111                     $modal.modal();
1112                 });
1113                 $dashlet.append(one.lib.dashlet.header(one.f.dashlet.spanPortConfig.name));
1114                 $dashlet.append($button);
1115
1116                 // Delete span port button
1117                 var button = one.lib.dashlet.button.single("Delete SPAN Port(s)", one.f.switchmanager.spanPortConfig.id.dashlet.remove, "btn-primary", "btn-mini");
1118                 var $button = one.lib.dashlet.button.button(button);
1119                 $button.click(function() {
1120
1121                     var checkedCheckBoxes = $("#" + one.f.switchmanager.spanPortConfig.id.dashlet.datagrid).find("tbody input:checked");
1122                     if (checkedCheckBoxes.length > 0) {
1123                         var spanPortsToDelete = "";
1124                         checkedCheckBoxes.each(function(index, value) {
1125                             spanPortsToDelete += decodeURIComponent(checkedCheckBoxes[index].getAttribute("spanPort")) + "###";
1126                         });
1127
1128                         var requestData = {};
1129                         requestData["spanPortsToDelete"] = spanPortsToDelete;
1130                         var url = one.f.switchmanager.rootUrl + "/spanPorts/delete";
1131                         one.f.switchmanager.spanPortConfig.ajax.main(url, requestData, function(response) {
1132                             if (response.status == true) {
1133                                 // refresh dashlet by passing dashlet div as param
1134                                 one.lib.alert("Span Port(s) successfully removed");
1135                             } else {
1136                                 one.lib.alert(response.message);
1137                             }
1138                             one.f.switchmanager.spanPortConfig.dashlet($("#right-bottom .dashlet"));
1139                         });
1140                     }
1141                 });
1142                 $dashlet.append($button);
1143             }
1144             var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.spanPortConfig.id.dashlet.datagrid, {
1145                 searchable: true,
1146                 filterable: false,
1147                 pagination: true,
1148                 flexibleRowsPerPage: true
1149                 }, "table-striped table-condensed");
1150             $dashlet.append($gridHTML);
1151             var dataSource = one.f.switchmanager.spanPortConfig.data.spanPortConfigGrid(content);
1152             $("#" + one.f.switchmanager.spanPortConfig.id.dashlet.datagrid).datagrid({dataSource: dataSource})
1153             .on("loaded", function() {
1154                 $("#"+one.f.switchmanager.spanPortConfig.id.dashlet.selectAll).click(function() {
1155                     $("#" + one.f.switchmanager.spanPortConfig.id.dashlet.datagrid).find(':checkbox').prop('checked',
1156                         $("#"+one.f.switchmanager.spanPortConfig.id.dashlet.selectAll).is(':checked'));
1157                 });
1158                 $(".spanPortConfig").click(function(){
1159                     if (!$('.spanPortConfig[type=checkbox]:not(:checked)').length) {
1160                         $("#"+one.f.switchmanager.spanPortConfig.id.dashlet.selectAll)
1161                             .prop("checked",
1162                           true);
1163                     } else {
1164                         $("#"+one.f.switchmanager.spanPortConfig.id.dashlet.selectAll)
1165                             .prop("checked",
1166                          false);
1167                     }
1168                     event.stopPropagation();
1169                 });
1170              });
1171         });
1172     },
1173     // device ajax calls
1174     ajax : {
1175         main : function(url, requestData, callback) {
1176             $.getJSON(url, requestData, function(data) {
1177                 callback(data);
1178             });
1179         }
1180     },
1181     registry: {},
1182     modal : {
1183         initialize: function() {
1184             var h3 = "Add SPAN Port";
1185             var footer = one.f.switchmanager.spanPortConfig.modal.footer();
1186             var $modal = one.lib.modal.spawn(one.f.switchmanager.spanPortConfig.id.modal.modal, h3, "", footer);
1187             // bind save button
1188             $('#' + one.f.switchmanager.spanPortConfig.id.modal.save, $modal).click(function() {
1189                 one.f.switchmanager.spanPortConfig.modal.save($modal);
1190             });
1191
1192             one.f.switchmanager.spanPortConfig.modal.ajax.nodes(function(nodes, nodeports) {
1193                 var $body = one.f.switchmanager.spanPortConfig.modal.body(nodes, nodeports);
1194                 one.lib.modal.inject.body($modal, $body);
1195             });
1196             return $modal;
1197         },
1198         save: function($modal) {
1199             var result = {};
1200             result['nodeId'] = $('#' + one.f.switchmanager.spanPortConfig.id.modal.form.nodes, $modal).val();
1201             result['spanPort'] = $('#' + one.f.switchmanager.spanPortConfig.id.modal.form.port, $modal).val();
1202             one.f.switchmanager.spanPortConfig.modal.ajax.saveSpanPortConfig(result, 
1203                 function(response) {
1204                     if(response.status == true) {
1205                         $modal.modal('hide');
1206                         one.f.switchmanager.spanPortConfig.dashlet($("#right-bottom .dashlet"));
1207                     } else {
1208                         alert(response.message);
1209                     }
1210                     
1211                 });
1212         },
1213         body: function(nodes, nodeports) {
1214             var $form = $(document.createElement('form'));
1215             var $fieldset = $(document.createElement('fieldset'));
1216             // node
1217             var $label = one.lib.form.label("Node");
1218             var $select = one.lib.form.select.create(nodes);
1219             one.lib.form.select.prepend($select, { '' : 'Please Select a Node' });
1220             $select.attr('id', one.f.switchmanager.spanPortConfig.id.modal.form.nodes);
1221             
1222             // bind onchange
1223             $select.change(function() {
1224                 // retrieve port value
1225                 var nodeId = $(this).find('option:selected').attr('value');
1226                 one.f.switchmanager.spanPortConfig.registry['currentNode'] = nodeId;
1227                 var $ports = $('#' + one.f.switchmanager.spanPortConfig.id.modal.form.port);
1228                 var ports = one.f.switchmanager.spanPortConfig.registry['nodePorts'][nodeId]
1229                 one.lib.form.select.inject($ports, ports); 
1230             });
1231
1232             $fieldset.append($label).append($select);
1233             // input port
1234             var $label = one.lib.form.label("Input Port");
1235             var $select = one.lib.form.select.create();
1236             $select.attr('id', one.f.switchmanager.spanPortConfig.id.modal.form.port);
1237             $fieldset.append($label).append($select);
1238             
1239             // return
1240             $form.append($fieldset);
1241             return $form;
1242         },
1243         ajax: {
1244             nodes: function(callback) {
1245                 $.getJSON(one.f.switchmanager.rootUrl + "/nodeports", function(data) {
1246                     var nodes = {};
1247                     var nodePorts = {};
1248                     $(data).each(function(index, node) {
1249                         nodes[node.nodeId] = node.nodeName;
1250                         nodePorts[node.nodeId] = node.nodePorts;
1251                     });
1252                     one.f.switchmanager.spanPortConfig.registry['nodePorts'] = nodePorts;
1253                     callback(nodes, nodePorts);
1254                 });
1255             },
1256             saveSpanPortConfig: function(requestData, callback) {
1257                 var resource = {};
1258                 resource["jsonData"] = JSON.stringify(requestData);
1259                 $.getJSON(one.f.switchmanager.rootUrl + "/spanPorts/add", resource, function(data) {
1260                     callback(data);
1261                 });
1262             }
1263         },
1264         footer : function() {
1265             var footer = [];
1266             var saveButton = one.lib.dashlet.button.single("Save", one.f.switchmanager.spanPortConfig.id.modal.save, "btn-success", "");
1267             var $saveButton = one.lib.dashlet.button.button(saveButton);
1268             footer.push($saveButton);
1269             return footer;
1270         }
1271     },
1272     // data functions
1273     data : {
1274         spanPortConfigGrid: function(data) {
1275             var source = new StaticDataSource({
1276                     columns: [
1277                         {
1278                             property: 'selector',
1279                             label: "<input type='checkbox'  id='"
1280                                 +one.f.switchmanager.spanPortConfig.id.dashlet.selectAll+"'/>",
1281                             sortable: false
1282                         },
1283                         {
1284                             property: 'nodeName',
1285                             label: 'Node',
1286                             sortable: true
1287                         },
1288                         {
1289                             property: 'spanPort',
1290                             label: 'SPAN Port',
1291                             sortable: true
1292                         },
1293                     ],
1294                     data: data.nodeData,
1295                     formatter: function(items) {
1296                         $.each(items, function(index, item) {
1297                             item["selector"] = '<input type="checkbox" class="spanPortConfig" spanPort=' + encodeURIComponent(item["json"]) + '></input>';
1298                         });
1299                     },
1300                     delay: 0
1301                 });
1302             return source;              
1303         },
1304         devices : function(data) {
1305             var result = [];
1306             $.each(data.nodeData, function(key, value) {
1307                 var tr = {};
1308                 // fill up all the td's
1309                 var entry = [];
1310                 var checkbox = document.createElement("input");
1311                 checkbox.setAttribute("type", "checkbox");
1312                 checkbox.spanPort = value.json;
1313                 entry.push(checkbox);
1314                 entry.push(value["nodeName"]);
1315                 entry.push(value["spanPort"]);
1316                 tr.entry = entry;
1317                 result.push(tr);
1318             });
1319             return result;
1320         }
1321     }
1322 }
1323
1324 /** INIT **/
1325 // populate nav tabs
1326 $(one.f.menu.left.top).each(function(index, value) {
1327     var $nav = $(".nav", "#left-top");
1328     one.main.page.dashlet($nav, value);
1329 });
1330
1331 $(one.f.menu.left.bottom).each(function(index, value) {
1332     var $nav = $(".nav", "#left-bottom");
1333     one.main.page.dashlet($nav, value);
1334 });
1335
1336 $(one.f.menu.right.bottom).each(function(index, value) {
1337     var $nav = $(".nav", "#right-bottom");
1338     one.main.page.dashlet($nav, value);
1339 });
1340
1341 one.f.addPopOut = function() {
1342     $img1 = $(document.createElement("img"));
1343     $img1.attr("src", "/img/Expand16T.png");
1344     $img1.attr("style", "float: right;");
1345     $img1.hover(function() {
1346         $img1.css("cursor", "pointer");
1347     });
1348     $img1.click(function() {
1349         var $modal = one.f.switchmanager.nodesLearnt.modal.initialize.popout();
1350         $modal.css({
1351             'margin-left': '-45%',
1352             'margin-top': '-3%',
1353             'width':$(document).width() * 0.8,
1354             'height':$(document).height() * 0.9
1355         });
1356         $(".modal-body", $modal).css({
1357             "max-height": $(document).height() * 0.75,
1358         });
1359         $modal.modal();
1360     });
1361     $dash1 = $($("#left-top .nav")[0]);
1362     $dash1.append($img1);
1363 };
1364 one.f.addPopOut();
1365
1366 // bind dashlet nav
1367 $('.dash .nav a', '#main').click(function() {
1368     // de/activation
1369     var $li = $(this).parent();
1370     var $ul = $li.parent();
1371     one.lib.nav.unfocus($ul);
1372     $li.addClass('active');
1373     // clear respective dashlet
1374     var $dashlet = $ul.parent().find('.dashlet');
1375     one.lib.dashlet.empty($dashlet);
1376
1377     // callback based on menu
1378     var id = $(this).attr('id');
1379     var menu = one.f.dashlet;
1380     switch (id) {
1381         case menu.nodesLearnt.id:
1382             one.f.switchmanager.nodesLearnt.dashlet($dashlet);
1383             break;
1384         case menu.staticRouteConfig.id:
1385             one.f.switchmanager.staticRouteConfig.dashlet($dashlet);
1386             break;
1387         case menu.subnetGatewayConfig.id:
1388             one.f.switchmanager.subnetGatewayConfig.dashlet($dashlet);
1389             break;
1390         case menu.spanPortConfig.id:
1391             one.f.switchmanager.spanPortConfig.dashlet($dashlet);
1392             break;
1393     };
1394 });
1395
1396 // activate first tab on each dashlet
1397 $('.dash .nav').each(function(index, value) {
1398     $($(value).find('li')[0]).find('a').click();
1399 });