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