Merge "Introduce ASYNC caches and use them in FRM"
[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 Learned'
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 Learned";
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-primary", "");
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                         var portsMatch = ports.match(/<\/span>/g);
325                         var portsLength = 0;
326                         if (portsMatch != null) {
327                             portsLength = portsMatch.length;
328                         }
329                         item.ports = '<span class="nodePorts" style="cursor:pointer;color: #08c" ports='+encodeURIComponent(JSON.stringify(item.ports)) + ' nodeId="' + item.nodeId
330                             + '" nodeName="' + nodeName
331                             + '">' + portsLength +'</span>';
332                     }); 
333                     },
334                     delay: 0
335                 });
336                 return source;
337
338             },
339             popout: function(data) {
340                 var source = new StaticDataSource({
341                     columns: [
342                         {
343                             property: 'nodeName',
344                             label: 'Node Name',
345                             sortable: true
346                         },
347                         {
348                             property: 'nodeId',
349                             label: 'Node ID',
350                             sortable: true
351                         },
352                         {
353                             property: 'tierName',
354                             label: 'Tier Name',
355                             sortable: true
356                         },
357                         {
358                             property: 'mac',
359                             label: 'MAC Address',
360                             sortable: true
361                         },
362                         {
363                             property: 'ports',
364                             label: 'Ports',
365                             sortable: true
366                         }
367                     ],
368                     data: data.nodeData,
369                     formatter: function(items) {
370                         $.each(items, function (index, item) {
371                             var ports = item.ports;
372                             var portsMatch = ports.match(/<\/span>/g);
373                             var portsLength = 0;
374                             if (portsMatch != null) {
375                                 portsLength = portsMatch.length;
376                             }
377                             item.ports = '<span class="nodePorts" style="cursor: pointer;color: #08c" ports='+encodeURIComponent(JSON.stringify(item.ports)) + ' nodeId="' + item.nodeId
378                                 + '" nodeName="' + item.nodeName
379                                 + '">' + portsLength +'</span>';
380                         }); 
381                     },
382                     delay: 0
383                 });
384                 return source;
385             },
386             displayPorts: function(content){
387                 var data=[];
388                 var start=0;;
389                 var finish=content.indexOf("<br>",start);
390                 while(finish != -1){
391                     data.push({"ports":content.substring(start,finish)});
392                     start=finish+4
393                     finish=content.indexOf("<br>",start);
394                 }
395                 var source = new StaticDataSource({
396                     columns: [
397                         {
398                             property: 'ports',
399                             label: 'Ports',
400                             sortable: true
401                         }
402                     ],
403                     data:data,
404                     delay: 0
405                 });
406                 
407                 return source;
408             }
409         },
410         abridged : function(data) {
411             var result = [];
412             $.each(data.nodeData, function(key, value) {
413                 var tr = {};
414                 var entry = [];
415                 var nodeNameEntry = value["nodeName"] ? value["nodeName"] : "Click to update";
416
417                 // TODO: Move anchor tag creation to one.lib.form.
418                 var aTag;
419                 aTag = document.createElement("a");
420                 aTag.privilege = data.privilege;
421                 aTag.addEventListener("click", one.f.switchmanager.nodesLearnt.modal.initialize.updateNode);
422                 aTag.addEventListener("mouseover", function(evt) {
423                     evt.target.style.cursor = "pointer";
424                 }, false);
425                 aTag.setAttribute("id", encodeURIComponent(value["nodeId"]));
426                 aTag.switchDetails = value;
427                 aTag.innerHTML = nodeNameEntry;
428                 entry.push(aTag);
429                 entry.push(value["nodeId"]);
430                 entry.push(value["ports"]);
431                 tr.entry = entry;
432                 result.push(tr);
433             });
434             return result;
435         },
436         popout : function(data) {
437             var result = [];
438             $.each(data.nodeData, function(key, value) {
439                 var tr = {};
440                 // fill up all the td's
441                 var entry = [];
442                 var nodenameentry = value["nodeName"] ? value["nodeName"] : "No name provided";
443                 entry.push(nodenameentry);
444                 entry.push(value["nodeId"]);
445                 entry.push(value["tierName"]);
446                 entry.push(value["mac"]);
447                 entry.push(value["ports"]);
448                 tr.entry = entry;
449                 result.push(tr);
450             });
451             return result;
452         }
453     }
454 };
455
456 one.f.switchmanager.subnetGatewayConfig = {
457     id: {
458         dashlet: {
459             addIPAddress: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_addIP",
460             addPorts: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_addPorts",
461             removeIPAddress: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_removeIP",
462             datagrid: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_datagrid",
463             selectAll: "one_f_switchmanager_subnetGatewayConfig_id_dashlet_selectAll"
464         }, 
465         modal: {
466             modal: "one_f_switchmanager_subnetGatewayConfig_id_modal_modal",
467             ports : "one_f_switchmanager_subnetGatewayConfig_id_modal_ports",
468             save: "one_f_switchmanager_subnetGatewayConfig_id_modal_save",
469             remove: "one_f_switchmanager_subnetGatewayConfig_id_modal_remove",
470             cancel: "one_f_switchmanager_subnetGatewayConfig_id_modal_cancel",
471             form: {
472                 name : "one_f_switchmanager_subnetGatewayConfig_id_modal_form_gatewayname",
473                 gatewayIPAddress : "one_f_switchmanager_subnetGatewayConfig_id_modal_form_gatewayipaddress",
474                 nodeId: "one_f_switchmanager_subnetGatewayConfig_id_modal_form_nodeid",
475                 ports: "one_f_switchmanager_subnetGatewayConfig_id_modal_form_ports"
476             }
477         }
478     },
479     // device ajax calls
480     dashlet: function($dashlet) {
481         one.lib.dashlet.empty($dashlet);
482         $dashlet.append(one.lib.dashlet.header(one.f.dashlet.subnetGatewayConfig.name));
483         // Add gateway IP Address button
484         var url = one.f.switchmanager.rootUrl + "/subnets";
485         one.f.switchmanager.subnetGatewayConfig.ajax.main(url, {}, function(content) {
486
487             if (content.privilege === 'WRITE') {
488                 var button = one.lib.dashlet.button.single("Add Gateway IP Address",
489                     one.f.switchmanager.subnetGatewayConfig.id.dashlet.addIPAddress, "btn-primary", "btn-mini");
490                 var $button = one.lib.dashlet.button.button(button);
491                 $button.click(function() {
492                     var $modal = one.f.switchmanager.subnetGatewayConfig.modal.initialize.gateway();
493                     $modal.modal();
494                 });
495                 $dashlet.append($button);
496
497                 // Delete gateway ip address button
498                 var button = one.lib.dashlet.button.single("Remove Gateway IP Address",
499                 one.f.switchmanager.subnetGatewayConfig.id.dashlet.removeIPAddress, "btn-danger", "btn-mini");
500                 var $button = one.lib.dashlet.button.button(button);
501                 $button.click(function() {
502                     var gatewaysToDelete = [];
503                     var checkedCheckBoxes = $("#" + one.f.switchmanager.subnetGatewayConfig.id.dashlet.datagrid).find("tbody input:checked")
504                     checkedCheckBoxes.each(function(index, value) {
505                         gatewaysToDelete.push(checkedCheckBoxes[index].id);
506                     });
507                     if (checkedCheckBoxes.size() === 0) {
508                         return false;
509                     }
510                     one.f.switchmanager.subnetGatewayConfig.modal.removeMultiple.dialog(gatewaysToDelete)
511                 });
512                 $dashlet.append($button);
513
514                 // Add Ports button
515                 var button = one.lib.dashlet.button.single("Add Ports",
516                     one.f.switchmanager.subnetGatewayConfig.id.dashlet.addPorts, "btn-primary", "btn-mini");
517                 var $button = one.lib.dashlet.button.button(button);
518                 $button.click(function() {
519                     if (one.f.switchmanager.subnetGatewayConfig.registry.gateways.length === 0) {
520                       alert('No Gateways Exist');
521                       return false;
522                     }
523                     var $modal = one.f.switchmanager.subnetGatewayConfig.modal.initialize.ports();
524                     $modal.modal();
525                 });
526                 $dashlet.append($button);
527             }
528             var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.subnetGatewayConfig.id.dashlet.datagrid, {
529                 searchable: true,
530                 filterable: false,
531                 pagination: true,
532                 flexibleRowsPerPage: true
533                 }, "table-striped table-condensed");
534             $dashlet.append($gridHTML);
535             var dataSource = one.f.switchmanager.subnetGatewayConfig.data.devicesgrid(content);
536             $("#" + one.f.switchmanager.subnetGatewayConfig.id.dashlet.datagrid).datagrid({dataSource: dataSource})
537             .on("loaded", function() {
538                 $("#"+one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll).click(function() {
539                     $("#" + one.f.switchmanager.subnetGatewayConfig.id.dashlet.datagrid).find(':checkbox').prop('checked',
540                         $("#"+one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll).is(':checked'));
541                 });
542                 $(".subnetGatewayConfig").click(function(e){
543                     if (!$('.subnetGatewayConfig[type=checkbox]:not(:checked)').length) {
544                         $("#"+one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll)
545                             .prop("checked",
546                           true);
547                     } else {
548                         $("#"+one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll)
549                             .prop("checked",
550                          false);
551                     }
552                     e.stopPropagation();
553                 });
554              });
555         });
556     },
557     ajax : {
558         main : function(url, requestData, callback) {
559             $.getJSON(url, requestData, function(data) {
560                 callback(data);
561             });
562         }
563     },
564     registry: {},
565     modal : {
566         initialize: {
567             gateway: function() {
568                 var h3 = "Add Gateway IP Address";
569                 var footer = one.f.switchmanager.subnetGatewayConfig.modal.footer();
570                 var $modal = one.lib.modal.spawn(one.f.switchmanager.subnetGatewayConfig.id.modal.modal, h3, "", footer);
571                 // bind save button
572                 $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.save, $modal).click(function() {
573                     one.f.switchmanager.subnetGatewayConfig.modal.save.gateway($modal);
574                 });
575                 var $body = one.f.switchmanager.subnetGatewayConfig.modal.body.gateway();
576                 one.lib.modal.inject.body($modal, $body);
577                 return $modal;
578             },
579             ports: function() {
580                 var h3 = "Add Ports";
581                 var footer = one.f.switchmanager.subnetGatewayConfig.modal.footer();
582                 var $modal = one.lib.modal.spawn(one.f.switchmanager.subnetGatewayConfig.id.modal.ports, h3, "", footer);
583                 // bind save button
584                 $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.save, $modal).click(function() {
585                     one.f.switchmanager.subnetGatewayConfig.modal.save.ports($modal);
586                 });
587                 
588                 // TODO: Change to subnetGateway instead.
589                 one.f.switchmanager.spanPortConfig.modal.ajax.nodes(function(nodes, nodeports) {
590                     var $body = one.f.switchmanager.subnetGatewayConfig.modal.body.ports(nodes, nodeports);
591                     one.lib.modal.inject.body($modal, $body);
592                 });
593                 return $modal;
594             }
595         },
596         save: {
597             gateway: function($modal) {
598                 var result = {};
599                 result['gatewayName'] = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.name, $modal).val();
600                 if(!one.f.switchmanager.validateName(result['gatewayName'])) {
601                     alert("Gateway name can contain upto 255 characters");
602                     return;
603                 }
604                 result['gatewayIPAddress'] = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.gatewayIPAddress, $modal).val();
605                 one.f.switchmanager.subnetGatewayConfig.modal.ajax.gateway(result, 
606                     function(response) {
607                         if(response.status == true) {
608                             $modal.modal('hide');
609                             one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
610                         } else {
611                             alert(response.message);
612                         }
613                     });
614             },
615             ports: function($modal) {
616                 var result = {};
617                 var gatewayRegistryIndex = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.name, $modal).val();
618                 result['portsName'] = one.f.switchmanager.subnetGatewayConfig.registry.gateways[gatewayRegistryIndex];
619                 result['nodeId'] = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.nodeId, $modal).val();
620                 result['ports'] = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.ports, $modal).val();
621                 if(!result['portsName'] || result['portsName'] == "") {
622                     alert("No gateway chosen. Cannot add port");
623                     return;
624                 }
625                 if(!result['nodeId'] || result['nodeId'] == "") {
626                     alert("Please select a node.");
627                     return;
628                 }
629                 if(!result['ports'] || result['ports'] == "") {
630                     alert("Please choose a port.");
631                     return;
632                 }
633                 one.f.switchmanager.subnetGatewayConfig.modal.ajax.ports(result, 
634                     function(response) {
635                         if(response.status == true) {
636                             $modal.modal('hide');
637                             one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
638                         } else {
639                             alert(response.message);
640                         }
641                     });
642             }
643         },
644         body: {
645             gateway: function() {
646                 var $form = $(document.createElement('form'));
647                 var $fieldset = $(document.createElement('fieldset'));
648                 // gateway name
649                 var $label = one.lib.form.label("Name");
650                 var $input = one.lib.form.input("Name");
651                 $input.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.name);
652                 $fieldset.append($label).append($input);
653                 // gateway IP Mask 
654                 var $label = one.lib.form.label("Gateway IP Address/Mask");
655                 var $input = one.lib.form.input("Gateway IP Address/Mask");
656                 var $help = one.lib.form.help('Example: 192.168.10.254/16');
657                 $input.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.gatewayIPAddress);
658                 $fieldset.append($label).append($input).append($help);
659                 
660                 $form.append($fieldset);
661                 return $form;
662             },
663             ports: function(nodes, nodeports) {
664                 var $form = $(document.createElement('form'));
665                 var $fieldset = $(document.createElement('fieldset'));
666                 // gateways drop down
667                 var $label = one.lib.form.label("Gateway Name");
668                 var $select = one.lib.form.select.create(one.f.switchmanager.subnetGatewayConfig.registry.gateways);
669                 $select.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.name);
670                 one.lib.form.select.prepend($select, { '' : 'Please Select a Gateway' });
671                 $select.val($select.find("option:first").val());
672                 $fieldset.append($label).append($select);
673
674                 // node ID
675                 var $label = one.lib.form.label("Node ID");
676                 var $select = one.lib.form.select.create(nodes);
677                 $select.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.nodeId);
678                 one.lib.form.select.prepend($select, { '' : 'Please Select a Node' });
679                 $select.val($select.find("option:first").val());
680                 $fieldset.append($label).append($select);
681
682                 // bind onchange
683                 $select.change(function() {
684                     // retrieve port value
685                     var node = $(this).find('option:selected').attr('value');
686                     one.f.switchmanager.subnetGatewayConfig.registry['currentNode'] = node;
687                     var $ports = $('#' + one.f.switchmanager.subnetGatewayConfig.id.modal.form.ports);
688                     var ports = nodeports[node];
689                     var options = {};
690                     $(ports).each(function(idx, val) {
691                         options[val.internalPortName] = val.portName+' ('+val.portId+')'; 
692                     });
693                     one.lib.form.select.inject($ports, options);
694                     one.lib.form.select.prepend($ports, { '' : 'Please Select a Port' });
695                     $ports.val($ports.find("option:first").val());
696                 });
697
698                 // ports
699                 var $label = one.lib.form.label("Select Port");
700                 var $select = one.lib.form.select.create();
701                 one.lib.form.select.prepend($select, { '' : 'Please Select a Port' });
702                 $select.attr('id', one.f.switchmanager.subnetGatewayConfig.id.modal.form.ports);
703                 $fieldset.append($label).append($select);
704                 
705                 $form.append($fieldset);
706                 return $form;
707             }
708         },
709         ajax: {
710             gateway: function(requestData, callback) {
711                 $.getJSON(one.f.switchmanager.rootUrl + "/subnetGateway/add", requestData, function(data) {
712                     callback(data);
713             });
714             },
715             ports: function(requestData, callback) {
716                 $.getJSON(one.f.switchmanager.rootUrl + "/subnetGateway/ports/add", requestData, function(data) {
717                     callback(data);
718             });
719             }
720         },
721         footer : function() {
722             var footer = [];
723             var saveButton = one.lib.dashlet.button.single("Save", one.f.switchmanager.subnetGatewayConfig.id.modal.save, "btn-primary", "");
724             var $saveButton = one.lib.dashlet.button.button(saveButton);
725             footer.push($saveButton);
726             return footer;
727         },
728         removeMultiple: {
729             dialog: function(gatewaysToDelete) {
730                 var h3 = 'Remove Gateway IP Address';
731                 
732                 var footer = one.f.switchmanager.subnetGatewayConfig.modal.removeMultiple.footer();
733                 var $body = one.f.switchmanager.subnetGatewayConfig.modal.removeMultiple.body(gatewaysToDelete);
734                 var $modal = one.lib.modal.spawn(one.f.switchmanager.subnetGatewayConfig.id.modal.modal, h3, $body, footer);
735
736                 // bind close button
737                 $('#'+one.f.switchmanager.subnetGatewayConfig.id.modal.cancel, $modal).click(function() {
738                     $modal.modal('hide');
739                 });
740
741                 // bind remove rule button
742                 $('#'+one.f.switchmanager.subnetGatewayConfig.id.modal.remove, $modal).click(this, function(e) {
743                     var requestData = {};
744                     if (gatewaysToDelete.length > 0) {
745                         requestData["gatewaysToDelete"] = gatewaysToDelete.toString();
746                         var url = one.f.switchmanager.rootUrl + "/subnetGateway/delete";
747                         one.f.switchmanager.subnetGatewayConfig.ajax.main(url, requestData, function(response) {
748                             $modal.modal('hide');
749                             if (response.status == true) {
750                                 // refresh dashlet by passing dashlet div as param 
751                                 one.lib.alert("Gateway IP Address(es) successfully removed");
752                             } else {
753                                 alert(response.message);
754                             }
755                             one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
756                         });
757                     }
758                 });
759                 $modal.modal();
760             },
761             footer : function() {
762                 var footer = [];
763                 var remove = one.lib.dashlet.button.single('Remove Gateway IP Address',one.f.switchmanager.subnetGatewayConfig.id.modal.remove, 'btn-danger', '');
764                 var $remove = one.lib.dashlet.button.button(remove);
765                 footer.push($remove);
766
767                 var cancel = one.lib.dashlet.button.single('Cancel', one.f.switchmanager.subnetGatewayConfig.id.modal.cancel, '', '');
768                 var $cancel = one.lib.dashlet.button.button(cancel);
769                 footer.push($cancel);
770
771                 return footer;
772             },
773             body : function (gatewayList) {
774                 var $p = $(document.createElement('p'));
775                 var p = 'Remove the following Gateway IP Address(es)?';
776                 //creata a BS label for each rule and append to list
777                 $(gatewayList).each(function(){
778                     var $span = $(document.createElement('span'));
779                     $span.append(this);
780                     p += '<br/>' + $span[0].outerHTML;
781                 });
782                 $p.append(p);
783                 return $p;
784             }
785         }
786     },
787     // data functions
788     data : {
789         devicesgrid: function(data) {
790             one.f.switchmanager.subnetGatewayConfig.registry.gateways = [];
791             var source = new StaticDataSource({
792                     columns: [
793                         {
794                             property: 'selector',
795                             label: "<input type='checkbox'  id='"
796                                 +one.f.switchmanager.subnetGatewayConfig.id.dashlet.selectAll+"'/>",
797                             sortable: false
798                         },
799                         {
800                             property: 'name',
801                             label: 'Name',
802                             sortable: true
803                         },
804                         {
805                             property: 'subnet',
806                             label: 'Gateway IP Address/Mask',
807                             sortable: true
808                         },
809                         {
810                             property: 'nodePorts',
811                             label: 'Ports',
812                             sortable: false
813                         }
814                     ],
815                     data: data.nodeData,
816                     formatter: function(items) {
817                         $.each(items, function(index, tableRow) {
818                             tableRow["selector"] = '<input type="checkbox" class="subnetGatewayConfig" id="'
819                                 + tableRow["name"] + '"></input>';
820                             var json = tableRow["nodePorts"];
821                             var nodePorts = JSON.parse(json);
822                             var nodePortHtml = "<div>";
823                             $.each(nodePorts, function(index, nodePort) {
824                                 nodePortHtml += nodePort["nodePortName"] + " @ " + nodePort["nodeName"];
825                                 nodePortHtml += "&nbsp;";
826                                 nodePortHtml += '<a href="#" id="' + encodeURIComponent(nodePort["nodePortId"]) +
827                                     '" gatewayName="' + tableRow["name"] +
828                                     '" onclick="javascript:one.f.switchmanager.subnetGatewayConfig.actions.deleteNodePort(this);">Remove</a>';
829                                 nodePortHtml += "<br/>";
830                             });
831                             nodePortHtml += "</div>";
832                             tableRow["nodePorts"] = nodePortHtml;
833                         });
834
835                     },
836                     delay: 0
837                 });
838                 // populate the registry with subnet names
839                 one.f.switchmanager.subnetGatewayConfig.registry.gateways = [];
840                 $.each(data.nodeData, function(key, value) {
841                     one.f.switchmanager.subnetGatewayConfig.registry.gateways.push(value["name"]);
842                 });
843                 return source;          
844         },
845         devices : function(data) {
846             var result = [];
847             one.f.switchmanager.subnetGatewayConfig.registry.gateways = [];
848             $.each(data.nodeData, function(key, value) {
849                 var tr = {};
850                 // fill up all the td's
851                 var subnetConfigObject = $.parseJSON(value["json"]);
852                 var nodePorts = subnetConfigObject.nodePorts;
853                 var $nodePortsContainer = $(document.createElement("div"));
854                 
855                 for(var i = 0; i < nodePorts.length; i++) {
856                     var nodePort = nodePorts[i];
857                     $nodePortsContainer.append(nodePort + " ");
858                     // add delete anchor tag to delete ports
859                     var aTag = document.createElement("a");
860                     aTag.setAttribute("id", encodeURIComponent(nodePort));
861                     aTag.gatewayName = value["name"];
862                     aTag.addEventListener("click", function(evt) {
863                         var htmlPortAnchor = evt.target;
864                         var requestData = {};
865                         requestData["gatewayName"] = evt.target.gatewayName;
866                         requestData["nodePort"] = decodeURIComponent(evt.target.id);
867                         // make ajax call to delete port
868                         var url = one.f.switchmanager.rootUrl + "/subnetGateway/ports/delete";
869                         one.f.switchmanager.subnetGatewayConfig.ajax.main(url, requestData, function(response) {
870                             if(response.status == true) {
871                                 // refresh dashlet by passing dashlet div as param
872                                 one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
873                             } else {
874                                 alert(response.message);
875                             }
876                         });
877                         
878                     });
879                     aTag.addEventListener("mouseover", function(evt) {
880                         evt.target.style.cursor = "pointer";
881                     }, false);
882                     aTag.innerHTML = "Remove";
883                     $nodePortsContainer.append(aTag);
884                     $nodePortsContainer.append("<br/>");
885                 }
886
887                 // store gateways in the registry so that they can be used in the add ports popup
888                 one.f.switchmanager.subnetGatewayConfig.registry.gateways.push(value["name"]);
889                 var entry = [];
890                 var checkbox = document.createElement("input");
891                 checkbox.setAttribute("type", "checkbox");
892                 checkbox.setAttribute("id", value["name"]);
893                 entry.push(checkbox);
894                 entry.push(value["name"]);
895                 entry.push(value["subnet"]);
896                 entry.push($nodePortsContainer);
897                 tr.entry = entry;
898                 result.push(tr);
899             });
900             return result;
901         }
902     },
903     actions: {
904         deleteNodePort: function(htmlPortAnchor) {
905             var requestData = {};
906             requestData["gatewayName"] = htmlPortAnchor.getAttribute("gatewayName");
907             requestData["nodePort"] = decodeURIComponent(htmlPortAnchor.id);
908             // make ajax call to delete port
909             var url = one.f.switchmanager.rootUrl + "/subnetGateway/ports/delete";
910             one.f.switchmanager.subnetGatewayConfig.ajax.main(url, requestData, function(response) {
911                 if(response.status == true) {
912                     // refresh dashlet by passing dashlet div as param
913                     one.f.switchmanager.subnetGatewayConfig.dashlet($("#right-bottom .dashlet"));
914                 } else {
915                     alert(response.message);
916                 }
917             });
918         }
919     }
920 }
921
922 one.f.switchmanager.staticRouteConfig = {
923     id: {
924         dashlet: {
925             add: "one_f_switchmanager_staticRouteConfig_id_dashlet_add",
926             remove: "one_f_switchmanager_staticRouteConfig_id_dashlet_remove",
927             datagrid: "one_f_switchmanager_staticRouteConfig_id_dashlet_datagrid",
928             selectAll: "one_f_switchmanager_staticRouteConfig_id_dashlet_selectAll"
929         }, 
930         modal: {
931             modal: "one_f_switchmanager_staticRouteConfig_id_modal_modal",
932             save: "one_f_switchmanager_staticRouteConfig_id_modal_save",
933             cancel: "one_f_switchmanager_staticRouteConfig_id_modal_cancel",
934             remove: "one_f_switchmanager_staticRouteConfig_id_modal_remove",
935             form: {
936                 routeName : "one_f_switchmanager_staticRouteConfig_id_modal_form_routename",
937                 staticRoute : "one_f_switchmanager_staticRouteConfig_id_modal_form_staticroute",
938                 nextHop : "one_f_switchmanager_staticRouteConfig_id_modal_form_nexthop",
939             }
940         }
941     },
942     dashlet: function($dashlet) {
943         one.lib.dashlet.empty($dashlet);
944         var url = one.f.switchmanager.rootUrl + "/staticRoutes";
945         one.f.switchmanager.staticRouteConfig.ajax.main(url, {}, function(content) {
946
947             if (content.privilege === 'WRITE') {
948                 // Add static route button
949                 var button = one.lib.dashlet.button.single("Add Static Route", one.f.switchmanager.staticRouteConfig.id.dashlet.add, "btn-primary", "btn-mini");
950                 var $button = one.lib.dashlet.button.button(button);
951                 $button.click(function() {
952                     var $modal = one.f.switchmanager.staticRouteConfig.modal.initialize();
953                     $modal.modal();
954                 });
955                 $dashlet.append(one.lib.dashlet.header(one.f.dashlet.staticRouteConfig.name));
956                 $dashlet.append($button);
957
958                 // Delete static route button
959                 var button = one.lib.dashlet.button.single("Remove Static Route", one.f.switchmanager.staticRouteConfig.id.dashlet.remove, "btn-danger", "btn-mini");
960                 var $button = one.lib.dashlet.button.button(button);
961                 $button.click(function() {
962                     var routesToDelete = [];
963                     var checkedCheckBoxes = $("#" + one.f.switchmanager.staticRouteConfig.id.dashlet.datagrid).find("tbody input:checked");
964                     checkedCheckBoxes.each(function(index, value) {
965                         routesToDelete.push(checkedCheckBoxes[index].id);
966                     });
967                     if (checkedCheckBoxes.size() === 0) {
968                         return false;
969                     }
970                     one.f.switchmanager.staticRouteConfig.modal.removeMultiple.dialog(routesToDelete);
971                 });
972                 $dashlet.append($button);
973             }
974             var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.staticRouteConfig.id.dashlet.datagrid, {
975                 searchable: true,
976                 filterable: false,
977                 pagination: true,
978                 flexibleRowsPerPage: true
979                 }, "table-striped table-condensed");
980             $dashlet.append($gridHTML);
981             var dataSource = one.f.switchmanager.staticRouteConfig.data.staticRouteConfigGrid(content);
982             $("#" + one.f.switchmanager.staticRouteConfig.id.dashlet.datagrid).datagrid({dataSource: dataSource})
983             .on("loaded", function() {
984                 $("#"+one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll).click(function() {
985                     $("#" + one.f.switchmanager.staticRouteConfig.id.dashlet.datagrid).find(':checkbox').prop('checked',
986                         $("#"+one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll).is(':checked'));
987                 });
988                 $(".staticRoute").click(function(e){
989                     if (!$('.staticRoute[type=checkbox]:not(:checked)').length) {
990                         $("#"+one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll)
991                             .prop("checked",
992                           true);
993                     } else {
994                         $("#"+one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll)
995                             .prop("checked",
996                          false);
997                     }
998                     e.stopPropagation();
999                 });
1000              });
1001         });
1002     },
1003     // device ajax calls
1004     ajax : {
1005         main : function(url, requestData, callback) {
1006             $.getJSON(url, requestData, function(data) {
1007                 callback(data);
1008             });
1009         }
1010     },
1011     registry: {},
1012     modal : {
1013         initialize: function() {
1014             var h3 = "Add Static Route";
1015             var footer = one.f.switchmanager.staticRouteConfig.modal.footer();
1016             var $modal = one.lib.modal.spawn(one.f.switchmanager.staticRouteConfig.id.modal.modal, h3, "", footer);
1017             // bind save button
1018             $('#' + one.f.switchmanager.staticRouteConfig.id.modal.save, $modal).click(function() {
1019                 one.f.switchmanager.staticRouteConfig.modal.save($modal);
1020             });
1021             var $body = one.f.switchmanager.staticRouteConfig.modal.body();
1022             one.lib.modal.inject.body($modal, $body);
1023             return $modal;
1024         },
1025         save: function($modal) {
1026             var result = {};
1027             result['routeName'] = $('#' + one.f.switchmanager.staticRouteConfig.id.modal.form.routeName, $modal).val();
1028             result['staticRoute'] = $('#' + one.f.switchmanager.staticRouteConfig.id.modal.form.staticRoute, $modal).val();
1029             result['nextHop'] = $('#' + one.f.switchmanager.staticRouteConfig.id.modal.form.nextHop, $modal).val();
1030             one.f.switchmanager.staticRouteConfig.modal.ajax.staticRouteConfig(result, function(response) {
1031                     if(response.status == true) {
1032                         $modal.modal('hide');
1033                         // refresh dashlet by passing dashlet div as param
1034                         one.f.switchmanager.staticRouteConfig.dashlet($("#left-bottom .dashlet"));
1035                     } else {
1036                         // TODO: Show error message in a error message label instead.
1037                         alert(response.message);
1038                     }
1039                 });
1040         },
1041         body: function() {
1042             var $form = $(document.createElement('form'));
1043             var $fieldset = $(document.createElement('fieldset'));
1044             // static route name
1045             var $label = one.lib.form.label("Name");
1046             var $input = one.lib.form.input("Name");
1047             $input.attr('id', one.f.switchmanager.staticRouteConfig.id.modal.form.routeName);
1048             $fieldset.append($label).append($input);
1049             // static route IP Mask 
1050             var $label = one.lib.form.label("Static Route");
1051             var $input = one.lib.form.input("Static Route");
1052             var $help = one.lib.form.help('Example: 53.55.0.0/16');
1053             $input.attr('id', one.f.switchmanager.staticRouteConfig.id.modal.form.staticRoute);
1054             $fieldset.append($label).append($input).append($help);
1055             // static route IP Mask 
1056             var $label = one.lib.form.label("Next Hop");
1057             var $input = one.lib.form.input("Next Hop");
1058             var $help = one.lib.form.help('Example: 192.168.10.254');
1059             $input.attr('id', one.f.switchmanager.staticRouteConfig.id.modal.form.nextHop);
1060             $fieldset.append($label).append($input).append($help);
1061             // return
1062             $form.append($fieldset);
1063             return $form;
1064         },
1065         ajax: {
1066             staticRouteConfig: function(requestData, callback) {
1067                 $.getJSON(one.f.switchmanager.rootUrl + "/staticRoute/add", requestData, function(data) {
1068                     callback(data);
1069                 });
1070             }
1071         },
1072         data : {
1073             
1074         },
1075         footer : function() {
1076             var footer = [];
1077             var saveButton = one.lib.dashlet.button.single("Save", one.f.switchmanager.staticRouteConfig.id.modal.save, "btn-primary", "");
1078             var $saveButton = one.lib.dashlet.button.button(saveButton);
1079             footer.push($saveButton);
1080             return footer;
1081         },
1082         removeMultiple: {
1083             dialog: function(routesToDelete) {
1084                 var h3 = 'Remove Static Route';
1085                 
1086                 var footer = one.f.switchmanager.staticRouteConfig.modal.removeMultiple.footer();
1087                 var $body = one.f.switchmanager.staticRouteConfig.modal.removeMultiple.body(routesToDelete);
1088                 var $modal = one.lib.modal.spawn(one.f.switchmanager.staticRouteConfig.id.modal.modal, h3, $body, footer);
1089
1090                 // bind close button
1091                 $('#'+one.f.switchmanager.staticRouteConfig.id.modal.cancel, $modal).click(function() {
1092                     $modal.modal('hide');
1093                 });
1094
1095                 // bind remove rule button
1096                 $('#'+one.f.switchmanager.staticRouteConfig.id.modal.remove, $modal).click(this, function(e) {
1097                     if (routesToDelete.length > 0) {
1098                         var requestData = {};
1099                         requestData["routesToDelete"] = routesToDelete.toString();
1100                         var url = one.f.switchmanager.rootUrl + "/staticRoute/delete";
1101                         one.f.switchmanager.staticRouteConfig.ajax.main(url, requestData, function(response) {
1102                             $modal.modal('hide');
1103                             if (response.status == true) {
1104                                 // refresh dashlet by passing dashlet div as param 
1105                                 one.lib.alert("Static Route(s) successfully removed");
1106                             } else {
1107                                 alert(response.message);
1108                             }
1109                             one.f.switchmanager.staticRouteConfig.dashlet($("#left-bottom .dashlet"));
1110                         });
1111                     }
1112                 });
1113                 $modal.modal();
1114             },
1115             footer : function() {
1116                 var footer = [];
1117                 var remove = one.lib.dashlet.button.single('Remove Static Route',one.f.switchmanager.staticRouteConfig.id.modal.remove, 'btn-danger', '');
1118                 var $remove = one.lib.dashlet.button.button(remove);
1119                 footer.push($remove);
1120
1121                 var cancel = one.lib.dashlet.button.single('Cancel', one.f.switchmanager.staticRouteConfig.id.modal.cancel, '', '');
1122                 var $cancel = one.lib.dashlet.button.button(cancel);
1123                 footer.push($cancel);
1124
1125                 return footer;
1126             },
1127             body : function (staticRouteList) {
1128                 var $p = $(document.createElement('p'));
1129                 var p = 'Remove the following Static Route(s)?';
1130                 //creata a BS label for each rule and append to list
1131                 $(staticRouteList).each(function(){
1132                     var $span = $(document.createElement('span'));
1133                     $span.append(this);
1134                     p += '<br/>' + $span[0].outerHTML;
1135                 });
1136                 $p.append(p);
1137                 return $p;
1138             }
1139         }
1140     },
1141     // data functions
1142     data : {
1143         staticRouteConfigGrid: function(data) {
1144             var source = new StaticDataSource({
1145                     columns: [
1146                         {
1147                             property: 'selector',
1148                             label: "<input type='checkbox'  id='"
1149                                 +one.f.switchmanager.staticRouteConfig.id.dashlet.selectAll+"'/>",
1150                             sortable: false
1151                         },
1152                         {
1153                             property: 'name',
1154                             label: 'Name',
1155                             sortable: true
1156                         },
1157                         {
1158                             property: 'staticRoute',
1159                             label: 'Static Route',
1160                             sortable: true
1161                         },
1162                         {
1163                             property: 'nextHop',
1164                             label: 'Next Hop Address',
1165                             sortable: true
1166                         }
1167                     ],
1168                     data: data.nodeData,
1169                     formatter: function(items) {
1170                         $.each(items, function(index, item) {
1171                             item["selector"] = '<input type="checkbox" class="staticRoute" id="' + item["name"] + '"></input>';
1172                         });
1173
1174                     },
1175                     delay: 0
1176                 });
1177             return source;              
1178         },
1179         staticRouteConfig : function(data) {
1180             var result = [];
1181             $.each(data.nodeData, function(key, value) {
1182                 var tr = {};
1183                 // fill up all the td's
1184                 var entry = [];
1185                 var checkbox = document.createElement("input");
1186                 checkbox.setAttribute("type", "checkbox");
1187                 checkbox.setAttribute("id", value["name"]);
1188                 entry.push(checkbox);
1189                 entry.push(value["name"]);
1190                 entry.push(value["staticRoute"]);
1191                 entry.push(value["nextHop"]);
1192                 tr.entry = entry;
1193                 result.push(tr);
1194             });
1195             return result;
1196         }
1197     }
1198 }
1199
1200 one.f.switchmanager.spanPortConfig = {
1201     id: {
1202         dashlet: {
1203             add: "one_f_switchmanager_spanPortConfig_id_dashlet_add",
1204             remove: "one_f_switchmanager_spanPortConfig_id_dashlet_remove",
1205             datagrid: "one_f_switchmanager_spanPortConfig_id_dashlet_datagrid",
1206             selectAllFlows: "one_f_switchmanager_spanPortConfig_id_dashlet_selectAllFlows"
1207         }, 
1208         modal: {
1209             modal: "one_f_switchmanager_spanPortConfig_id_modal_modal",
1210             save: "one_f_switchmanager_spanPortConfig_id_modal_save",
1211             cancel: "one_f_switchmanager_spanPortConfig_id_modal_cancel",
1212             remove: "one_f_switchmanager_spanPortConfig_id_modal_remove",
1213             form: {
1214                 name : "one_f_switchmanager_spanPortConfig_id_modal_form_name",
1215                 nodes : "one_f_switchmanager_spanPortConfig_id_modal_form_nodes",
1216                 port : "one_f_switchmanager_spanPortConfig_id_modal_form_port",
1217             }
1218         }
1219     },
1220     dashlet: function($dashlet) {
1221         one.lib.dashlet.empty($dashlet);
1222         
1223         //populate table in dashlet
1224         var url = one.f.switchmanager.rootUrl + "/spanPorts";
1225         one.f.switchmanager.spanPortConfig.ajax.main(url, {}, function(content) {
1226
1227             if (content.privilege === 'WRITE') {
1228
1229                 // Add span port button
1230                 var button = one.lib.dashlet.button.single("Add SPAN Port", one.f.switchmanager.spanPortConfig.id.dashlet.add, "btn-primary", "btn-mini");
1231                 var $button = one.lib.dashlet.button.button(button);
1232
1233                 $button.click(function() {
1234                     var $modal = one.f.switchmanager.spanPortConfig.modal.initialize();
1235                     $modal.modal();
1236                 });
1237                 $dashlet.append(one.lib.dashlet.header(one.f.dashlet.spanPortConfig.name));
1238                 $dashlet.append($button);
1239
1240                 // Delete span port button
1241                 var button = one.lib.dashlet.button.single("Remove SPAN Port", one.f.switchmanager.spanPortConfig.id.dashlet.remove, "btn-danger", "btn-mini");
1242                 var $button = one.lib.dashlet.button.button(button);
1243                 $button.click(function() {
1244                     var spanPortsToDelete = [];
1245                     var checkedCheckBoxes = $("#" + one.f.switchmanager.spanPortConfig.id.dashlet.datagrid).find("tbody input:checked");
1246                     
1247                     if (checkedCheckBoxes.size() === 0) {
1248                         return false;
1249                     }
1250                     checkedCheckBoxes.each(function(index, value) {
1251                         var spanPortObj = {};
1252                         spanPortObj['spanPortJson'] = decodeURIComponent(checkedCheckBoxes[index].getAttribute("spanPort"));
1253                         spanPortObj['spanPortNodeName'] = checkedCheckBoxes[index].getAttribute("spanPortNode");
1254                         spanPortObj['spanPortPortName'] = checkedCheckBoxes[index].getAttribute("spanPortPort");
1255
1256                         spanPortsToDelete.push(spanPortObj);
1257                     });
1258                     one.f.switchmanager.spanPortConfig.modal.removeMultiple.dialog(spanPortsToDelete);
1259                 });
1260                 $dashlet.append($button);
1261             }
1262             var $gridHTML = one.lib.dashlet.datagrid.init(one.f.switchmanager.spanPortConfig.id.dashlet.datagrid, {
1263                 searchable: true,
1264                 filterable: false,
1265                 pagination: true,
1266                 flexibleRowsPerPage: true
1267                 }, "table-striped table-condensed");
1268             $dashlet.append($gridHTML);
1269             var dataSource = one.f.switchmanager.spanPortConfig.data.spanPortConfigGrid(content);
1270             $("#" + one.f.switchmanager.spanPortConfig.id.dashlet.datagrid).datagrid({dataSource: dataSource})
1271             .on("loaded", function() {
1272                 $("#"+one.f.switchmanager.spanPortConfig.id.dashlet.selectAll).click(function() {
1273                     $("#" + one.f.switchmanager.spanPortConfig.id.dashlet.datagrid).find(':checkbox').prop('checked',
1274                         $("#"+one.f.switchmanager.spanPortConfig.id.dashlet.selectAll).is(':checked'));
1275                 });
1276                 $(".spanPortConfig").click(function(e){
1277                     if (!$('.spanPortConfig[type=checkbox]:not(:checked)').length) {
1278                         $("#"+one.f.switchmanager.spanPortConfig.id.dashlet.selectAll)
1279                             .prop("checked",
1280                           true);
1281                     } else {
1282                         $("#"+one.f.switchmanager.spanPortConfig.id.dashlet.selectAll)
1283                             .prop("checked",
1284                          false);
1285                     }
1286                     e.stopPropagation();
1287                 });
1288              });
1289         });
1290     },
1291     // device ajax calls
1292     ajax : {
1293         main : function(url, requestData, callback) {
1294             $.getJSON(url, requestData, function(data) {
1295                 callback(data);
1296             });
1297         }
1298     },
1299     registry: {},
1300     modal : {
1301         initialize: function() {
1302             var h3 = "Add SPAN Port";
1303             var footer = one.f.switchmanager.spanPortConfig.modal.footer();
1304             var $modal = one.lib.modal.spawn(one.f.switchmanager.spanPortConfig.id.modal.modal, h3, "", footer);
1305             // bind save button
1306             $('#' + one.f.switchmanager.spanPortConfig.id.modal.save, $modal).click(function() {
1307                 one.f.switchmanager.spanPortConfig.modal.save($modal);
1308             });
1309
1310             one.f.switchmanager.spanPortConfig.modal.ajax.nodes(function(nodes, nodeports) {
1311                 var $body = one.f.switchmanager.spanPortConfig.modal.body(nodes, nodeports);
1312                 one.lib.modal.inject.body($modal, $body);
1313             });
1314             return $modal;
1315         },
1316         save: function($modal) {
1317             var result = {};
1318             result['nodeId'] = $('#' + one.f.switchmanager.spanPortConfig.id.modal.form.nodes, $modal).val();
1319             result['spanPort'] = $('#' + one.f.switchmanager.spanPortConfig.id.modal.form.port, $modal).val();
1320             one.f.switchmanager.spanPortConfig.modal.ajax.saveSpanPortConfig(result, 
1321                 function(response) {
1322                     if(response.status == true) {
1323                         $modal.modal('hide');
1324                         one.f.switchmanager.spanPortConfig.dashlet($("#right-bottom .dashlet"));
1325                     } else {
1326                         alert(response.message);
1327                     }
1328                     
1329                 });
1330         },
1331         body: function(nodes, nodeports) {
1332             var $form = $(document.createElement('form'));
1333             var $fieldset = $(document.createElement('fieldset'));
1334             // node
1335             var $label = one.lib.form.label("Node");
1336             var $select = one.lib.form.select.create(nodes);
1337             one.lib.form.select.prepend($select, { '' : 'Please Select a Node' });
1338             $select.val($select.find("option:first").val());
1339             $select.attr('id', one.f.switchmanager.spanPortConfig.id.modal.form.nodes);
1340             
1341             // bind onchange
1342             $select.change(function() {
1343                 // retrieve port value
1344                 var nodeId = $(this).find('option:selected').attr('value');
1345                 one.f.switchmanager.spanPortConfig.registry['currentNode'] = nodeId;
1346                 var $ports = $('#'+one.f.switchmanager.spanPortConfig.id.modal.form.port);
1347                 var ports = one.f.switchmanager.spanPortConfig.registry['nodePorts'][nodeId]
1348                 var options = {};
1349                 $(ports).each(function(idx, val) {
1350                     options[val.internalPortName] = val.portName+' ('+val.portId+')'; 
1351                 });
1352                 one.lib.form.select.inject($ports, options); 
1353                 one.lib.form.select.prepend($ports, {'':'Please Select a Port'});
1354                 $ports.val($ports.find('option:first').val());
1355             });
1356
1357             $fieldset.append($label).append($select);
1358             // input port
1359             var $label = one.lib.form.label("Input Port");
1360             var $select = one.lib.form.select.create();
1361             one.lib.form.select.prepend($select, {'':'None'});
1362             $select.attr('id', one.f.switchmanager.spanPortConfig.id.modal.form.port);
1363             $select.val($select.find('option:first').val());
1364             $fieldset.append($label).append($select);
1365             
1366             // return
1367             $form.append($fieldset);
1368             return $form;
1369         },
1370         ajax: {
1371             nodes: function(callback) {
1372                 $.getJSON(one.f.switchmanager.rootUrl + "/nodeports", function(data) {
1373                     var nodes = {};
1374                     var nodePorts = {};
1375                     $(data).each(function(index, node) {
1376                         nodes[node.nodeId] = node.nodeName;
1377                         nodePorts[node.nodeId] = node.nodePorts;
1378                     });
1379                     one.f.switchmanager.spanPortConfig.registry['nodePorts'] = nodePorts;
1380                     callback(nodes, nodePorts);
1381                 });
1382             },
1383             saveSpanPortConfig: function(requestData, callback) {
1384                 var resource = {};
1385                 resource["jsonData"] = JSON.stringify(requestData);
1386                 $.getJSON(one.f.switchmanager.rootUrl + "/spanPorts/add", resource, function(data) {
1387                     callback(data);
1388                 });
1389             }
1390         },
1391         footer : function() {
1392             var footer = [];
1393             var saveButton = one.lib.dashlet.button.single("Save", one.f.switchmanager.spanPortConfig.id.modal.save, "btn-primary", "");
1394             var $saveButton = one.lib.dashlet.button.button(saveButton);
1395             footer.push($saveButton);
1396             return footer;
1397         },
1398         removeMultiple: {
1399             dialog: function(spanPortsToDelete) {
1400                 var h3 = 'Remove SPAN Port';
1401                 
1402                 var footer = one.f.switchmanager.spanPortConfig.modal.removeMultiple.footer();
1403                 var $body = one.f.switchmanager.spanPortConfig.modal.removeMultiple.body(spanPortsToDelete);
1404                 var $modal = one.lib.modal.spawn(one.f.switchmanager.spanPortConfig.id.modal.modal, h3, $body, footer);
1405
1406                 // bind close button
1407                 $('#'+one.f.switchmanager.spanPortConfig.id.modal.cancel, $modal).click(function() {
1408                     $modal.modal('hide');
1409                 });
1410
1411                 // bind remove rule button
1412                 $('#'+one.f.switchmanager.spanPortConfig.id.modal.remove, $modal).click(this, function(e) {
1413                     var requestData = {};
1414                     var spanPorts = [];
1415                     $(spanPortsToDelete).each(function(index, spanPort) {
1416                         spanPorts.push(JSON.parse(spanPort.spanPortJson));
1417                     });
1418                     requestData["spanPortsToDelete"] = JSON.stringify(spanPorts);
1419
1420                     var url = one.f.switchmanager.rootUrl + "/spanPorts/delete";
1421                     one.f.switchmanager.spanPortConfig.ajax.main(url, requestData, function(response) {
1422                         $modal.modal('hide');
1423                         if (response.status == true) {
1424                             // refresh dashlet by passing dashlet div as param
1425                             one.lib.alert("Span Port(s) successfully removed");
1426                         } else {
1427                             alert(response.message);
1428                         }
1429                         one.f.switchmanager.spanPortConfig.dashlet($("#right-bottom .dashlet"));
1430                     });
1431                 });
1432                 $modal.modal();
1433             },
1434             footer : function() {
1435                 var footer = [];
1436                 var remove = one.lib.dashlet.button.single('Remove SPAN Port',one.f.switchmanager.spanPortConfig.id.modal.remove, 'btn-danger', '');
1437                 var $remove = one.lib.dashlet.button.button(remove);
1438                 footer.push($remove);
1439
1440                 var cancel = one.lib.dashlet.button.single('Cancel', one.f.switchmanager.spanPortConfig.id.modal.cancel, '', '');
1441                 var $cancel = one.lib.dashlet.button.button(cancel);
1442                 footer.push($cancel);
1443
1444                 return footer;
1445             },
1446             body : function (spanPortToDelete) {
1447                 var $p = $(document.createElement('p'));
1448                 var p = 'Remove the following Span Port(s)?';
1449                 //creata a BS label for each rule and append to list
1450
1451                 $(spanPortToDelete).each(function(index, spanPortItem) {
1452                     var $span = $(document.createElement('span'));
1453                     $span.append(this.spanPortNodeName+"-"+this.spanPortPortName);
1454                     p += '<br/>' + $span[0].outerHTML;
1455                 });
1456                 $p.append(p);
1457                 return $p;
1458             }
1459         }
1460     },
1461     // data functions
1462     data : {
1463         spanPortConfigGrid: function(data) {
1464             var source = new StaticDataSource({
1465                     columns: [
1466                         {
1467                             property: 'selector',
1468                             label: "<input type='checkbox'  id='"
1469                                 +one.f.switchmanager.spanPortConfig.id.dashlet.selectAll+"'/>",
1470                             sortable: false
1471                         },
1472                         {
1473                             property: 'nodeName',
1474                             label: 'Node',
1475                             sortable: true
1476                         },
1477                         {
1478                             property: 'spanPortName',
1479                             label: 'SPAN Port',
1480                             sortable: true
1481                         },
1482                     ],
1483                     data: data.nodeData,
1484                     formatter: function(items) {
1485                         $.each(items, function(index, item) {
1486                             item["selector"] = '<input type="checkbox" class="spanPortConfig" spanPort=' + encodeURIComponent(item["json"]) + ' spanPortNode="' + item["nodeName"] + '" spanPortPort="' + item["spanPortName"] + '"></input>';
1487                         });
1488                     },
1489                     delay: 0
1490                 });
1491             return source;              
1492         },
1493         devices : function(data) {
1494             var result = [];
1495             $.each(data.nodeData, function(key, value) {
1496                 var tr = {};
1497                 // fill up all the td's
1498                 var entry = [];
1499                 var checkbox = document.createElement("input");
1500                 checkbox.setAttribute("type", "checkbox");
1501                 checkbox.spanPort = value.json;
1502                 entry.push(checkbox);
1503                 entry.push(value["nodeName"]);
1504                 entry.push(value["spanPort"]);
1505                 tr.entry = entry;
1506                 result.push(tr);
1507             });
1508             return result;
1509         }
1510     }
1511 }
1512
1513 /** INIT **/
1514 // populate nav tabs
1515 $(one.f.menu.left.top).each(function(index, value) {
1516     var $nav = $(".nav", "#left-top");
1517     one.main.page.dashlet($nav, value);
1518 });
1519
1520 $(one.f.menu.left.bottom).each(function(index, value) {
1521     var $nav = $(".nav", "#left-bottom");
1522     one.main.page.dashlet($nav, value);
1523 });
1524
1525 $(one.f.menu.right.bottom).each(function(index, value) {
1526     var $nav = $(".nav", "#right-bottom");
1527     one.main.page.dashlet($nav, value);
1528 });
1529
1530 one.f.addPopOut = function() {
1531     $img1 = $(document.createElement("img"));
1532     $img1.attr("src", "/img/Expand16T.png");
1533     $img1.attr("style", "float: right;");
1534     $img1.hover(function() {
1535         $img1.css("cursor", "pointer");
1536     });
1537     $img1.click(function() {
1538         var $modal = one.f.switchmanager.nodesLearnt.modal.initialize.popout();
1539         $modal.css({
1540             'margin-left': '-45%',
1541             'margin-top': '-3%',
1542             'width':$(document).width() * 0.8,
1543             'height':$(document).height() * 0.9
1544         });
1545         $(".modal-body", $modal).css({
1546             "max-height": $(document).height() * 0.75,
1547         });
1548         $modal.modal();
1549     });
1550     $dash1 = $($("#left-top .nav")[0]);
1551     $dash1.append($img1);
1552 };
1553 one.f.addPopOut();
1554
1555 // bind dashlet nav
1556 $('.dash .nav a', '#main').click(function() {
1557     // de/activation
1558     var $li = $(this).parent();
1559     var $ul = $li.parent();
1560     one.lib.nav.unfocus($ul);
1561     $li.addClass('active');
1562     // clear respective dashlet
1563     var $dashlet = $ul.parent().find('.dashlet');
1564     one.lib.dashlet.empty($dashlet);
1565
1566     // callback based on menu
1567     var id = $(this).attr('id');
1568     var menu = one.f.dashlet;
1569     switch (id) {
1570         case menu.nodesLearnt.id:
1571             one.f.switchmanager.nodesLearnt.dashlet($dashlet);
1572             break;
1573         case menu.staticRouteConfig.id:
1574             one.f.switchmanager.staticRouteConfig.dashlet($dashlet);
1575             break;
1576         case menu.subnetGatewayConfig.id:
1577             one.f.switchmanager.subnetGatewayConfig.dashlet($dashlet);
1578             break;
1579         case menu.spanPortConfig.id:
1580             one.f.switchmanager.spanPortConfig.dashlet($dashlet);
1581             break;
1582     };
1583 });
1584
1585 // activate first tab on each dashlet
1586 $('.dash .nav').each(function(index, value) {
1587     $($(value).find('li')[0]).find('a').click();
1588 });