Merge branch 'configfile' into checkboxes
authorThierry Parmentelat <thierry.parmentelat@inria.fr>
Tue, 1 Oct 2013 12:39:20 +0000 (14:39 +0200)
committerThierry Parmentelat <thierry.parmentelat@inria.fr>
Tue, 1 Oct 2013 12:39:20 +0000 (14:39 +0200)
plugins/googlemap/static/js/googlemap.js
plugins/hazelnut/__init__.py
plugins/hazelnut/static/js/hazelnut.js
plugins/hazelnut/templates/hazelnut.html
plugins/query_editor/static/js/query_editor.js
portal/platformview.py
portal/sliceview.py
unfold/static/js/unfold-helper.js

index 854ee4a..34b2b8d 100644 (file)
@@ -141,9 +141,9 @@ googlemap_debug_detailed=false;
        // retrieve DOM checkbox and make sure it is checked/unchecked
         set_checkbox: function(record, checked) {
            var hrn=this.record_hrn (record);
-           if (! hrn) { messages.warning ("set_checkbox: record has no hrn"); return; }
+           if (! hrn) { messages.warning ("googlemap.set_checkbox: record has no hrn"); return; }
            var checkbox_s = this.by_hrn [ hrn ];
-           if (! checkbox_s ) { messages.warning ("set_checkbox: could not spot checkbox for hrn "+hrn); return; }
+           if (! checkbox_s ) { messages.warning ("googlemap.set_checkbox: could not spot checkbox for hrn "+hrn); return; }
            checkbox_s.checkbox.prop('checked',checked);
         }, // set_checkbox
 
index e8ecfce..1fa9940 100644 (file)
@@ -5,6 +5,8 @@ class Hazelnut (Plugin):
     # set checkboxes if a final column with checkboxes is desired
     # pass columns as the initial set of columns
     #   if None then this is taken from the query's fields
+    # also please refrain from passing an 'aoColumns' as datatables_options
+    # as we use 'aoColumnDefs' instead
     def __init__ (self, query=None, query_all=None, 
                   checkboxes=False, columns=None, 
                   datatables_options={}, **settings):
@@ -21,7 +23,7 @@ class Hazelnut (Plugin):
         elif self.query:
             self.columns = self.query.fields
             if query_all:
-                # We need a list because sets are not JSON-serilizable
+                # We need a list because sets are not JSON-serializable
                 self.hidden_columns = list(self.query_all.fields - self.query.fields)
             else:
                 self.hidden_columns = []
@@ -29,6 +31,19 @@ class Hazelnut (Plugin):
             self.columns = []
             self.hidden_columns = []
         self.datatables_options=datatables_options
+        # if checkboxes were required, we tell datatables about this column's type
+        # so that sorting can take place on a selected-first basis (or -last of course)
+        # this relies on the template exposing the checkboxes 'th' with class 'checkbox'
+        if self.checkboxes:
+            # we use aoColumnDefs rather than aoColumns -- ignore user-provided aoColumns
+            if 'aoColumns' in self.datatables_options:
+                print 'WARNING: hazelnut uses aoColumnDefs, your aoColumns spec. is discarded'
+                del self.datatables_options['aoColumns']
+            # set aoColumnDefs in datatables_options - might already have stuff in there
+            aoColumnDefs = self.datatables_options.setdefault ('aoColumnDefs',[])
+            # here 'checkbox' is the class that we give to the <th> dom elem
+            # dom-checkbox is a sorting type that we define in hazelnut.js
+            aoColumnDefs.append ( {'aTargets': ['checkbox'], 'sSortDataType': 'dom-checkbox' } )
 
     def template_file (self):
         return "hazelnut.html"
@@ -41,17 +56,19 @@ class Hazelnut (Plugin):
 
     def requirements (self):
         reqs = {
-            'js_files' : [ "js/hazelnut.js", 
-                           "js/manifold.js", "js/manifold-query.js", 
+            'js_files' : [ "js/spin.presets.js", "js/spin.min.js", "js/jquery.spin.js", 
                            "js/dataTables.js", "js/dataTables.bootstrap.js", "js/with-datatables.js",
-                           "js/spin.presets.js", "js/spin.min.js", "js/jquery.spin.js", 
+                           "js/manifold.js", "js/manifold-query.js", 
                            "js/unfold-helper.js",
+                          # hazelnut.js needs to be loaded after dataTables.js as it extends 
+                          # dataTableExt.afnSortData
+                           "js/hazelnut.js", 
                            ] ,
-            'css_files': [ "css/hazelnut.css" , 
-                           "css/dataTables.bootstrap.css",
+            'css_files': [ "css/dataTables.bootstrap.css",
                            # hopefully temporary, when/if datatables supports sPaginationType=bootstrap3
                            # for now we use full_numbers\, with our own ad hoc css 
                            "css/dataTables.full_numbers.css",
+                           "css/hazelnut.css" , 
                            ],
             }
         return reqs
index 12ee398..9374cf5 100644 (file)
             this._super(options, element);
 
             /* Member variables */
-            // query status
-            this.received_all = false;
-            this.received_set = false;
-            this.in_set_buffer = Array();
+           // in general we expect 2 queries here
+           // query_uuid refers to a single object (typically a slice)
+           // query_all_uuid refers to a list (typically resources or users)
+           // these can return in any order so we keep track of which has been received yet
+            this.received_all_query = false;
+            this.received_query = false;
+
+            // an internal buffer for records that are 'in' and thus need to be checked 
+            this.buffered_records_to_check = [];
+           // an internal buffer for keeping lines and display them in one call to fnAddData
+           this.buffered_lines = [];
 
             /* XXX Events XXX */
             // this.$element.on('show.Datatables', this.on_show);
@@ -39,9 +46,6 @@
             this.listen_query(options.query_uuid);
             this.listen_query(options.query_all_uuid, 'all');
 
-           /* an internal buffer for keeping lines and display them in one call to fnAddData */
-           this.buffered_lines = [];
-
             /* GUI setup and event binding */
             this.initialize_table();
         },
                 // XXX use $.proxy here !
             };
             // the intention here is that options.datatables_options as coming from the python object take precedence
-            //  XXX DISABLED by jordan: was causing errors in datatables.js     $.extend(actual_options, options.datatables_options );
+           // xxx DISABLED by jordan: was causing errors in datatables.js
+           // xxx turned back on by Thierry - this is the code that takes python-provided options into account
+           // check your datatables_options tag instead 
+           $.extend(actual_options, this.options.datatables_options );
             this.table = this.elmt('table').dataTable(actual_options);
 
             /* Setup the SelectAll button in the dataTable header */
 
         on_new_record: function(record)
         {
-            /* NOTE in fact we are doing a join here */
-            if (this.received_all)
-                // update checkbox for record
+            if (this.received_all_query) {
+               // if the 'all' query has been dealt with already we may turn on the checkbox
                 this.set_checkbox(record, true);
-            else
-                // store for later update of checkboxes
-                this.in_set_buffer.push(record);
+           } else {
+               // otherwise we need to remember that and do it later on
+                this.buffered_records_to_check.push(record);
+               console.log ("Remembering record to check " + record);
+           }
         },
 
         on_clear_records: function()
 
         on_query_done: function()
         {
-            if (this.received_all)
+            if (this.received_all_query)
                 this.unspin();
-            this.received_set = true;
+            this.received_query = true;
         },
         
         on_field_state_changed: function(data)
         on_all_query_done: function()
         {
             var self = this;
-            if (this.received_set) {
+            if (this.received_query) {
                 /* XXX needed ? XXX We uncheck all checkboxes ... */
                 $("[id^='datatables-checkbox-" + this.options.plugin_uuid +"']").attr('checked', false);
 
                 /* ... and check the ones specified in the resource list */
-                $.each(this.in_set_buffer, function(i, record) {
+                $.each(this.buffered_records_to_check, function(i, record) {
                     self.set_checkbox(record, true);
                 });
 
             }
            this.table.fnAddData (this.buffered_lines);
            this.buffered_lines=[];
-            this.received_all = true;
+            this.received_all_query = true;
 
         }, // on_all_query_done
 
 
     $.plugin('Hazelnut', Hazelnut);
 
+  /* define the 'dom-checkbox' type for sorting in datatables 
+     http://datatables.net/examples/plug-ins/dom_sort.html
+     using trial and error I found that the actual column number
+     was in fact given as a third argument, and not second 
+     as the various online resources had it - go figure */
+    $.fn.dataTableExt.afnSortData['dom-checkbox'] = function  ( oSettings, _, iColumn ) {
+       return $.map( oSettings.oApi._fnGetTrNodes(oSettings), function (tr, i) {
+           return result=$('td:eq('+iColumn+') input', tr).prop('checked') ? '1' : '0';
+       } );
+    }
+
 })(jQuery);
+
index b49161b..a223d1b 100644 (file)
@@ -2,31 +2,19 @@
   <table class='table table-striped table-bordered dataTable' id='{{domid}}__table'>
     <thead>
       <tr>
-        {% for column in columns %}
-        <th>{{ column }}</th>
-        {% endfor %} 
-        {% for column in hidden_columns %}
-        <th>{{ column }}</th>
-        {% endfor %} 
-        {% if checkboxes %}
-               <th>+/-</th>
-               {% endif %}
-         </tr>
-       </thead> 
+        {% for column in columns %} <th>{{ column }}</th> {% endfor %} 
+        {% for column in hidden_columns %} <th>{{ column }}</th> {% endfor %} 
+        {% if checkboxes %} <th class="checkbox">+/-</th> {% endif %}
+      </tr>
+    </thead> 
     <tbody>
     </tbody>
     <tfoot>
       <tr>
-        {% for column in columns %}
-           <th>{{ column }}</th>
-        {% endfor %} 
-        {% for column in hidden_columns %}
-           <th>{{ column }}</th>
-        {% endfor %} 
-        {% if checkboxes %}
-               <th>+/-</th>
-               {% endif %}
-         </tr>
+        {% for column in columns %} <th>{{ column }}</th> {% endfor %} 
+        {% for column in hidden_columns %} <th>{{ column }}</th> {% endfor %} 
+        {% if checkboxes %} <th>+/-</th> {% endif %}
+      </tr>
     </tfoot> 
   </table>
 </div>
index 553dbc6..8b739f0 100644 (file)
@@ -40,7 +40,6 @@
 
         init: function(options, element) {
             this._super(options, element);
-            console.log("init Query_Editor");
             this.listen_query(options.query_uuid);
 
             this.elts('queryeditor-auto-filter').change(this.event_filter_added('='));
index 16148ee..76699cf 100644 (file)
@@ -35,9 +35,6 @@ class PlatformView(TemplateView):
             query_all = network_query,
             checkboxes = False,
             datatables_options = {
-            # for now we turn off sorting on the checkboxes columns this way
-            # this of course should be automatic in hazelnut
-            'aoColumns'      : [None, None, None, None, {'bSortable': False}],
             'iDisplayLength' : 25,
             'bLengthChange'  : True,
             },
index 74101f2..0e514dd 100644 (file)
@@ -136,9 +136,6 @@ class SliceView (LoginRequiredAutoLogoutView):
             query_all  = query_resource_all,
             checkboxes = True,
             datatables_options = { 
-                # for now we turn off sorting on the checkboxes columns this way
-                # this of course should be automatic in hazelnut
-                'aoColumns'     : [None, None, None, None, {'bSortable': False}],
                 'iDisplayLength': 25,
                 'bLengthChange' : True,
                 'bAutoWidth'    : True,
@@ -194,14 +191,14 @@ class SliceView (LoginRequiredAutoLogoutView):
                 outline_complete    = True,
                 togglable           = True,
                 title               = 'Users',
-                active_domid        = 'checkboxes2',
+                active_domid        = 'users-list',
                 )
             main_stack.insert(tab_users)
     
             tab_users.insert(Hazelnut( 
                 page        = page,
                 title       = 'Users List',
-                domid       = 'checkboxes2',
+                domid       = 'users-list',
                 # tab's sons preferably turn this off
                 togglable   = False,
                 # this is the query at the core of the slice list
@@ -219,7 +216,7 @@ class SliceView (LoginRequiredAutoLogoutView):
         # MEASUREMENTS
         tab_measurements = Tabs (
             page                = page,
-            active_domid        = 'checkboxes3',
+            active_domid        = 'measurements-list',
             outline_complete    = True,
             togglable           = True,
             title               = 'Measurements',
@@ -230,7 +227,7 @@ class SliceView (LoginRequiredAutoLogoutView):
         tab_measurements.insert(Hazelnut( 
             page        = page,
             title       = 'Measurements',
-            domid       = 'checkboxes3',
+            domid       = 'measurements-list',
             # tab's sons preferably turn this off
             togglable   = False,
             # this is the query at the core of the slice list
index 67524a1..f5adb1b 100644 (file)
@@ -37,7 +37,7 @@ var unfold = {
         if(typeof id != 'undefined'){
             return id.replace( /(:|\.|\[|\])/g, "\\$1" );
         }else{
-            return "fake-id";
+            return "undefined-id";
         }
     }