SliceList and TestbedList are specialized versions of SimpleList with related css
[myslice.git] / plugins / lists / static / js / simplelist.js
1 /**
2  * Description: display simple lists like slices or testbeds
3  * Copyright (c) 2012 UPMC Sorbonne Universite - INRIA
4  * License: GPLv3
5  */
6
7 (function($){
8
9     var debug=false;
10     debug=true
11
12     $.fn.SimpleList = function( method ) {
13         /* Method calling logic */
14         if ( methods[method] ) {
15             return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
16         } else if ( typeof method === 'object' || ! method ) {
17             return methods.init.apply( this, arguments );
18         } else {
19             $.error( 'Method ' +  method + ' does not exist on jQuery.SimpleList' );
20         }    
21     };
22
23     var methods = {
24         init : function( options ) {
25             return this.each(function(){
26                 var $this = $(this), data = $this.data('SimpleList');
27                 /* Subscribe to query updates */
28                 var channel='/results/' + options.query_uuid + '/changed';
29                 /* passing $this as 2nd arg: callbacks will retrieve $this as e.data */
30                 $.subscribe(channel, $this, update_plugin);
31                 if (debug) window.messages.debug('subscribing to ' + channel);
32                 $this.data('SimpleList', options);
33             });
34         },
35         destroy : function( ) {
36             if (debug) messages.debug("SimpleList.destroy...");
37             return this.each(function(){
38                 var $this = $(this), data = $this.data('SimpleList');
39                 // xxx not too sure what this is about
40                 $(window).unbind('SimpleList');
41                 $this.removeData('SimpleList');
42             });
43         },
44         update : function( content ) { 
45             if (debug) messages.debug("SimpleList.update...");
46         },
47     }; // methods
48
49     /* Private methods */
50     // complexity here is mostly because a datatables-enabled table cannot
51     // be updated in a "normal" way using .html()
52     function update_plugin(e, rows) {
53         // e.data is what we passed in second argument to subscribe
54         // so here it is the jquery object attached to the plugin <div>
55         var $plugindiv = e.data;
56         var options = $plugindiv.data().SimpleList;
57         var classname=options.classname;
58         // locate the <table> element; with datatables in the way,
59         // this might not be a direct son of the div-plugin
60         var $table = $plugindiv.find("table."+classname).first();
61         // also we may or may not have a header
62         var $tbody = $table.find("tbody."+classname).first();
63         var use_datatables = $table.hasClass("with-datatables");
64         if (debug) 
65             messages.debug($plugindiv.attr('id') + " udt= " + use_datatables + " rows="+rows.length);
66         
67         // clear the spinning wheel: look up an ancestor that has the need-spin class
68         // do this before we might return
69             $plugindiv.closest('.need-spin').spin(false);
70
71         if (rows.length == 0) {
72             if (use_datatables)
73                 datatables_set_message ($table, $tbody, unfold.warning("No result"));
74             else
75                 regular_set_message ($table, $tbody, unfold.warning("No result"));
76             return;
77         }
78
79         if (typeof rows[0].error != 'undefined') {
80             var error="ERROR: " + rows[0].error;
81             if (use_datatables) 
82                 datatables_set_message ($table, $tbody, unfold.error(error));
83             else
84                 regular_set_message ($table, $tbody, unfold.error(error));
85             return;
86         }
87
88         if (use_datatables)     
89             datatables_update_table($table, $tbody, rows, options.key);
90         else
91             regular_update_table($table, $tbody, rows, options.key, classname);
92
93     }
94
95     // hard-wire a separate presentation depending on the key being used....
96     function cell(key, value) {
97         if (key == 'slice.slice_hrn') {
98             return "<i class='icon-play-circle'></i><a href='/portal/slice/" + value + "'>" + value + "</a>";
99         } else if (key == 'platform') {
100             return "<i class='icon-play-circle'></i><a href='/portal/platform/" + value + "'>" + value + "</a>";
101         } else {
102             return value;
103         }
104     }
105
106     function regular_set_message ($table, $tbody, message) {
107         $tbody.html("<tr><td>"+message+"</td></tr>");
108     }
109
110     function regular_update_table ($table, $tbody, rows, key, classname) {
111         if (debug)
112             messages.debug('regular_update_table ' + rows.length + " rows" + " key=" + key + " classname=" + classname);
113         var html=$.map(rows, function (row) {
114             value = row;
115             $.each(key.split('.'), function(i, k) {
116                 if ($.isArray(value)) {
117                     value = $.map(value, function(val, i) { return val[k]});
118                 } else {
119                     value = value[k];
120                 }
121             });
122                 if ($.isArray(value)) {
123                 x = $.map(value, function(val, i) { 
124                     messages.debug("loop.loop val="+val+" i="+i);
125                     return html_row ( cell (key, val), classname); });
126                 return x;
127             } else {
128                 return html_row ( cell (key, value), classname);
129             }
130         }).join();
131         $tbody.html(html);
132     }
133     
134     function datatables_set_message ($table, $tbody, message) {
135         $table.dataTable().fnClearTable();
136         $table.dataTable().fnAddData( [ message ] );
137         $table.dataTable().fnDraw();
138     }
139
140     function datatables_update_table ($table, $tbody, rows, key) {
141         if (debug) messages.debug('datatables_update_table ' + rows.length + " rows");
142         $table.dataTable().fnClearTable();
143         // the lambda here returns a [[]] because $.map is kind of broken; as per the doc:
144         // The function can return any value to add to the array. A returned array will be flattened into the resulting array.
145         // this is wrong indeed so let's work around that
146         $table.dataTable().fnAddData( $.map(rows, function (row) { return [[ cell (key,row[key]) ]] }) );
147         $table.dataTable().fnDraw();
148     }   
149     
150     function html_row (cell, classname) { 
151         return "<tr><td class='"+classname+"'>"+cell+"</td></tr>"; 
152     }
153     
154 })( jQuery );