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