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