2 * Description: display a query result in a datatables-powered <table>
3 * Copyright (c) 2012-2013 UPMC Sorbonne Universite - INRIA
13 var UnivbrisFvfo = Plugin.extend({
15 init: function(options, element) {
16 //alert("foam init called");
17 this.classname="univbrisfvfo";
18 this._super(options, element);
20 //alert(this.options.hidden_columns);
21 /* Member variables */
22 // in general we expect 2 queries here
23 // query_uuid refers to a single object (typically a slice)
24 // query_all_uuid refers to a list (typically resources or users)
25 // these can return in any order so we keep track of which has been received yet
26 //this.received_all_query = false;
27 //this.received_query = false;
29 // We need to remember the active filter for datatables filtering
30 this.filters = Array();
32 // an internal buffer for records that are 'in' and thus need to be checked
33 this.buffered_records_to_check = [];
34 // an internal buffer for keeping lines and display them in one call to fnAddData
35 this.buffered_lines = [];
38 // xx somehow non of these triggers at all for now
39 //this.elmt().on('show', this, this.on_show);
40 //this.elmt().on('shown.bs.tab', this, this.on_show);
41 //this.elmt().on('resize', this, this.on_resize);
43 //var query = manifold.query_store.find_analyzed_query(this.options.query_uuid);
44 //this.object = query.object;
46 //// we need 2 different keys
47 // * canonical_key is the primary key as derived from metadata (typically: urn)
48 // and is used to communicate about a given record with the other plugins
49 // * init_key is a key that both kinds of records
50 // (i.e. records returned by both queries) must have (typically: hrn or hostname)
51 // in general query_all will return well populated records, but query
52 // returns records with only the fields displayed on startup
53 var keys = manifold.metadata.get_key(this.object);
54 this.canonical_key = (keys && keys.length == 1) ? keys[0] : undefined;
56 this.init_key = this.options.init_key;
57 // have init_key default to canonical_key
58 this.init_key = this.init_key || this.canonical_key;
60 if ( ! this.init_key ) messages.warning ("UnivbrisFvfo : cannot find init_key");
61 if ( ! this.canonical_key ) messages.warning ("UnivbrisFvfo : cannot find canonical_key");
62 if (debug) messages.debug("UnivbrisFvfo: canonical_key="+this.canonical_key+" init_key="+this.init_key);
64 /* Setup query and record handlers */
65 //this.listen_query(options.query_uuid);
66 //this.listen_query(options.query_all_uuid, 'all');
68 /* GUI setup and event binding */
69 //this.initialize_table();
71 jQuery("#uob_ofv_table_form").hide();
73 //$('<button id="cancel_addflowspaceform" type="button" style="height: 25px; width: 200px" onclick="fnCancel()">Cancel</button>').appendTo('#fvf_table_button');
75 //$('<button id="addflowspaceform" type="button" style="height: 25px; width: 200px" onclick="fnAddflowspace()">Add flowspace</button>').appendTo('#fvf_table_button');
77 this._querytable_draw_callback();
82 on_show: function(e) {
83 if (debug) messages.debug("univbrisfvfo.on_show");
85 self.table.fnAdjustColumnSizing();
88 on_resize: function(e) {
89 if (debug) messages.debug("univbrisfvfo.on_resize");
91 self.table.fnAdjustColumnSizing();
96 /* GUI MANIPULATION */
98 initialize_table: function()
100 /* Transforms the table into DataTable, and keep a pointer to it */
102 var actual_options = {
103 // Customize the position of Datatables elements (length,filter,button,...)
104 // we use a fluid row on top and another on the bottom, making sure we take 12 grid elt's each time
105 //sDom: "<'row'<'col-xs-5'l><'col-xs-1'r><'col-xs-6'f>>t<'row'<'col-xs-5'i><'col-xs-7'p>>",
106 //sDom: "<'row'<'col-xs-2'l><'col-xs-9'r><'col-xs-2'f>>t<'row'<'col-xs-5'i><'col-xs-5'p>><'next'>",
107 sDom: "<'row'<'col-xs-9'r>t<'buttons'>",
108 // XXX as of sept. 2013, I cannot locate a bootstrap3-friendly mode for now
109 // hopefully this would come with dataTables v1.10 ?
110 // in any case, search for 'sPaginationType' all over the code for more comments
111 sPaginationType: 'bootstrap',
112 // Handle the null values & the error : Datatables warning Requested unknown parameter
113 // http://datatables.net/forums/discussion/5331/datatables-warning-...-requested-unknown-parameter/p2
114 aoColumnDefs: [{sDefaultContent: '',aTargets: [ '_all' ]}],
115 // WARNING: this one causes tables in a 'tabs' that are not exposed at the time this is run to show up empty
116 // sScrollX: '100%', /* Horizontal scrolling */
117 bProcessing: false, /* Loading */
118 fnDrawCallback: function() { self._querytable_draw_callback.call(self);}
119 //fnFooterCallback: function() {self._univbrisfvf_footer_callback.call(self,nFoot, aData, iStart, iEnd, aiDisplay)};}
120 // XXX use $.proxy here !
122 // the intention here is that options.datatables_options as coming from the python object take precedence
123 // xxx DISABLED by jordan: was causing errors in datatables.js
124 // xxx turned back on by Thierry - this is the code that takes python-provided options into account
125 // check your datatables_options tag instead
126 // however, we have to accumulate in aoColumnDefs from here (above)
127 // and from the python wrapper (checkboxes management, plus any user-provided aoColumnDefs)
128 if ( 'aoColumnDefs' in this.options.datatables_options) {
129 actual_options['aoColumnDefs']=this.options.datatables_options['aoColumnDefs'].concat(actual_options['aoColumnDefs']);
130 delete this.options.datatables_options['aoColumnDefs'];
132 $.extend(actual_options, this.options.datatables_options );
133 this.table = $("#univbris_flowspace_form__table").dataTable(actual_options);
137 /* Setup the SelectAll button in the dataTable header */
138 /* xxx not sure this is still working */
139 var oSelectAll = $('#datatableSelectAll-'+ this.options.plugin_uuid);
140 oSelectAll.html("<span class='glyphicon glyphicon-ok' style='float:right;display:inline-block;'></span>Select All");
142 oSelectAll.css('font-size','11px');
143 oSelectAll.css('float','right');
144 oSelectAll.css('margin-right','15px');
145 oSelectAll.css('margin-bottom','5px');
146 oSelectAll.unbind('click');
147 oSelectAll.click(this._selectAll);
149 /* Add a filtering function to the current table
150 * Note: we use closure to get access to the 'options'
152 $.fn.dataTableExt.afnFiltering.push(function( oSettings, aData, iDataIndex ) {
153 /* No filtering if the table does not match */
154 if (oSettings.nTable.id != self.options.plugin_uuid + '__table')
156 return self._querytable_filter.call(self, oSettings, aData, iDataIndex);
159 //alert(this.options.hidden_columns);
161 /* Processing hidden_columns */
162 $.each(this.options.hidden_columns, function(i, field) {
163 //manifold.raise_event(self.options.query_all_uuid, FIELD_REMOVED, field);
165 self.hide_column(field);
166 //self.hide_column(field);
169 }, // initialize_table
172 fnCancel:function(e){
173 //var sData=$("#uob_fv_table_form").find("input").serialize();
174 //alert("add flowspace:" + sData);
177 jQuery("#uob_ofv_table_form").hide();
178 jQuery( "#univbris_foam_ports_selection" ).hide();
179 jQuery( "#univbris_flowspace_selection" ).show();
180 jQuery('#topo_plugin').hide();
181 /*var port_table=$("#univbris_foam_ports_selection__table").dataTable();
182 var nodes = $('input',port_table.fnGetNodes());
183 for(var i=0;i<nodes.length;i++){
184 nodes[i].checked=false;
185 console.log(nodes[i].id);
191 fnAddflowspace:function(e){
194 pk_flowspace_index=1+pk_flowspace_index;
195 jQuery("#uob_fv_table_form").hide();
196 var sData=$("#uob_fv_table_form").find("input").serialize();
197 var form =serializeAnything("#uob_fv_table_form");
199 //var form2=serializeAnything("#uob_form");
201 var port_table=$("#univbris_foam_ports_selection__table").dataTable();
202 var form2=$('input',port_table.fnGetNodes()).serialize();
203 //console.log(form2);
204 //alert($('input',port_table.fnGetNodes()).serialize());
205 var nodes = $('input',port_table.fnGetNodes());
206 //console.log(nodes[1]);
207 //console.log(nodes);
208 //alert($("#uob_form").serialize());
209 //var pos = form.search("&urn");
210 //form2=form2.substring(pos+1);
212 //console.log(form2);
213 this.table = $("#univbris_flowspace_selection__table").dataTable();
215 var val_status=validateFvfForm();
217 if (val_status == true){
219 var m_form=form+","+form2;
220 var string = "<p id='"+m_form+"'> <a onclick=\'fnPopTable(\""+form+"\",\""+form2+"\");'>"+$("#flowspace_name").val()+"</a></p>";
221 this.table.fnAddData([string, '<a class="edit">Edit</a>', '<a class="delete" href="">Delete</a>']);
222 jQuery( "#univbris_foam_ports_selection" ).hide();
223 jQuery( "#univbris_flowspace_selection" ).show();
224 jQuery('#topo_plugin').hide();
227 alert("validation failed");
228 jQuery("#uob_ofv_table_form").show();
229 jQuery( "#univbris_foam_ports_selection" ).show();
233 jQuery("#uob_fv_table_form").hide();
234 var sData=$("#uob_fv_table_form").find("input").serialize();
235 var form =serializeAnything("#uob_fv_table_form");
236 //var form2=serializeAnything("#uob_form");
238 var port_table=$("#univbris_foam_ports_selection__table").dataTable();
239 var form2=$('input',port_table.fnGetNodes()).serialize();
240 this.table = $("#univbris_flowspace_selection__table").dataTable();
242 var m_form=form+","+form2;
243 var string = "<p id='"+m_form+"'> <a onclick=\'fnPopTable(\""+form+"\",\""+form2+"\");'>"+$("#flowspace_name").val()+"</a></p>";
244 this.table.fnDeleteRow(fvf_nrow);
245 this.table.fnAddData([string, '<a class="edit">Edit</a>', '<a class="delete" href="">Delete</a>']);
247 jQuery( "#univbris_foam_ports_selection" ).hide();
248 jQuery( "#univbris_flowspace_selection" ).show();
249 jQuery('#topo_plugin').hide();
256 * @brief Determine index of key in the table columns
260 getColIndex: function(key, cols) {
261 var tabIndex = $.map(cols, function(x, i) { if (x.sTitle == key) return i; });
262 return (tabIndex.length > 0) ? tabIndex[0] : -1;
265 // create a checkbox <input> tag
266 // computes 'id' attribute from canonical_key
267 // computes 'init_id' from init_key for initialization phase
268 // no need to used convoluted ids with plugin-uuid or others, since
269 // we search using table.$ which looks only in this table
270 checkbox_html : function (record) {
272 // Prefix id with plugin_uuid
274 result += " class='univbrisfvfo-checkbox'";
275 // compute id from canonical_key
276 var id = record[this.canonical_key]
277 // compute init_id form init_key
278 var init_id=record[this.init_key];
279 // set id - for retrieving from an id, or for posting events upon user's clicks
280 result += " id='"+record[this.canonical_key]+"'";
282 result += "init_id='" + init_id + "'";
284 result += " type='checkbox'";
285 result += " autocomplete='off'";
286 result += "></input>";
290 fake_checkbox_html : function (record) {
291 //alert("fake fun called");
293 // Prefix id with plugin_uuid
295 //result += " class='univbrisfvfo-checkbox'";
296 // set id - for retrieving from an id, or for posting events upon user's clicks
297 result += " id='"+ record +"'";
298 result += " name='"+ record +"'";
300 result += " init_id='" + record + "'";
302 result += " type='checkbox'";
303 result += " autocomplete='off'";
304 result += "></input>";
310 new_record: function(record)
313 // this models a line in dataTables, each element in the line describes a cell
316 // go through table headers to get column names we want
317 // in order (we have temporarily hack some adjustments in names)
318 var cols = this.table.fnSettings().aoColumns;
319 var colnames = cols.map(function(x) {return x.sTitle})
320 var nb_col = cols.length;
321 /* if we've requested checkboxes, then forget about the checkbox column for now */
322 if (this.options.checkboxes) nb_col -= 1;
325 /*replace production*/
326 /* fill in stuff depending on the column name */
327 var cols = this.table.fnSettings().aoColumns;
328 //alert("col "+cols);
329 var colnames = cols.map(function(x) {return x.sTitle})
330 var nb_col = cols.length;
331 //alert("nb_col: "+ nb_col);
332 /* if we've requested checkboxes, then forget about the checkbox column for now */
333 if (this.options.checkboxes) nb_col -= 1;
334 //alert("nb_col: "+ nb_col);
336 /*replace production*/
337 /* fill in stuff depending on the column name */
338 for (var j = 0; j < nb_col; j++) {
339 if (typeof colnames[j] == 'undefined') {
341 } else if (colnames[j] == 'Flowspace Selector') {
348 // catch up with the last column if checkboxes were requested
349 if (this.options.checkboxes) {
350 // Use a key instead of hostname (hard coded...)
351 line.push(this.checkbox_html(record));
354 // adding an array in one call is *much* more efficient
355 // this.table.fnAddData(line);
356 this.buffered_lines.push(line);
357 this.table.fnAddData(this.buffered_lines);
358 //this.table.redraw();
359 //this._querytable_draw_callback();
362 clear_table: function()
364 this.table.fnClearTable();
367 redraw_table: function()
372 show_column: function(field)
374 var oSettings = this.table.fnSettings();
375 var cols = oSettings.aoColumns;
376 var index = this.getColIndex(field,cols);
378 this.table.fnSetColumnVis(index, true);
381 hide_column: function(field)
383 var oSettings = this.table.fnSettings();
384 var cols = oSettings.aoColumns;
385 var index = this.getColIndex(field,cols);
387 //alert(field + ": index: " + index );
389 //alert(field + ": hidden with index: " + index );
390 this.table.fnSetColumnVis(index, false);
393 // this is used at init-time, at which point only init_key can make sense
394 // (because the argument record, if it comes from query, might not have canonical_key set
395 set_checkbox_from_record: function (record, checked) {
396 if (checked === undefined) checked = true;
397 var init_id = record[this.init_key];
398 if (debug) messages.debug("univbrisfvfo.set_checkbox_from_record, init_id="+init_id);
399 // using table.$ to search inside elements that are not visible
400 var element = this.table.$('[init_id="'+init_id+'"]');
401 element.attr('checked',checked);
404 // id relates to canonical_key
405 set_checkbox_from_data: function (id, checked) {
406 if (checked === undefined) checked = true;
407 if (debug) messages.debug("univbrisfvfo.set_checkbox_from_data, id="+id);
408 // using table.$ to search inside elements that are not visible
409 var element = this.table.$("[id='"+id+"']");
410 element.attr('checked',checked);
413 /*************************** QUERY HANDLER ****************************/
415 on_filter_added: function(filter)
417 this.filters.push(filter);
421 on_filter_removed: function(filter)
423 // Remove corresponding filters
424 this.filters = $.grep(this.filters, function(x) {
430 on_filter_clear: function()
436 on_field_added: function(field)
438 this.show_column(field);
441 on_field_removed: function(field)
443 this.hide_column(field);
446 on_field_clear: function()
448 alert('UnivbrisFvfo::clear_fields() not implemented');
451 /* XXX TODO: make this generic a plugin has to subscribe to a set of Queries to avoid duplicated code ! */
452 /*************************** ALL QUERY HANDLER ****************************/
454 on_all_filter_added: function(filter)
460 on_all_filter_removed: function(filter)
466 on_all_filter_clear: function()
472 on_all_field_added: function(field)
474 this.show_column(field);
477 on_all_field_removed: function(field)
479 this.hide_column(field);
482 on_all_field_clear: function()
484 alert('UnivbrisFvfo::clear_fields() not implemented');
488 /*************************** RECORD HANDLER ***************************/
490 on_new_record: function(record)
492 if (this.received_all_query) {
493 // if the 'all' query has been dealt with already we may turn on the checkbox
494 this.set_checkbox_from_record(record, true);
496 this.buffered_records_to_check.push(record);
500 on_clear_records: function()
504 // Could be the default in parent
505 on_query_in_progress: function()
510 on_query_done: function()
512 this.received_query = true;
513 // unspin once we have received both
514 if (this.received_all_query && this.received_query) this.unspin();
517 on_field_state_changed: function(data)
519 switch(data.request) {
520 case FIELD_REQUEST_ADD:
521 case FIELD_REQUEST_ADD_RESET:
522 this.set_checkbox_from_data(data.value, true);
524 case FIELD_REQUEST_REMOVE:
525 case FIELD_REQUEST_REMOVE_RESET:
526 this.set_checkbox_from_data(data.value, false);
533 /* XXX TODO: make this generic a plugin has to subscribe to a set of Queries to avoid duplicated code ! */
535 on_all_field_state_changed: function(data)
537 switch(data.request) {
538 case FIELD_REQUEST_ADD:
539 case FIELD_REQUEST_ADD_RESET:
540 this.set_checkboxfrom_data(data.value, true);
542 case FIELD_REQUEST_REMOVE:
543 case FIELD_REQUEST_REMOVE_RESET:
544 this.set_checkbox_from_data(data.value, false);
551 on_all_new_record: function(record)
553 this.new_record(record);
556 on_all_clear_records: function()
562 on_all_query_in_progress: function()
566 }, // on_all_query_in_progress
568 on_all_query_done: function()
570 if (debug) messages.debug("1-shot initializing dataTables content with " + this.buffered_lines.length + " lines");
571 this.table.fnAddData (this.buffered_lines);
572 this.buffered_lines=[];
575 // if we've already received the slice query, we have not been able to set
576 // checkboxes on the fly at that time (dom not yet created)
577 $.each(this.buffered_records_to_check, function(i, record) {
578 if (debug) messages.debug ("querytable delayed turning on checkbox " + i + " record= " + record);
579 self.set_checkbox_from_record(record, true);
581 this.buffered_records_to_check = [];
583 this.received_all_query = true;
584 // unspin once we have received both
585 if (this.received_all_query && this.received_query) this.unspin();
587 }, // on_all_query_done
589 /************************** PRIVATE METHODS ***************************/
592 * @brief QueryTable filtering function
594 _querytable_filter: function(oSettings, aData, iDataIndex)
597 $.each (this.filters, function(index, filter) {
598 /* XXX How to manage checkbox ? */
601 var value = filter[2];
603 /* Determine index of key in the table columns */
604 var col = $.map(oSettings.aoColumns, function(x, i) {if (x.sTitle == key) return i;})[0];
606 /* Unknown key: no filtering */
607 if (typeof(col) == 'undefined')
610 col_value=unfold.get_value(aData[col]);
611 /* Test whether current filter is compatible with the column */
612 if (op == '=' || op == '==') {
613 if ( col_value != value || col_value==null || col_value=="" || col_value=="n/a")
615 }else if (op == '!=') {
616 if ( col_value == value || col_value==null || col_value=="" || col_value=="n/a")
619 if ( parseFloat(col_value) >= value || col_value==null || col_value=="" || col_value=="n/a")
622 if ( parseFloat(col_value) <= value || col_value==null || col_value=="" || col_value=="n/a")
624 } else if(op=='<=' || op=='≤') {
625 if ( parseFloat(col_value) > value || col_value==null || col_value=="" || col_value=="n/a")
627 } else if(op=='>=' || op=='≥') {
628 if ( parseFloat(col_value) < value || col_value==null || col_value=="" || col_value=="n/a")
631 // How to break out of a loop ?
632 alert("filter not supported");
640 _querytable_draw_callback: function()
643 * Handle clicks on checkboxes: reassociate checkbox click every time
644 * the table is redrawn
646 this.elts('querytable-checkbox').unbind('click').click(this, this._check_click);
647 //alert("fvf_add: "+fvf_add);
649 $("#addflowspaceform").unbind('click').click(this, this.fnAddflowspace);
652 $("[id='addflowspaceform']").unbind('click').click(this, this.fnModflowspace);
654 $("#cancel_addflowspaceform").unbind('click').click(this,this.fnCancel);
659 /* Remove pagination if we show only a few results */
660 var wrapper = this.table; //.parent().parent().parent();
661 var rowsPerPage = this.table.fnSettings()._iDisplayLength;
662 var rowsToShow = this.table.fnSettings().fnRecordsDisplay();
663 var minRowsPerPage = this.table.fnSettings().aLengthMenu[0];
665 if ( rowsToShow <= rowsPerPage || rowsPerPage == -1 ) {
666 $('.querytable_paginate', wrapper).css('visibility', 'hidden');
668 $('.querytable_paginate', wrapper).css('visibility', 'visible');
671 if ( rowsToShow <= minRowsPerPage ) {
672 $('.querytable_length', wrapper).css('visibility', 'hidden');
674 $('.querytable_length', wrapper).css('visibility', 'visible');
681 _check_click: function(e)
688 // this.id = key of object to be added... what about multiple keys ?
689 if (debug) messages.debug("querytable._check_click key="+this.canonical_key+"->"+id+" checked="+this.checked);
690 //manifold.raise_event(self.options.query_uuid, this.checked?SET_ADD:SET_REMOVED, id);
691 //return false; // prevent checkbox to be checked, waiting response from manifold plugin api
695 _selectAll: function()
697 // requires jQuery id
698 var uuid=this.id.split("-");
699 var oTable=$("#querytable-"+uuid[1]).dataTable();
700 // Function available in QueryTable 1.9.x
701 // Filter : displayed data only
702 var filterData = oTable._('tr', {"filter":"applied"});
703 /* TODO: WARNING if too many nodes selected, use filters to reduce nuber of nodes */
704 if(filterData.length<=100){
705 $.each(filterData, function(index, obj) {
706 var last=$(obj).last();
707 var key_value=unfold.get_value(last[0]);
708 if(typeof($(last[0]).attr('checked'))=="undefined"){
709 $.publish('selected', 'add/'+key_value);
717 $.plugin('UnivbrisFvfo', UnivbrisFvfo);
719 /* define the 'dom-checkbox' type for sorting in datatables
720 http://datatables.net/examples/plug-ins/dom_sort.html
721 using trial and error I found that the actual column number
722 was in fact given as a third argument, and not second
723 as the various online resources had it - go figure */
724 $.fn.dataTableExt.afnSortData['dom-checkbox'] = function ( oSettings, _, iColumn ) {
725 return $.map( oSettings.oApi._fnGetTrNodes(oSettings), function (tr, i) {
726 return result=$('td:eq('+iColumn+') input', tr).prop('checked') ? '1' : '0';
734 function deserializeDT(d){
740 $currentSavedValue = null,
743 keyValPairString = [],
744 keyValPairObject = {},
748 if (data.constructor === String) {
751 data = decodeURIComponent(data.replace(/\+/g, " "));
753 keyValPairString = data.split('&');
755 for (i = 0; i < keyValPairString.length; i++) {
756 tmp = keyValPairString[i].split('=');
757 keyValPairObject[tmp[0]] = tmp[1];
762 var port_table=$("#univbris_foam_ports_selection__table").dataTable();
763 var nodes = $('input',port_table.fnGetNodes());
766 for(i=0;i<nodes.length;i++){
767 $currentSavedValue = keyValPairObject[nodes[i].id];
768 if ($currentSavedValue === undefined){
769 nodes[i].checked=false;
772 nodes[i].checked=true;
785 function fnPopTable(form1,form2){
787 $("[id='addflowspaceform']").hide();
788 $("#uob_fv_table_form :input").prop("disabled", false);
789 $("#uob_fv_table_form").deserialize(form1);
790 deserializeDT(form2);
793 $("[name='flowspace_name']").prop("disabled", true);
794 $("#uob_fv_table_form :input").prop("disabled", true);
795 $("[id='cancel_addflowspaceform']").prop("disabled", false);
796 $("[id='cancel_addflowspaceform']").text('close');
798 var port_table=$("#univbris_foam_ports_selection__table").dataTable();
799 var nodes = $('input',port_table.fnGetNodes());
800 for(var i=0;i<nodes.length;i++){
801 nodes[i].disabled=true;
804 jQuery("#univbris_flowspace_selection").hide();
805 jQuery("#uob_fv_table_form").show();
806 jQuery( "#univbris_foam_ports_selection" ).show();
808 if ($("#flowspace_name").val().search("pk")==0){
809 topoviewer_state={mode:"read",link_type:"non-optical"};
812 topoviewer_state={mode:"read",link_type:"optical"};
815 jQuery('#topo_plugin').show();
818 function macValidator (mac_str){
820 var mac_validator=/(^(([0-9a-fA-F]{2}[:-]){5}([0-9a-fA-F]{2}))$)|(^(([0-9a-fA-F]{2}[:-]){5}([0-9a-fA-F]{2})))$/;
821 var result =mac_str.match(mac_validator);
834 function ethertypeValidator (eth_str){
836 var ethertype_validator=/^0x[0-9a-fA-F]{4}$/;
837 var result = eth_str.match(ethertype_validator);
851 function vlanValidator (vlan_str){
853 var vlan_validator=/(^[1-9][0-9]{0,2}|[1-3][0-9]{3}|40[0-8][0-9]|409[0-5]$)/;
854 var result = vlan_str.match(vlan_validator);
867 function ipValidator(ip_str){
869 var ip_validator=/(^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$)/;
870 var result = ip_str.match(ip_validator);
884 function portValidator (port_str){
886 var port_validator=/^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/;
887 var result = port_str.match(port_validator);
900 function ipProtoValidator (ipproto_str){
901 if (ipproto_str != ""){
902 var ipproto_validator=/(^[0-9]{1,2}|1[0-9]{2}|2[0-4][0-9]|25[0-5]$)/;
903 var result = ipproto_str.match(ipproto_validator);
922 function validateFvfForm(){
927 if (macValidator ($("#uob_fv_table_dl_src_start").val())==false){
928 $("#uob_fv_table_dl_src_start").addClass('error');
929 $("#uob_fv_table_dl_src_error").show();
935 if (macValidator ($("#uob_fv_table_dl_src_end").val())==false){
936 $("#uob_fv_table_dl_src_end").addClass('error');
937 $("#uob_fv_table_dl_src_error").show();
945 if (macValidator ($("#uob_fv_table_dl_dst_start").val())==false){
946 $("#uob_fv_table_dl_dst_start").addClass('error');
947 $("#uob_fv_table_dl_dst_error").show();
953 if (macValidator ($("#uob_fv_table_dl_dst_end").val())==false){
954 $("#uob_fv_table_dl_dst_end").addClass('error');
955 $("#uob_fv_table_dl_dst_error").show();
963 if (ethertypeValidator ($("#uob_fv_table_dl_type_start").val())==false){
964 $("#uob_fv_table_dl_type_start").addClass('error');
965 $("#uob_fv_table_dl_type_error").show();
971 if (ethertypeValidator ($("#uob_fv_table_dl_type_end").val())==false){
972 $("#uob_fv_table_dl_type_end").addClass('error');
973 $("#uob_fv_table_dl_type_error").show();
981 if (vlanValidator ($("#uob_fv_table_vlan_id_start").val())==false){
982 $("#uob_fv_table_vlan_id_start").addClass('error');
983 $("#uob_fv_table_vlan_id_error").show();
989 if (vlanValidator ($("#uob_fv_table_vlan_id_end").val())==false){
990 $("#uob_fv_table_vlan_id_end").addClass('error');
991 $("#uob_fv_table_vlan_id_error").show();
998 if (ipValidator ($("#uob_fv_table_nw_src_start").val())==false){
999 $("#uob_fv_table_nw_src_start").addClass('error');
1000 $("#uob_fv_table_nw_src_error").show();
1006 if (ipValidator ($("#uob_fv_table_nw_src_end").val())==false){
1007 $("#uob_fv_table_nw_src_end").addClass('error');
1008 $("#uob_fv_table_nw_src_error").show();
1015 if (ipValidator ($("#uob_fv_table_nw_dst_start").val())==false){
1016 $("#uob_fv_table_nw_dst_start").addClass('error');
1017 $("#uob_fv_table_nw_dst_error").show();
1023 if (ipValidator ($("#uob_fv_table_nw_dst_end").val())==false){
1024 $("#uob_fv_table_nw_dst_end").addClass('error');
1025 $("#uob_fv_table_nw_dst_error").show();
1035 if (ipProtoValidator ($("#uob_fv_table_nw_proto_start").val())==false){
1036 $("#uob_fv_table_nw_proto_start").addClass('error');
1037 $("#uob_fv_table_nw_proto_error").show();
1043 if (ipProtoValidator ($("#uob_fv_table_nw_proto_end").val())==false){
1044 $("#uob_fv_table_nw_proto_end").addClass('error');
1045 $("#uob_fv_table_nw_proto_error").show();
1052 if (portValidator ($("#uob_fv_table_tp_src_start").val())==false){
1053 $("#uob_fv_table_tp_src_start").addClass('error');
1054 $("#uob_fv_table_tp_src_error").show();
1060 if (portValidator ($("#uob_fv_table_tp_src_end").val())==false){
1061 $("#uob_fv_table_tp_src_end").addClass('error');
1062 $("#uob_fv_table_tp_src_error").show();
1069 if (portValidator ($("#uob_fv_table_tp_dst_start").val())==false){
1070 $("#uob_fv_table_tp_dst_start").addClass('error');
1071 $("#uob_fv_table_tp_dst_error").show();
1077 if (portValidator ($("#uob_fv_table_tp_dst_end").val())==false){
1078 $("#uob_fv_table_tp_dst_end").addClass('error');
1079 $("#uob_fv_table_tp_dst_error").show();
1085 //validate that at least one port is selected
1086 var port_table=$("#univbris_foam_ports_selection__table").dataTable();
1087 var nodes = $('input',port_table.fnGetNodes());
1089 var port_selected=false;
1090 for(var i=0;i<nodes.length;i++){
1091 if(nodes[i].checked==true){
1098 if (checked >= 19) {
1102 if (port_selected==false & checked == 18){
1103 alert("you need to select at least one port");
1105 else if (port_selected==false & checked <= 18){
1106 alert("you need to select at least one port and correct other flowspace parameter errors");
1108 else if (port_selected==true & checked <= 18){
1109 alert("you need to correct other flowspace parameter errors");
1112 //alert("validator status:"+status+" checked:"+checked);
1118 function fnGetSelected( oTableLocal )
1120 var aReturn = new Array();
1121 var aTrs = oTableLocal.fnGetNodes();
1123 for ( var i=0 ; i<aTrs.length ; i++ )
1125 if ( $(aTrs[i]).hasClass('row_selected') )
1127 aReturn.push( aTrs[i] );
1133 function serializeAnything (form){
1135 var els = $(form).find(':input').get();
1137 $.each(els, function() {
1138 if (this.name && (this.checked || /select|textarea/i.test(this.nodeName) || /text|hidden|password/i.test(this.type))) {
1139 var val = $(this).val();
1140 toReturn.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( val ) );
1144 return toReturn.join("&").replace(/%20/g, "+");
1147 function hideFvfError(){
1148 $("[id*=_error]").hide();
1150 $("#uob_fv_table_form :input").each(function(){
1152 $(this).removeClass('error');
1163 deserialize : function (d, config) {
1167 $currentSavedValue = null,
1170 keyValPairString = [],
1171 keyValPairObject = {},
1175 if (d === undefined || !$self.is('form')) {
1183 config = $.extend(defaults, config);
1185 if (d.constructor === String) {
1188 d = decodeURIComponent(d.replace(/\+/g, " "));
1190 keyValPairString = d.split('&');
1192 for (i = 0; i < keyValPairString.length; i++) {
1193 tmp = keyValPairString[i].split('=');
1194 keyValPairObject[tmp[0]] = tmp[1];
1199 $('input, select, textarea', $self).each(function (i) {
1202 currentDom = $current.get(0);
1203 $currentSavedValue = keyValPairObject[$current.attr('name')];
1205 if (currentDom.disabled === true) {
1206 //current.val($currentSavedValue);
1210 if ($current.is('textarea')) {
1211 if ($currentSavedValue === undefined) {
1214 $current.val($currentSavedValue);
1219 if ($current.is('select')) {
1220 if ($currentSavedValue === undefined) {
1223 currentDom.selectedIndex = $currentSavedValue;
1228 if ($current.is('input:radio')) {
1229 if ($currentSavedValue !== undefined) {
1231 $current.each(function () {
1232 if ($(this).val() === $currentSavedValue) {
1233 $(this).get(0).checked = true;
1241 if ($current.is('input:checkbox')) {
1242 currentDom.checked = ($current.val() === $currentSavedValue);
1246 if ($current.is('input:text, input:hidden')) {
1247 if ($currentSavedValue === undefined) {
1250 $current.val($currentSavedValue);