remove commented code for hazelnut's old 'update_plugin'
[unfold.git] / plugins / hazelnut / static / js / hazelnut.js
index d26f0ea..316c3f8 100644 (file)
@@ -7,7 +7,6 @@
 (function($){
 
     // TEMP
-    var ELEMENT_KEY = 'resource_hrn';
     var debug=false;
     debug=true
 
             this.in_set_buffer = Array();
 
             /* XXX Events XXX */
-            this.$element.on('show.Datatables', this.on_show);
+            // this.$element.on('show.Datatables', this.on_show);
+            this.elmt().on('show', this, this.on_show);
             // Unbind all events using namespacing
             // TODO in destructor
             // $(window).unbind('Hazelnut');
 
+            var query = manifold.query_store.find_analyzed_query(this.options.query_uuid);
+            this.method = query.object;
+
+            var keys = manifold.metadata.get_key(this.method);
+            this.key = (keys && keys.length == 1) ? keys[0] : null;
+
             /* Setup query and record handlers */
             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();
         },
 
         /* PLUGIN EVENTS */
 
-        on_show: function()
+        on_show: function(e)
         {
-            // XXX
-            var $this=$(this);
-            // xxx wtf. why [1] ? would expect 0...
-            if (debug)
-                messages.debug("Hitting suspicious line in hazelnut.show");
-            var oTable = $($('.dataTable', $this)[1]).dataTable();
-            oTable.fnAdjustColumnSizing()
+            var self = e.data;
+
+            self.table.fnAdjustColumnSizing()
         
             /* Refresh dataTabeles if click on the menu to display it : fix dataTables 1.9.x Bug */        
+            /* temp disabled... useful ? -- jordan
             $(this).each(function(i,elt) {
                 if (jQuery(elt).hasClass('dataTables')) {
                     var myDiv=jQuery('#hazelnut-' + this.id).parent();
                     }
                 }
             });
+            */
         }, // on_show
 
         /* GUI EVENTS */
 
         /* GUI MANIPULATION */
 
-        initialize_table: function() {
+        initialize_table: function() 
+        {
             /* Transforms the table into DataTable, and keep a pointer to it */
             var self = this;
             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',
+                sDom: "<'row'<'col-md-5'l><'col-md-1'r><'col-md-6'f>>t<'row'<'col-md-5'i><'col-md-7'p>>",
+               // XXX as of sept. 2013, I cannot locate a bootstrap3-friendly mode for now
+               // hopefully this would come with dataTables v1.10 ?
+               // in any case, search for 'sPaginationType' all over the code for more comments
+                sPaginationType: 'full_numbers',
                 // 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' ]}],
@@ -88,7 +99,7 @@
             };
             // 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 = this.el('table').dataTable(actual_options);
+            this.table = this.elmt('table').dataTable(actual_options);
 
             /* Setup the SelectAll button in the dataTable header */
             /* xxx not sure this is still working */
             return (tabIndex.length > 0) ? tabIndex[0] : -1;
         }, // getColIndex
 
- // UNUSED ? //         this.update_plugin = function(e, rows) {
- // UNUSED ? //             // e.data is what we passed in second argument to subscribe
- // UNUSED ? //             // so here it is the jquery object attached to the plugin <div>
- // UNUSED ? //             var $plugindiv=e.data;
- // UNUSED ? //             if (debug)
- // UNUSED ? //                 messages.debug("entering hazelnut.update_plugin on id '" + $plugindiv.attr('id') + "'");
- // UNUSED ? //             // clear the spinning wheel: look up an ancestor that has the need-spin class
- // UNUSED ? //             // do this before we might return
- // UNUSED ? //             $plugindiv.closest('.need-spin').spin(false);
- // UNUSED ? // 
- // UNUSED ? //             var options = this.options;
- // UNUSED ? //             var hazelnut = this;
- // UNUSED ? //     
- // UNUSED ? //             /* if we get no result, or an error, try to make that clear, and exit */
- // UNUSED ? //             if (rows.length==0) {
- // UNUSED ? //                 if (debug) 
- // UNUSED ? //                     messages.debug("Empty result on hazelnut " + this.options.domid);
- // UNUSED ? //                 var placeholder=$(this.table).find("td.dataTables_empty");
- // UNUSED ? //                 console.log("placeholder "+placeholder);
- // UNUSED ? //                 if (placeholder.length==1) 
- // UNUSED ? //                     placeholder.html(unfold.warning("Empty result"));
- // UNUSED ? //                 else
- // UNUSED ? //                     this.table.html(unfold.warning("Empty result"));
- // UNUSED ? //                     return;
- // UNUSED ? //             } else if (typeof(rows[0].error) != 'undefined') {
- // UNUSED ? //                 // we now should have another means to report errors that this inline/embedded hack
- // UNUSED ? //                 if (debug) 
- // UNUSED ? //                     messages.error ("undefined result on " + this.options.domid + " - should not happen anymore");
- // UNUSED ? //                 this.table.html(unfold.error(rows[0].error));
- // UNUSED ? //                 return;
- // UNUSED ? //             }
- // UNUSED ? // 
- // UNUSED ? //             /* 
- // UNUSED ? //              * fill the dataTables object
- // UNUSED ? //              * we cannot set html content directly here, need to use fnAddData
- // UNUSED ? //              */
- // UNUSED ? //             var lines = new Array();
- // UNUSED ? //     
- // UNUSED ? //             this.current_resources = Array();
- // UNUSED ? //     
- // UNUSED ? //             $.each(rows, function(index, row) {
- // UNUSED ? //                 // this models a line in dataTables, each element in the line describes a cell
- // UNUSED ? //                 line = new Array();
- // UNUSED ? //      
- // UNUSED ? //                 // go through table headers to get column names we want
- // UNUSED ? //                 // in order (we have temporarily hack some adjustments in names)
- // UNUSED ? //                 var cols = object.table.fnSettings().aoColumns;
- // UNUSED ? //                 var colnames = cols.map(function(x) {return x.sTitle})
- // UNUSED ? //                 var nb_col = cols.length;
- // UNUSED ? //                 /* if we've requested checkboxes, then forget about the checkbox column for now */
- // UNUSED ? //                 if (options.checkboxes) nb_col -= 1;
- // UNUSED ? // 
- // UNUSED ? //                 /* fill in stuff depending on the column name */
- // UNUSED ? //                 for (var j = 0; j < nb_col; j++) {
- // UNUSED ? //                     if (typeof colnames[j] == 'undefined') {
- // UNUSED ? //                         line.push('...');
- // UNUSED ? //                     } else if (colnames[j] == 'hostname') {
- // UNUSED ? //                         if (row['type'] == 'resource,link')
- // UNUSED ? //                             //TODO: we need to add source/destination for links
- // UNUSED ? //                             line.push('');
- // UNUSED ? //                         else
- // UNUSED ? //                             line.push(row['hostname']);
- // UNUSED ? //                     } else {
- // UNUSED ? //                         if (row[colnames[j]])
- // UNUSED ? //                             line.push(row[colnames[j]]);
- // UNUSED ? //                         else
- // UNUSED ? //                             line.push('');
- // UNUSED ? //                     }
- // UNUSED ? //                 }
- // UNUSED ? //     
- // UNUSED ? //                 /* catch up with the last column if checkboxes were requested */
- // UNUSED ? //                 if (options.checkboxes) {
- // UNUSED ? //                     var checked = '';
- // UNUSED ? //                     // xxx problem is, we don't get this 'sliver' thing set apparently
- // UNUSED ? //                     if (typeof(row['sliver']) != 'undefined') { /* It is equal to null when <sliver/> is present */
- // UNUSED ? //                         checked = 'checked ';
- // UNUSED ? //                         hazelnut.current_resources.push(row[ELEMENT_KEY]);
- // UNUSED ? //                     }
- // UNUSED ? //                     // Use a key instead of hostname (hard coded...)
- // UNUSED ? //                     line.push(hazelnut.checkbox(options.plugin_uuid, row[ELEMENT_KEY], row['type'], checked, false));
- // UNUSED ? //                 }
- // UNUSED ? //     
- // UNUSED ? //                 lines.push(line);
- // UNUSED ? //     
- // UNUSED ? //             });
- // UNUSED ? //     
- // UNUSED ? //             this.table.fnClearTable();
- // UNUSED ? //             if (debug)
- // UNUSED ? //                 messages.debug("hazelnut.update_plugin: total of " + lines.length + " rows");
- // UNUSED ? //             this.table.fnAddData(lines);
- // UNUSED ? //         
- // UNUSED ? //         }, // update_plugin
-
-        checkbox: function (plugin_uuid, header, field, selected_str, disabled_str)
+        checkbox: function (key, value)
         {
             var result="";
-            if (header === null)
-                header = '';
             // Prefix id with plugin_uuid
             result += "<input";
-            result += " class='hazelnut-checkbox-" + plugin_uuid + "'";
-            result += " id='hazelnut-checkbox-" + plugin_uuid + "-" + unfold.get_value(header).replace(/\\/g, '')  + "'";
-            result += " name='" + unfold.get_value(field) + "'";
+            result += " class='hazelnut-checkbox'";
+            result += " id='" + this.id('checkbox', this.id_from_key(key, value)) + "'";
+            result += " name='" + key + "'";
             result += " type='checkbox'";
-            result += selected_str;
-            result += disabled_str;
             result += " autocomplete='off'";
-            result += " value='" + unfold.get_value(header) + "'";
+            result += " value='" + value + "'";
             result += "></input>";
             return result;
         }, // checkbox
             }
     
             /* catch up with the last column if checkboxes were requested */
-            if (this.options.checkboxes) {
-                var checked = '';
-                // xxx problem is, we don't get this 'sliver' thing set apparently
-                if (typeof(record['sliver']) != 'undefined') { /* It is equal to null when <sliver/> is present */
-                    checked = 'checked ';
-                    hazelnut.current_resources.push(record[ELEMENT_KEY]);
-                }
+            if (this.options.checkboxes)
                 // Use a key instead of hostname (hard coded...)
-                line.push(this.checkbox(this.options.plugin_uuid, record[ELEMENT_KEY], record['type'], checked, false));
-            }
+                // XXX remove the empty checked attribute
+                line.push(this.checkbox(this.key, record[this.key]));
     
             // XXX Is adding an array of lines more efficient ?
-            this.table.fnAddData(line);
+//            this.table.fnAddData(line);
+           this.buffered_lines.push(line)
 
         },
 
                 this.table.fnSetColumnVis(index, false);
         },
 
-        set_checkbox: function(record)
+        set_checkbox: function(record, checked)
         {
-            // XXX urn should be replaced by the key
-            // XXX we should enforce that both queries have the same key !!
-            checkbox_id = "#hazelnut-checkbox-" + this.options.plugin_uuid + "-" + unfold.escape_id(record[ELEMENT_KEY].replace(/\\/g, ''))
-            $(checkbox_id, this.table.fnGetNodes()).attr('checked', true);
+            /* Default: checked = true */
+            if (typeof checked === 'undefined')
+                checked = true;
+
+            var key_value;
+            /* The function accepts both records and their key */
+            switch (manifold.get_type(record)) {
+                case TYPE_VALUE:
+                    key_value = record;
+                    break;
+                case TYPE_RECORD:
+                    /* XXX Test the key before ? */
+                    key_value = record[this.key];
+                    break;
+                default:
+                    throw "Not implemented";
+                    break;
+            }
+
+
+            var checkbox_id = this.id('checkbox', this.id_from_key(this.key, key_value));
+            checkbox_id = '#' + checkbox_id.replace(/\./g, '\\.');
+
+            var element = $(checkbox_id, this.table.fnGetNodes());
+
+            element.attr('checked', checked);
         },
 
         /*************************** QUERY HANDLER ****************************/
             alert('Hazelnut::clear_fields() not implemented');
         },
 
-        /* RECORD HANDLERS */
+        /*************************** RECORD HANDLER ***************************/
 
         on_new_record: function(record)
         {
             /* NOTE in fact we are doing a join here */
             if (this.received_all)
                 // update checkbox for record
-                this.set_checkbox(record);
+                this.set_checkbox(record, true);
             else
                 // store for later update of checkboxes
                 this.in_set_buffer.push(record);
                 this.unspin();
             this.received_set = true;
         },
+        
+        on_field_state_changed: function(data)
+        {
+            switch(data.request) {
+                case FIELD_REQUEST_ADD:
+                case FIELD_REQUEST_ADD_RESET:
+                    this.set_checkbox(data.value, true);
+                    break;
+                case FIELD_REQUEST_REMOVE:
+                case FIELD_REQUEST_REMOVE_RESET:
+                    this.set_checkbox(data.value, false);
+                    break;
+                default:
+                    break;
+            }
+        },
 
         // all
 
 
                 /* ... and check the ones specified in the resource list */
                 $.each(this.in_set_buffer, function(i, record) {
-                    self.set_checkbox(record);
+                    self.set_checkbox(record, true);
                 });
 
                 this.unspin();
             }
+           this.table.fnAddData (this.buffered_lines);
+           this.buffered_lines=[];
             this.received_all = true;
 
         }, // on_all_query_done
              * Handle clicks on checkboxes: reassociate checkbox click every time
              * the table is redrawn 
              */
-            $('.hazelnut-checkbox-' + this.options.plugin_uuid).unbind('click');
-            $('.hazelnut-checkbox-' + this.options.plugin_uuid).click({instance: this}, this._check_click);
+            this.elts('hazelnut-checkbox').unbind('click').click(this, this._check_click);
 
             if (!this.table)
                 return;
 
         _check_click: function(e) 
         {
+            e.stopPropagation();
 
-            var self = e.data.instance;
+            var self = e.data;
 
             // XXX this.value = key of object to be added... what about multiple keys ?
             manifold.raise_event(self.options.query_uuid, this.checked?SET_ADD:SET_REMOVED, this.value);
+            //return false; // prevent checkbox to be checked, waiting response from manifold plugin api
             
         },