From e445cc0ae92f3927e7d29e9d271fea7f8dee05a6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jordan=20Aug=C3=A9?= Date: Thu, 8 Aug 2013 17:18:01 +0200 Subject: [PATCH] manifold: fix in plugin.js plugins: revamped query_editor to accept filter updates + fixes in active_filters --- manifold/js/plugin.js | 28 +- plugins/active_filters/active_filters.js | 8 +- plugins/query_editor/__init__.py | 25 +- .../query_editor/filter_input_integer.html | 4 +- plugins/query_editor/filter_input_others.html | 4 +- plugins/query_editor/filter_input_string.html | 4 +- .../filter_input_string_values.html | 7 +- plugins/query_editor/query_editor.html | 4 +- plugins/query_editor/query_editor.js | 264 ++++++++---------- 9 files changed, 187 insertions(+), 161 deletions(-) diff --git a/manifold/js/plugin.js b/manifold/js/plugin.js index 5d3df742..84ebbc4f 100644 --- a/manifold/js/plugin.js +++ b/manifold/js/plugin.js @@ -77,12 +77,14 @@ var Plugin = Class.extend({ }, listen_query: function(query_uuid, prefix) { - this.query_handler_prefix = (typeof prefix === 'undefined') ? '' : (prefix + '_'); + this.query_handler_prefix = (typeof prefix === 'undefined') ? '' : (prefix + manifold.separator); this.$element.on(manifold.get_query_channel(query_uuid), $.proxy(this._query_handler, this)); }, default_options: {}, + /* Helper functions for naming HTML elements (ID, classes), with support for filters and fields */ + id: function() { var ret = this.options.plugin_uuid; @@ -129,4 +131,28 @@ var Plugin = Class.extend({ return filter[0] + ' ' + filter[1] + ' ' + filter[2]; }, + array_from_id: function(id) + { + var ret = id.split(manifold.separator); + ret.shift(); // remove plugin_uuid at the beginning + return ret; + }, + + id_from_field: function(field) + { + return 'field' + manifold.separator + field; + }, + + field_from_id: function(id) + { + var array; + if (typeof id === 'string') { + array = id.split(manifold.separator); + } else { // We suppose we have an array ('object') + array = id; + } + // array = ['field', FIELD_NAME] + return array[1]; + }, + }); diff --git a/plugins/active_filters/active_filters.js b/plugins/active_filters/active_filters.js index fe619247..89ebef28 100644 --- a/plugins/active_filters/active_filters.js +++ b/plugins/active_filters/active_filters.js @@ -50,12 +50,12 @@ show_clear_button: function() { this.el('clearFilters').show(); - } + }, hide_clear_button: function() { this.el('clearFilters').hide(); - } + }, check_and_hide_clear_button: function() { @@ -64,7 +64,7 @@ if (count == 1) { // Including the template this.el('clearFilters').hide(); } - } + }, clear_filters: function() { @@ -92,7 +92,7 @@ this.show_clear_button(); }, - remove_filter = function(filter) + remove_filter: function(filter) { this.el(this.id_from_filter(filter, false)).remove(); this.check_and_hide_clear_button(); diff --git a/plugins/query_editor/__init__.py b/plugins/query_editor/__init__.py index e46a0334..98e7f9fc 100644 --- a/plugins/query_editor/__init__.py +++ b/plugins/query_editor/__init__.py @@ -2,6 +2,8 @@ from unfold.plugin import Plugin from django.template.loader import render_to_string +# XXX We need naming helpers in the python Plugin class also, used in template + class QueryEditor(Plugin): def template_file(self): @@ -10,6 +12,7 @@ class QueryEditor(Plugin): def requirements (self): reqs = { 'js_files' : [ + # XXX datatables 'js/query_editor.js', ] , 'css_files': [ @@ -43,18 +46,32 @@ class QueryEditor(Plugin): v_desc = v.split('-') options.append(v_desc[0]) - env = {'options': options} + env = { + 'domid': self.domid, + 'options': options + } filter_input = render_to_string('filter_input_string_values.html', env) else: - env = {'filter_id': "%s-filter-%s" % (self.domid, md_field['name'])} + env = { + 'domid': self.domid, + 'field': md_field['name'] + } filter_input = render_to_string('filter_input_string.html', env) elif md_field['type'] == 'int': allowed_values = md_field.get('allowed_values', '0,0').split(',') - env = {'min': allowed_values[0], 'max': allowed_values[1]} + env = { + 'domid': self.domid, + 'field': md_field['name'], + 'min' : allowed_values[0], + 'max' : allowed_values[1] + } filter_input = render_to_string('filter_input_integer.html', env) else: - env = {'filter_id': "%s-filter-%s" % (self.domid, md_field['name'])} + env = { + 'domid': self.domid, + 'field': md_field['name'] + } filter_input = render_to_string('filter_input_others.html', env) fields.append({ diff --git a/plugins/query_editor/filter_input_integer.html b/plugins/query_editor/filter_input_integer.html index ab80a649..bf1a70cf 100644 --- a/plugins/query_editor/filter_input_integer.html +++ b/plugins/query_editor/filter_input_integer.html @@ -1,2 +1,2 @@ - -  - + -  + diff --git a/plugins/query_editor/filter_input_others.html b/plugins/query_editor/filter_input_others.html index 3ccaae99..cd4ba267 100644 --- a/plugins/query_editor/filter_input_others.html +++ b/plugins/query_editor/filter_input_others.html @@ -1,4 +1,4 @@
- - + +
diff --git a/plugins/query_editor/filter_input_string.html b/plugins/query_editor/filter_input_string.html index 12971d9e..b0d580ce 100644 --- a/plugins/query_editor/filter_input_string.html +++ b/plugins/query_editor/filter_input_string.html @@ -1,4 +1,4 @@
- - + +
diff --git a/plugins/query_editor/filter_input_string_values.html b/plugins/query_editor/filter_input_string_values.html index f0a10df8..6a8aecaa 100644 --- a/plugins/query_editor/filter_input_string_values.html +++ b/plugins/query_editor/filter_input_string_values.html @@ -1,5 +1,6 @@ ') -filter_input = "\n".join(_filter_input) + {% for option in options %} + + {% endfor %} + diff --git a/plugins/query_editor/query_editor.html b/plugins/query_editor/query_editor.html index 6cd3ff26..e366a646 100644 --- a/plugins/query_editor/query_editor.html +++ b/plugins/query_editor/query_editor.html @@ -8,7 +8,7 @@ EOF; EOF; -->
- +
@@ -29,7 +29,7 @@ EOF; --> diff --git a/plugins/query_editor/query_editor.js b/plugins/query_editor/query_editor.js index 9ef90fd8..9f130f9f 100644 --- a/plugins/query_editor/query_editor.js +++ b/plugins/query_editor/query_editor.js @@ -4,140 +4,109 @@ * License: GPLv3 */ +// XXX TODO This plugin will be interested in changes in metadata +// What if we remove a filter, is it removed in the right min/max field ??? +// -> no on_filter_removed is not yet implemented +// XXX if a plugin has not declared a handler, it might become inconsistent, +// and the interface should either reset or disable it (function($){ var QueryEditor = Plugin.extend({ + event_filter_added: function(op, suffix) { + suffix = (typeof suffix === 'undefined') ? '' : manifold.separator + suffix; + var self = this; + return function(e) { + var array = self.array_from_id(e.target.id); + var key = self.field_from_id(array); // No need to remove suffix... + var value = e.target.value; + + if (value) { + // XXX This should be handled by manifold + //manifold.raise_event(object.options.query_uuid, FILTER_UPDATED, [key, op, value]); + manifold.raise_event(self.options.query_uuid, FILTER_ADDED, [key, op, value]); + } else { + // XXX This should be handled by manifold + manifold.raise_event(self.options.query_uuid, FILTER_REMOVED, [key, op]); + } + } + }, + init: function(options, element) { - $('.queryeditor-auto-filter').change(function(event) { - var key = event.target.id.split('-')[4]; // Should be consistent with the naming of fields - var op = '='; - var value = event.target.value; + this._super(options, element); + + this.listen_query(options.query_uuid); - manifold.raise_event(object.options.query_uuid, FILTER_ADDED, [key, op, value]); + this.els('queryeditor-auto-filter').change(this.event_filter_added('=')); + this.els('queryeditor-filter').change(this.event_filter_added('=')); + this.els('queryeditor-filter-min').change(this.event_filter_added('>')); + this.els('queryeditor-filter-max').change(this.event_filter_added('<')); + + var self = this; + this.els('queryeditor-check').click(function() { + manifold.raise_event(self.options.query_uuid, this.checked?FIELD_ADDED:FIELD_REMOVED, this.value); }); - - jQuery('.queryeditor-filter').change(function(event) { - var key = event.target.id.split('-')[4]; - var op = '='; - var value = event.target.value; - manifold.raise_event(object.options.query_uuid, FILTER_ADDED, [key, op, value]); + /* The following code adds an expandable column for the table */ + // XXX Why isn't it done statically ? + var nCloneTh = document.createElement( 'th' ); + var nCloneTd = document.createElement( 'td' ); + nCloneTd.innerHTML = ""; + //nCloneTd.innerHTML = ''; + nCloneTh.innerHTML = 'Info'; + nCloneTd.className = "center"; + nCloneTh.className = "center"; + // XXX + jQuery('#'+this.options.plugin_uuid+'_fields thead tr').each( function () { + this.insertBefore( nCloneTh, this.childNodes[0] ); }); - jQuery('.queryeditor-filter-min').change(function(event) { - query = data.current_query; - var key=getKeySplitId(event.target.id,"-"); - var op='>'; - var value=event.target.value; - - if(value){ - query.update_filter(key, op, value); - //add_ActiveFilter(event.target.id,'>',event.target.value,data); - }else{ - query.remove_filter(key,op,""); - //remove_ActiveFilter(event, data, event.target.id,'>'); - } - // Publish the query changed, the other plugins with subscribe will get the changes - jQuery.publish('/query/' + query.uuid + '/changed', query); + // XXX + jQuery('#'+this.options.plugin_uuid+'_fields tbody tr').each( function () { + this.insertBefore( nCloneTd.cloneNode( true ), this.childNodes[0] ); + }); + + // We are currently using a DataTable display, but another browsing component could be better + //jQuery('#'+this.options.plugin_uuid+'-table').dataTable... + var metaTable = this.el('table').dataTable({ + bFilter : false, + bPaginate : false, + bInfo : false, + sScrollX : '100%', // Horizontal scrolling + sScrollY : '200px', + bJQueryUI : true, // Use jQuery UI + bProcessing : true, // Loading + aaSorting : [[ 1, "asc" ]], // sort by column fields on load + aoColumnDefs: [ + { 'bSortable': false, 'aTargets': [ 0 ]}, + { 'sWidth': '8px', 'aTargets': [ 0 ] }, + { 'sWidth': '8px', 'aTargets': [ 4 ] } // XXX NB OF COLS + ] }); - jQuery('.queryeditor-filter-max').change(function(event) { - query = data.current_query; - var key=getKeySplitId(event.target.id,"-"); - var op='<'; - var value=event.target.value; + + var self = this; + // Actions on the newly added fields + this.el('table tbody td span').on('click', function() { + var nTr = this.parentNode.parentNode; + // use jQuery UI instead of images to keep a common UI + // class="ui-icon treeclick ui-icon-triangle-1-s tree-minus" + // East oriented Triangle class="ui-icon-triangle-1-e" + // South oriented Triangle class="ui-icon-triangle-1-s" - if(value){ - query.update_filter(key, op, value); - //add_ActiveFilter(event.target.id,'<',event.target.value,data); - }else{ - query.remove_filter(key,op,""); - //remove_ActiveFilter(event, data, event.target.id,'<'); + if (this.className=="ui-icon ui-icon-triangle-1-e") { + this.removeClass("ui-icon-triangle-1-e").addClass("ui-icon-triangle-1-s"); + // XXX ?????? + metaTable.fnOpen(nTr, this.fnFormatDetails(metaTable, nTr, self.options.plugin_uuid+'_div'), 'details' ); + } else { + this.removeClass("ui-icon-triangle-1-s").addClass("ui-icon-triangle-1-e"); + metaTable.fnClose(nTr); } - // Publish the query changed, the other plugins with subscribe will get the changes - jQuery.publish('/query/' + query.uuid + '/changed', query); }); - jQuery('.queryeditor-check').click(function() { - 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; - if (this.checked) { - if (jQuery.inArray(column, query.fields) == -1) { - query.fields.push(column); - jQuery.publish('/query/' + query.uuid + '/changed', query); - } - } else { - query.fields = jQuery.grep(query.fields, function(value) {return value != column;}); - jQuery.publish('/query/' + query.uuid + '/changed', query); - } - */ - }); - - //onFunctionAvailable('jQuery.fn.dataTable', function() { - - var nCloneTh = document.createElement( 'th' ); - var nCloneTd = document.createElement( 'td' ); - nCloneTd.innerHTML = ""; - //nCloneTd.innerHTML = ''; - nCloneTh.innerHTML = 'Info'; - nCloneTd.className = "center"; - nCloneTh.className = "center"; - - jQuery('#'+this.options.plugin_uuid+'_fields thead tr').each( function () { - this.insertBefore( nCloneTh, this.childNodes[0] ); - }); - - jQuery('#'+this.options.plugin_uuid+'_fields tbody tr').each( function () { - this.insertBefore( nCloneTd.cloneNode( true ), this.childNodes[0] ); - }); - - var metaTable = jQuery('#'+this.options.plugin_uuid+'-table').dataTable( { - bFilter: false, - bPaginate: false, - bInfo: false, - sScrollX: '100%', /* Horizontal scrolling */ - sScrollY: "200px", - bJQueryUI: true, // Use jQuery UI - bProcessing: true, // Loading - aaSorting: [[ 1, "asc" ]], // sort by column fields on load - aoColumnDefs: [ {"bSortable": false, "aTargets": [ 0 ]}, - { "sWidth": "8px", "aTargets": [ 0 ] }, - { "sWidth": "8px", "aTargets": [ 4 ] } - ] - }); - - jQuery('#'+this.options.plugin_uuid+'_fields tbody td span').live('click', function () { - var nTr = this.parentNode.parentNode; - // use jQuery UI instead of images to keep a common UI - // class="ui-icon treeclick ui-icon-triangle-1-s tree-minus" - //East oriented Triangle class="ui-icon-triangle-1-e" - //South oriented Triangle class="ui-icon-triangle-1-s" - - if(this.className=="ui-icon ui-icon-triangle-1-e"){ - this.removeClass("ui-icon-triangle-1-e"); - this.addClass("ui-icon-triangle-1-s"); - metaTable.fnOpen( nTr, this.fnFormatDetails(metaTable, nTr, this.options.plugin_uuid+'_div'), 'details' ); - }else{ - this.removeClass("ui-icon-triangle-1-s"); - this.addClass("ui-icon-triangle-1-e"); - metaTable.fnClose( nTr ); - } - /* - if ( this.src.match('details_close') ) { - this.src = "/components/com_tophat/images/details_open.png"; - metaTable.fnClose( nTr ); - } - else { - this.src = "/components/com_tophat/images/details_close.png"; - metaTable.fnOpen( nTr, this.fnFormatDetails(metaTable, nTr, this.options.plugin_uuid+'_div'), 'details' ); - } - */ - }); - - jQuery('#'+this.options.plugin_uuid+'_fields_wrapper').css({'padding-top':'0em','padding-bottom':'0em'}); + this.el('table_wrapper').css({ + 'padding-top' : '0em', + 'padding-bottom': '0em' + }); - //}); // onfunctionAvailable }, // init /* UI management */ @@ -152,34 +121,44 @@ this.el('check', field).attr('checked', false); }, + update_filter_value: function(filter, removed) + { + removed = !(typeof removed === 'undefined'); // default = False + + var key = filter[0]; + var op = filter[1]; + var value = filter[2]; + + var id = this.id_from_field(key); + + if (op == '=') { + var element = this.el(id); + } else { + var suffix; + if (op == '<') { + this.el(id, 'max').val(value); + } else if (op == '>') { + this.el(id, 'min').val(value); + } else { + return; + } + var element = this.el(id, suffix); + } + + element.val(removed?null:value); + + }, + /* Events */ on_filter_added: function(filter) { -// filter = data; -// // Set the value of the filter = to query filter value -// // Necessary if the filter has been modified by another plugin (QuickFilter) -// if(filter[1]=="="){ -// jQuery('#'+this.options.plugin_uuid+'-filter-'+filter[0]).val(filter[2]); -// }else if(filter[1]=="<"){ -// jQuery('#'+this.options.plugin_uuid+'-filter-'+filter[0]+'-max').val(filter[2]); -// }else if(filter[1]==">"){ -// jQuery('#'+this.options.plugin_uuid+'-filter-'+filter[0]+'-min').val(filter[2]); -// } + this.update_filter_value(filter); }, on_filter_removed: function(filter) { -// filter = data; -// if(filter[1]=="="){ -// jQuery('#'+this.options.plugin_uuid+'-filter-'+filter[0]).val(null); -// }else if(filter[1]=="<"){ -// //502124d5a5848-filter-asn-max -// jQuery('#'+this.options.plugin_uuid+'-filter-'+filter[0]+'-max').val(null); -// }else if(filter[1]==">"){ -// //502124d5a5848-filter-asn-min -// jQuery('#'+this.options.plugin_uuid+'-filter-'+filter[0]+'-min').val(null); -// } + this.update_filter_value(filter, true); }, on_field_added: function(field) @@ -305,5 +284,8 @@ return sOut; } - -})( jQuery ); + }); + + $.plugin('QueryEditor', QueryEditor); + +})(jQuery); -- 2.43.0
Field {{ field.type }} {{ field.filter_input }} - +