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