plugins: supporting columns adding/removing + passed query instead of uuid as parameters
authorJordan Augé <jordan.auge@lip6.fr>
Wed, 7 Aug 2013 16:07:20 +0000 (18:07 +0200)
committerJordan Augé <jordan.auge@lip6.fr>
Wed, 7 Aug 2013 16:07:20 +0000 (18:07 +0200)
13 files changed:
manifold/js/manifold-query.js
manifold/js/manifold.js
plugins/googlemap/googlemap.js
plugins/googlemap/googlemap.py
plugins/hazelnut/hazelnut.html
plugins/hazelnut/hazelnut.js
plugins/hazelnut/hazelnut.py
plugins/pres_view/pres_view.js
plugins/query_editor/__init__.py
plugins/query_editor/query_editor.html
plugins/query_editor/query_editor.js
plugins/resources_selected/resources_selected.js
trash/sliceview.py

index 77925c4..1dcd56c 100644 (file)
@@ -117,6 +117,16 @@ INSERT INTO object VALUES(field=value)
         rec(query, callback, data, null);
     }
 
+    this.select = function(field)
+    {
+        this.fields.push(field);
+    }
+
+    this.unselect = function(field)
+    {   
+        this.fields = $.grep(this.fields, function(x) { return x != field; });
+    }
+
 // we send queries as a json string now 
 //    this.as_POST = function() {
 //        return {'action': this.action, 'object': this.object, 'timestamp': this.timestamp,
index 89c83d1..ef492f7 100644 (file)
@@ -56,9 +56,9 @@ function QueryExt(query, parent_query, main_query) {
     /* Constructor */
     if (typeof query == "undefined")
         throw "Must pass a query in QueryExt constructor";
-    this.query        = query
-    this.parent_query = (typeof parent_query == "undefined") ? false : parent_query
-    this.main_query   = (typeof main_query   == "undefined") ? false : main_query
+    this.query            = query
+    this.parent_query_ext = (typeof parent_query == "undefined") ? false : parent_query
+    this.main_query_ext   = (typeof main_query   == "undefined") ? false : main_query
     
     this.status       = null;
     this.results      = null;
@@ -82,11 +82,14 @@ function QueryStore() {
         manifold.query_store.main_queries[query.query_uuid] = query_ext;
 
         // We also need to insert all queries and subqueries from the analyzed_query
+        // XXX We need the root of all subqueries
         query.iter_subqueries(function(sq, data, parent_query) {
             if (parent_query)
                 parent_query_ext = manifold.query_store.find_analyzed_query_ext(parent_query.query_uuid);
             else
                 parent_query_ext = null;
+            // XXX parent_query_ext == false
+            // XXX main.subqueries = {} # Normal, we need analyzed_query
             sq_ext = new QueryExt(sq, parent_query_ext, query_ext)
             manifold.query_store.analyzed_queries[sq.query_uuid] = sq_ext;
         });
@@ -394,17 +397,18 @@ var manifold = {
 
     raise_event: function(query_uuid, event_type, value)
     {
+        // Query uuid has been updated with the key of a new element
+        query_ext    = manifold.query_store.find_analyzed_query_ext(query_uuid);
+        query = query_ext.query;
+
         switch(event_type) {
             case SET_ADD:
-                // Query uuid has been updated with the key of a new element
-                query_ext    = manifold.query_store.find_analyzed_query(query_uuid);
-
                 // update is only possible is the query is not pending, etc
                 // CHECK status !
 
                 // XXX we can only update subqueries of the main query. Check !
                 // assert query_ext.parent_query == query_ext.main_query
-                update_query = query_ext.parent_query.update_query;
+                update_query = query_ext.parent_query_ext.update_query;
 
                 // NOTE: update might modify the fields in Get
                 // NOTE : we have to modify all child queries
@@ -419,7 +423,45 @@ var manifold = {
             case SET_REMOVED:
                 // Query uuid has been updated with the key of a removed element
                 break;
+            case FILTER_ADDED:
+                break;
+            case FILTER_REMOVED:
+                break;
+            case FIELD_ADDED:
+                main_query = query_ext.main_query_ext.query;
+                main_update_query = query_ext.main_query_ext.update_query;
+                query.select(value);
+
+                // Here we need the full path through all subqueries
+                path = ""
+                // XXX We might need the query name in the QueryExt structure
+                main_query.select(value);
+
+                // XXX When is an update query associated ?
+                // XXX main_update_query.select(value);
+
+                // We need to inform about changes in these queries to the respective plugins
+                // Note: query, main_query & update_query have the same UUID
+                manifold.raise_query_event(query_uuid, event_type, value);
+                // We are targeting the same object with get and update
+                // The notion of query is bad, we should have a notion of destination, and issue queries on the destination
+                // NOTE: Editing a subquery == editing a local view on the destination
+                break;
+
+            case FIELD_REMOVED:
+                query = query_ext.query;
+                main_query = query_ext.main_query_ext.query;
+                main_update_query = query_ext.main_query_ext.update_query;
+                query.unselect(value);
+                main_query.unselect(value);
+
+                // We need to inform about changes in these queries to the respective plugins
+                // Note: query & main_query have the same UUID
+                manifold.raise_query_event(query_uuid, event_type, value);
+                break;
         }
+        // XXX We might need to run the new query again and manage the plugins in the meantime with spinners...
+        // For the time being, we will collect all columns during the first query
     },
 
     /* Publish/subscribe channels for internal use */
index 69db6ef..9963abf 100644 (file)
                 // Fields
                 /* Hide/unhide columns to match added/removed fields */
                 case FIELD_ADDED:
-                    var object = this;
-                    $.each(added_fields, function (index, field) {            
-                        var index = object.getColIndex(field,cols);
-                        if(index != -1)
-                            object.table.fnSetColumnVis(index, true);
-                    });
                     break;
                 case FIELD_REMOVED:
-                    var object = this;
-                    $.each(removed_fields, function (index, field) {
-                        var index = object.getColIndex(field,cols);
-                        if(index != -1)
-                            object.table.fnSetColumnVis(index, false);
-                    });            
                     break;
                 case CLEAR_FIELDS:
                     alert('GoogleMaps::clear_fields() not implemented');
index 59c7eb6..bce84f5 100644 (file)
@@ -6,10 +6,11 @@ class GoogleMap (Plugin):
     # pass columns as the initial set of columns
     #   if None then this is taken from the query's fields
     # latitude,longitude, zoom : the starting point
-    def __init__ (self, query, query_all_uuid = None, latitude=43., longitude=7., zoom=4, **settings):
+    def __init__ (self, query, query_all = None, latitude=43., longitude=7., zoom=4, **settings):
         Plugin.__init__ (self, **settings)
         self.query=query
-        self.query_all_uuid = query_all_uuid
+        self.query_all = query_all
+        self.query_all_uuid = query_all.query_uuid if query_all else None
         self.latitude=latitude
         self.longitude=longitude
         self.zoom=zoom
index 84f2e18..aae78e4 100644 (file)
@@ -1,13 +1,33 @@
 <div id='main-{{ domid }}'>
-<table class='table table-striped table-bordered dataTable' id='hazelnut-{{ domid }}'>
-<thead><tr> {% for column in columns %}
-<th>{{ column }}</th>{% endfor %} {% if checkboxes %}<th>+/-</th>{% endif %}
-</tr></thead> 
-<tbody>
-</tbody>
-<tfoot><tr> {% for column in columns %}
-<th>{{ column }}</th>{% endfor %} {% if checkboxes %}<th>+/-</th>{% endif %}
-</tr></tfoot> 
-</table>
+  <table class='table table-striped table-bordered dataTable' id='hazelnut-{{ domid }}'>
+    <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> 
+    <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>
+    </tfoot> 
+  </table>
 </div>
 <div class="hazelnut-spacer"></div>
index f685ced..8cbc537 100644 (file)
@@ -53,16 +53,16 @@ var ELEMENT_KEY = 'resource_hrn';
                 var $this = $(this);
 
                 /* An object that will hold private variables and methods */
-                var hazelnut = new Hazelnut (options);
-                $this.data('Hazelnut', hazelnut);
+                var plugin = new Hazelnut (options);
+                $this.data('Hazelnut', plugin);
 
                 /* Events */
                 $this.on('show.Datatables', methods.show);
 
                 // This is the new plugin API meant to replace the weird publish_subscribe mechanism
-                $this.set_query_handler(options.query_uuid, hazelnut.query_handler);
-                $this.set_record_handler(options.query_uuid, hazelnut.record_handler); 
-                $this.set_record_handler(options.query_all_uuid, hazelnut.record_handler_all); 
+                $this.set_query_handler(options.query_uuid, plugin.query_handler);
+                $this.set_record_handler(options.query_uuid, plugin.record_handler); 
+                $this.set_record_handler(options.query_all_uuid, plugin.record_handler_all); 
 
 //                /* Subscriptions */
 //                var query_channel   = '/query/' + options.query_uuid + '/changed';
@@ -146,45 +146,52 @@ var ELEMENT_KEY = 'resource_hrn';
 
         var object = this;
 
-        /* Transforms the table into DataTable, and keep a pointer to it */
-        actual_options = {
-            // Customize the position of Datatables elements (length,filter,button,...)
-            // we use a fluid row on top and another on the bottom, making sure we take 12 grid elt's each time
-            sDom: "<'row-fluid'<'span5'l><'span1'r><'span6'f>>t<'row-fluid'<'span5'i><'span7'p>>",
-            sPaginationType: 'bootstrap',
-            // Handle the null values & the error : Datatables warning Requested unknown parameter
-            // http://datatables.net/forums/discussion/5331/datatables-warning-...-requested-unknown-parameter/p2
-            aoColumnDefs: [{sDefaultContent: '',aTargets: [ '_all' ]}],
-            // WARNING: this one causes tables in a 'tabs' that are not exposed at the time this is run to show up empty
-            // sScrollX: '100%',       /* Horizontal scrolling */
-            bProcessing: true,      /* Loading */
-            fnDrawCallback: function() { hazelnut_draw_callback.call(object, options); }
-        };
-        // 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 );
-        this.table = $('#hazelnut-' + options.plugin_uuid).dataTable(actual_options);
-
-        /* Setup the SelectAll button in the dataTable header */
-        /* xxx not sure this is still working */
-        var oSelectAll = $('#datatableSelectAll-'+ options.plugin_uuid);
-        oSelectAll.html("<span class='ui-icon ui-icon-check' style='float:right;display:inline-block;'></span>Select All");
-        oSelectAll.button();
-        oSelectAll.css('font-size','11px');
-        oSelectAll.css('float','right');
-        oSelectAll.css('margin-right','15px');
-        oSelectAll.css('margin-bottom','5px');
-        oSelectAll.unbind('click');
-        oSelectAll.click(selectAll);
-
-        /* Add a filtering function to the current table 
-         * Note: we use closure to get access to the 'options'
-         */
-        $.fn.dataTableExt.afnFiltering.push(function( oSettings, aData, iDataIndex ) { 
-            /* No filtering if the table does not match */
-            if (oSettings.nTable.id != "hazelnut-" + options.plugin_uuid)
-                return true;
-            return hazelnut_filter.call(object, oSettings, aData, iDataIndex);
-        });
+        this.initialize = function() {
+            /* Transforms the table into DataTable, and keep a pointer to it */
+            actual_options = {
+                // Customize the position of Datatables elements (length,filter,button,...)
+                // we use a fluid row on top and another on the bottom, making sure we take 12 grid elt's each time
+                sDom: "<'row-fluid'<'span5'l><'span1'r><'span6'f>>t<'row-fluid'<'span5'i><'span7'p>>",
+                sPaginationType: 'bootstrap',
+                // Handle the null values & the error : Datatables warning Requested unknown parameter
+                // http://datatables.net/forums/discussion/5331/datatables-warning-...-requested-unknown-parameter/p2
+                aoColumnDefs: [{sDefaultContent: '',aTargets: [ '_all' ]}],
+                // WARNING: this one causes tables in a 'tabs' that are not exposed at the time this is run to show up empty
+                // sScrollX: '100%',       /* Horizontal scrolling */
+                bProcessing: true,      /* Loading */
+                fnDrawCallback: function() { hazelnut_draw_callback.call(object, options); }
+            };
+            // 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 );
+            this.table = $('#hazelnut-' + options.plugin_uuid).dataTable(actual_options);
+
+            /* Setup the SelectAll button in the dataTable header */
+            /* xxx not sure this is still working */
+            var oSelectAll = $('#datatableSelectAll-'+ options.plugin_uuid);
+            oSelectAll.html("<span class='ui-icon ui-icon-check' style='float:right;display:inline-block;'></span>Select All");
+            oSelectAll.button();
+            oSelectAll.css('font-size','11px');
+            oSelectAll.css('float','right');
+            oSelectAll.css('margin-right','15px');
+            oSelectAll.css('margin-bottom','5px');
+            oSelectAll.unbind('click');
+            oSelectAll.click(selectAll);
+
+            /* Add a filtering function to the current table 
+             * Note: we use closure to get access to the 'options'
+             */
+            $.fn.dataTableExt.afnFiltering.push(function( oSettings, aData, iDataIndex ) { 
+                /* No filtering if the table does not match */
+                if (oSettings.nTable.id != "hazelnut-" + options.plugin_uuid)
+                    return true;
+                return hazelnut_filter.call(object, oSettings, aData, iDataIndex);
+            });
+
+            /* Processing hidden_columns */
+            $.each(options.hidden_columns, function(i, field) {
+                object.hide_column(field);
+            });
+        }
 
         /* methods */
 
@@ -527,7 +534,25 @@ var ELEMENT_KEY = 'resource_hrn';
             }
         };
 
-        this.query_handler = function(e, event_type, query)
+        this.show_column = function(field)
+        {
+            var oSettings = object.table.fnSettings();
+            var cols = oSettings.aoColumns;
+            var index = object.getColIndex(field,cols);
+            if (index != -1)
+                object.table.fnSetColumnVis(index, true);
+        }
+
+        this.hide_column = function(field)
+        {
+            var oSettings = object.table.fnSettings();
+            var cols = oSettings.aoColumns;
+            var index = object.getColIndex(field,cols);
+            if (index != -1)
+                object.table.fnSetColumnVis(index, false);
+        }
+
+        this.query_handler = function(e, event_type, data)
         {
             // This replaces the complex set_query function
             // The plugin does not need to remember the query anymore
@@ -544,20 +569,10 @@ var ELEMENT_KEY = 'resource_hrn';
                 // Fields
                 /* Hide/unhide columns to match added/removed fields */
                 case FIELD_ADDED:
-                    var object = this;
-                    $.each(added_fields, function (index, field) {            
-                        var index = object.getColIndex(field,cols);
-                        if(index != -1)
-                            object.table.fnSetColumnVis(index, true);
-                    });
+                    object.show_column(data);
                     break;
                 case FIELD_REMOVED:
-                    var object = this;
-                    $.each(removed_fields, function (index, field) {
-                        var index = object.getColIndex(field,cols);
-                        if(index != -1)
-                            object.table.fnSetColumnVis(index, false);
-                    });            
+                    object.hide_column(data);
                     break;
                 case CLEAR_FIELDS:
                     alert('Hazelnut::clear_fields() not implemented');
@@ -566,6 +581,10 @@ var ELEMENT_KEY = 'resource_hrn';
 
 
         }
+
+        // Constructor
+        object.initialize();
+
     } // constructor
 
     /***************************************************************************
index a54cde7..9509dc0 100644 (file)
@@ -5,17 +5,27 @@ 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
-    def __init__ (self, query=None, query_all_uuid=None, checkboxes=False, columns=None, datatables_options={}, **settings):
+    def __init__ (self, query=None, query_all=None, checkboxes=False, columns=None, datatables_options={}, **settings):
         Plugin.__init__ (self, **settings)
         self.query          = query
-        self.query_all_uuid = query_all_uuid
+        # Until we have a proper way to access queries in Python
+        self.query_all      = query_all
+        self.query_all_uuid = query_all.query_uuid if query_all else None
         self.checkboxes=checkboxes
+        # XXX We need to have some hidden columns until we properly handle dynamic queries
         if columns is not None:
             self.columns=columns
+            self.hidden_columns = []
         elif self.query:
-            self.columns=self.query.fields
+            self.columns = self.query.fields
+            if query_all:
+                # We need a list because sets are not JSON-serilizable
+                self.hidden_columns = list(self.query_all.fields - self.query.fields)
+            else:
+                self.hidden_columns = []
         else:
             self.columns = []
+            self.hidden_columns = []
         self.datatables_options=datatables_options
 
     def template_file (self):
@@ -43,4 +53,4 @@ class Hazelnut (Plugin):
 
     # the list of things passed to the js plugin
     def json_settings_list (self):
-        return ['plugin_uuid', 'domid', 'query_uuid', 'query_all_uuid', 'checkboxes','datatables_options']
+        return ['plugin_uuid', 'domid', 'query_uuid', 'query_all_uuid', 'checkboxes', 'datatables_options', 'hidden_columns']
index c5ff26c..bd49c1c 100644 (file)
 
             return this.each(function() {
                 var $this = $(this);
-                var hazelnut = $this.data('Manifold');
+                var plugin = $this.data('Manifold');
 
                 // Unbind all events using namespacing
                 $(window).unbind(PLUGIN_NAME);
 
                 // Remove associated data
-                hazelnut.remove();
+                plugin.remove();
                 $this.removeData('Manifold');
             });
         }, // destroy
index f5a334e..e46a033 100644 (file)
@@ -30,7 +30,6 @@ class QueryEditor(Plugin):
         fields = []
         metadata = self.page.get_metadata()
         md_fields = metadata.details_by_object('resource')
-        print "METADATA FIELDS", md_fields
 
         # XXX use django templating system here
         for md_field in md_fields['column']:
@@ -64,5 +63,6 @@ class QueryEditor(Plugin):
                 'resource_type': 'N/A',
                 'filter_input':  filter_input,
                 'header':        None,
+                'checked':       md_field['name'] in self.query.get_select()
             })
         return { 'fields': fields }
index b822959..6cd3ff2 100644 (file)
@@ -29,7 +29,7 @@ EOF; -->
         <td class='center'> {{ field.type }}</td>
         <td class='center'> {{ field.filter_input }}</td>
         <td class='center'>
-          <input class='queryeditor-check' id='check_{{ field.name }}' name='{{ field.header }}' type='checkbox' autocomplete='off' value='{{ field.header}}'></input>
+          <input class='queryeditor-check' id='check_{{ field.name }}' name='{{ field.header }}' type='checkbox' autocomplete='off' value='{{ field.name }}' {% if field.checked %} checked {% endif %}></input>
         </td>
       </tr>
                
index 3bc3d8b..7514b4a 100644 (file)
@@ -47,6 +47,9 @@
                 var plugin = new QueryEditor(options);
                 $this.data('Manifold', plugin);
 
+                $this.set_query_handler(options.query_uuid, plugin.query_handler);
+                $this.set_record_handler(options.query_uuid, plugin.record_handler); 
+
             }); // this.each
         }, // init
 
             });
 
             jQuery('.queryeditor-check').click(function() { 
-                manifold.raise_event(object.options.query_uuid, this.checked?SET_ADD:SET_REMOVED, this.value);
+                manifold.raise_event(object.options.query_uuid, this.checked?FIELD_ADDED:FIELD_REMOVED, this.value);
                 /*
                     var column = this.id.substring(6);
                     query = data.current_query;
             // elements in set
             switch(event_type) {
                 case NEW_RECORD:
-                    /* NOTE in fact we are doing a join here */
-                    if (object.received_all)
-                        // update checkbox for record
-                        object.set_checkbox(record);
-                    else
-                        // store for later update of checkboxes
-                        object.in_set_buffer.push(record);
                     break;
                 case CLEAR_RECORDS:
-                    // nothing to do here
                     break;
                 case IN_PROGRESS:
-                    manifold.spin($(this));
                     break;
                 case DONE:
-                    if (object.received_all)
-                        manifold.spin($(this), false);
-                    object.received_set = true;
                     break;
             }
         };
 
                 // Fields
                 /* Hide/unhide columns to match added/removed fields */
+                // XXX WRONG IDENTIFIERS
                 case FIELD_ADDED:
-                    $('#check_' + data).attr('checked', true);
+                    object.check(data);
                     break;
                 case FIELD_REMOVED:
-                    $('#check_' + data).attr('checked', false);
+                    object.uncheck(data);
                     break;
                 case CLEAR_FIELDS:
                     alert(PLUGIN_NAME + '::clear_fields() not implemented');
             } // switch
 
 
+        }
+        this.check = function(field)
+        {
+            $('#check_' + field).attr('checked', true);
+        }
+        this.uncheck = function(field)
+        {
+            $('#check_' + field).attr('checked', false);
         }
         this.fnFormatDetails  = function( metaTable, nTr, div_id ) {
             var aData = metaTable.fnGetData( nTr );
index ad2e5fd..e00cda5 100644 (file)
@@ -16,6 +16,8 @@
  */
 (function( $ ){
 
+    var PLUGIN_NAME = 'ResourcesSelected';
+
     // Routing calls
     jQuery.fn.ResourcesSelected = function( method ) {
         if ( methods[method] ) {
@@ -23,7 +25,7 @@
         } else if ( typeof method === 'object' || ! method ) {
             return methods.init.apply( this, arguments );
         } else {
-            jQuery.error( 'Method ' +  method + ' does not exist on jQuery.ResourcesSelected' );
+            jQuery.error( 'Method ' +  method + ' does not exist on jQuery.' + PLUGIN_NAME );
         }    
 
     };
                 var $this = $(this);
 
                 /* An object that will hold private variables and methods */
-                var s = new ResourcesSelected(options);
-                $(this).data('ResourcesSelected', s);
-                var RESULTS_RESOURCES = '/results/' + options.resource_query_uuid + '/changed';
-                var UPDATE_RESOURCES  = '/update-set/' + options.resource_query_uuid;
-                                 
-                $.subscribe(RESULTS_RESOURCES, function(e, resources) { s.set_resources(resources);    });
-                $.subscribe(UPDATE_RESOURCES,  function(e, resources, change) { s.update_resources(resources, change); });
+                var plugin = new ResourcesSelected(options);
+                $(this).data('Manifold', plugin);
+
+                //$this.set_query_handler(options.query_uuid, hazelnut.query_handler);
+                //$this.set_record_handler(options.query_uuid, hazelnut.record_handler); 
+
+                //var RESULTS_RESOURCES = '/results/' + options.resource_query_uuid + '/changed';
+                //var UPDATE_RESOURCES  = '/update-set/' + options.resource_query_uuid;
+                //$.subscribe(RESULTS_RESOURCES, function(e, resources) { s.set_resources(resources);    });
+                //$.subscribe(UPDATE_RESOURCES,  function(e, resources, change) { s.update_resources(resources, change); });
                 
             }); // this.each
         }, // init
          */
         destroy : function( ) {
 
-            return this.each(function(){
-                var $this = jQuery(this), data = $this.data('ResourcesSelected');
-                jQuery(window).unbind('ResourcesSelected');
-                data.ResourcesSelected.remove();
-                $this.removeData('ResourcesSelected');
-            })
+            return this.each(function() {
+                var $this = $(this);
+                var plugin = $this.data('Manifold');
 
+                // Remove associated data
+                plugin.remove();
+                $this.removeData('Manifold');
+            });
         }, // destroy
 
     }; // var methods
 
     /***************************************************************************
-     * ResourcesSelected object
+     * Plugin object
      ***************************************************************************/
 
     function ResourcesSelected(options)
@@ -86,6 +92,8 @@
 
         this.options = options;
 
+        var object = this;
+
         /* The resources that are in the slice */
         this.current_resources = null;
 
                 jQuery('.ResourceSelectedClose').unbind('click');
                 /* Handle clicks on close span */
                 /* Reassociate close click every time the table is redrawn */
-                $('.ResourceSelectedClose').bind('click',{instance: rs}, close_click);
+                $('.ResourceSelectedClose').bind('click',{instance: rs}, object.close_click);
             }
          });
 
 
         } // update_resources
 
+        this.record_handler = function(e, event_type, record)
+        {
+            // elements in set
+            switch(event_type) {
+                case NEW_RECORD:
+                    /* NOTE in fact we are doing a join here */
+                    if (object.received_all)
+                        // update checkbox for record
+                        object.set_checkbox(record);
+                    else
+                        // store for later update of checkboxes
+                        object.in_set_buffer.push(record);
+                    break;
+                case CLEAR_RECORDS:
+                    // nothing to do here
+                    break;
+                case IN_PROGRESS:
+                    manifold.spin($(this));
+                    break;
+                case DONE:
+                    if (object.received_all)
+                        manifold.spin($(this), false);
+                    object.received_set = true;
+                    break;
+            }
+        };
+
+        this.record_handler_all = function(e, event_type, record)
+        {
+            // all elements
+            switch(event_type) {
+                case NEW_RECORD:
+                    // Add the record to the table
+                    object.new_record(record);
+                    break;
+                case CLEAR_RECORDS:
+                    object.table.fnClearTable();
+                    break;
+                case IN_PROGRESS:
+                    manifold.spin($(this));
+                    break;
+                case DONE:
+                    if (object.received_set) {
+                        /* XXX needed ? XXX We uncheck all checkboxes ... */
+                        $("[id^='datatables-checkbox-" + object.options.plugin_uuid +"']").attr('checked', false);
+
+                        /* ... and check the ones specified in the resource list */
+                        $.each(object.in_set_buffer, function(i, record) {
+                            object.set_checkbox(record);
+                        });
+
+                        manifold.spin($(this), false);
+                    }
+                    object.received_all = true;
+                    break;
+            }
+        };
+
+        this.query_handler = function(e, event_type, data)
+        {
+            // This replaces the complex set_query function
+            // The plugin does not need to remember the query anymore
+            switch(event_type) {
+                // Filters
+                case FILTER_ADDED:
+                case FILTER_REMOVED:
+                case CLEAR_FILTERS:
+                    // XXX Here we might need to maintain the list of filters !
+                    /* Process updates in filters / current_query must be updated before this call for filtering ! */
+                    object.table.fnDraw();
+                    break;
+
+                // Fields
+                /* Hide/unhide columns to match added/removed fields */
+                case FIELD_ADDED:
+                    var field = data;
+                    var oSettings = object.table.fnSettings();
+                    var cols = oSettings.aoColumns;
+                    var index = object.getColIndex(field,cols);
+                    if(index != -1)
+                        object.table.fnSetColumnVis(index, true);
+                    break;
+                case FIELD_REMOVED:
+                    var field = data;
+                    var oSettings = object.table.fnSettings();
+                    var cols = oSettings.aoColumns;
+                    var index = object.getColIndex(field,cols);
+                    if(index != -1)
+                        object.table.fnSetColumnVis(index, false);
+                    break;
+                case CLEAR_FIELDS:
+                    alert('Hazelnut::clear_fields() not implemented');
+                    break;
+            } // switch
+        }
+
     } // ResourcesSelected
 
 
index 94b539c..bed99df 100644 (file)
@@ -143,13 +143,13 @@ def _slice_view (request, slicename):
     )
 
     tab_resource_plugins.insert(Hazelnut( 
-        page           = page,
-        title          = 'List',
-        domid          = 'checkboxes',
+        page       = page,
+        title      = 'List',
+        domid      = 'checkboxes',
         # this is the query at the core of the slice list
-        query          = sq_resource,
-        query_all_uuid = query_resource_all.query_uuid,
-        checkboxes     = True,
+        query      = sq_resource,
+        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
@@ -160,18 +160,18 @@ def _slice_view (request, slicename):
     ))
 
     tab_resource_plugins.insert(GoogleMap(
-        page        = page,
-        title       = 'Geographic view',
-        domid       = 'gmap',
+        page       = page,
+        title      = 'Geographic view',
+        domid      = 'gmap',
         # tab's sons preferably turn this off
-        togglable   = False,
-        query       = sq_resource,
-        query_all_uuid = query_resource_all.query_uuid,
-        checkboxes     = True,
+        togglable  = False,
+        query      = sq_resource,
+        query_all  = query_resource_all,
+        checkboxes = True,
         # center on Paris
-        latitude    = 49.,
-        longitude   = 2.2,
-        zoom        = 3,
+        latitude   = 49.,
+        longitude  = 2.2,
+        zoom       = 3,
     ))
 
     stack_resources.insert(tab_resource_plugins)