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