--- /dev/null
+/* Simple JavaScript Inheritance
+ * By John Resig http://ejohn.org/
+ * MIT Licensed.
+ */
+// Inspired by base2 and Prototype
+(function(){
+ var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
+
+ // The base Class implementation (does nothing)
+ this.Class = function(){};
+
+ // Create a new Class that inherits from this class
+ Class.extend = function(prop) {
+ var _super = this.prototype;
+
+ // Instantiate a base class (but only create the instance,
+ // don't run the init constructor)
+ initializing = true;
+ var prototype = new this();
+ initializing = false;
+
+ // Copy the properties over onto the new prototype
+ for (var name in prop) {
+ // Check if we're overwriting an existing function
+ prototype[name] = typeof prop[name] == "function" &&
+ typeof _super[name] == "function" && fnTest.test(prop[name]) ?
+ (function(name, fn){
+ return function() {
+ var tmp = this._super;
+
+ // Add a new ._super() method that is the same method
+ // but on the super-class
+ this._super = _super[name];
+
+ // The method only need to be bound temporarily, so we
+ // remove it when we're done executing
+ var ret = fn.apply(this, arguments);
+ this._super = tmp;
+
+ return ret;
+ };
+ })(name, prop[name]) :
+ prop[name];
+ }
+
+ // The dummy class constructor
+ function Class() {
+ // All construction is actually done in the init method
+ if ( !initializing && this.init )
+ this.init.apply(this, arguments);
+ }
+
+ // Populate our constructed prototype object
+ Class.prototype = prototype;
+
+ // Enforce the constructor to be what we expect
+ Class.prototype.constructor = Class;
+
+ // And make this class extendable
+ Class.extend = arguments.callee;
+
+ return Class;
+ };
+})();
// 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:
manifold.raise_query_event(query_uuid, event_type, value);
break;
}
+ // 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
+
// 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
},
--- /dev/null
+<!doctype html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Extensible jQuery</title>
+
+ <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
+ <script type="text/javascript" src="simple-inheritance.js"></script>
+ <script type="text/javascript">
+ $.plugin = function(name, object) {
+ $.fn[name] = function(options) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ return this.each(function() {
+ var instance = $.data(this, name);
+ if (instance) {
+ instance[options].apply(instance, args);
+ } else {
+ instance = $.data(this, name, new object(options, this));
+ }
+ });
+ };
+ };
+
+ var Stepper = Class.extend({
+ init: function(options, element) {
+ this.options = $.extend({
+ value: 0,
+ stepSize: 1
+ }, options);
+ this.element = $(element);
+ this.display();
+ },
+ stepUp: function(steps) {
+ this.options.value += this.options.stepSize * steps;
+ this.display();
+ },
+ stepDown: function(steps) {
+ this.options.value -= this.options.stepSize * steps;
+ this.display();
+ },
+ value: function() {
+ return this.options.value;
+ },
+ display: function() {
+ this.element.html(this.options.value);
+ }
+ });
+
+ var Pager = Stepper.extend({
+ init: function(options, element) {
+ this._super(options, element);
+ this.options.pageSize = this.options.pageSize || 10;
+ },
+ pageUp: function() {
+ this.options.value += this.options.pageSize * this.options.stepSize;
+ this.display();
+ },
+ pageDown: function() {
+ this.options.value -= this.options.pageSize * this.options.stepSize;
+ this.display();
+ }
+ });
+
+ $.plugin('stepper', Stepper);
+ $.plugin('pager', Pager);
+
+ $(document).ready(function() {
+
+ // instantiate and use a stepper via jQuery
+ $('#stepper').stepper({ value: 5 });
+ var stepper = $('#stepper').data('stepper');
+
+ console.log(stepper.value());
+
+ $('#stepper').stepper('stepUp', 3);
+ console.log(stepper.value());
+
+
+ // instantiate and use a pager via jQuery
+ $('#pager').pager({ value: 30 });
+ var pager = $('#pager').data('pager');
+
+ console.log(pager.value());
+
+ $('#pager').pager('stepUp', 3);
+ console.log(pager.value());
+
+ $('#pager').pager('pageUp');
+ console.log(pager.value());
+
+
+ // instantiate and use a stepper directly
+ var stepper2 = new Stepper({ value: 20 }, '#stepper2');
+
+ console.log(stepper2.value());
+
+ stepper2.stepDown(2);
+ console.log(stepper2.value());
+
+
+ // modify stepper
+ Function.prototype.partial = function() {
+ var fn = this,
--- /dev/null
+// INHERITANCE
+// http://alexsexton.com/blog/2010/02/using-inheritance-patterns-to-organize-large-jquery-applications/
+// We will use John Resig's proposal
+
+// http://pastie.org/517177
+
+// NOTE: missing a destroy function
+
+$.plugin = function(name, object) {
+ $.fn[name] = function(options) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ return this.each(function() {
+ var instance = $.data(this, name);
+ if (instance) {
+ instance[options].apply(instance, args);
+ } else {
+ instance = $.data(this, name, new object(options, this));
+ }
+ });
+ };
+};
+
+var Plugin = Class.extend({
+
+ init: function(options, element)
+ {
+ // Mix in the passed in options with the default options
+ this.options = $.extend({}, this.default_options, options);
+
+ // Save the element reference, both as a jQuery
+ // reference and a normal reference
+ this.element = element;
+ this.$element = $(element);
+
+ // return this so we can chain/use the bridge with less code.
+ return this;
+ },
+
+ has_query_handler: function() {
+ return (typeof this.on_filter_added === 'function');
+ },
+
+ _query_handler: function(e, event_type, data)
+ {
+ // We suppose this.query_handler_prefix has been defined if this
+ // callback is triggered
+ var fn;
+ switch(event_type) {
+ case FILTER_ADDED:
+ fn = 'filter_added';
+ break;
+ case FILTER_REMOVED:
+ fn = 'filter_removed';
+ break;
+ case CLEAR_FILTERS:
+ fn = 'filter_clear';
+ break;
+ case FIELD_ADDED:
+ fn = 'field_added';
+ break;
+ case FIELD_REMOVED:
+ fn = 'field_removed';
+ break;
+ case CLEAR_FIELDS:
+ fn = 'field_clear';
+ break;
+ default:
+ return;
+ } // switch
+
+ fn = 'on_' + this.query_handler_prefix + fn;
+ if (typeof this[fn] === 'function') {
+ // call with data as parameter
+ // XXX implement anti loop
+ this[fn](data);
+ }
+ },
+
+ listen_query: function(query_uuid, prefix) {
+ this.query_handler_prefix = (typeof prefix === 'undefined') ? '' : (prefix + '_');
+ this.$element.on(manifold.get_query_channel(query_uuid), $.proxy(this._query_handler, this));
+ },
+
+ default_options: {},
+
+ speak: function(msg){
+ // You have direct access to the associated and cached jQuery element
+ this.$element.append('<p>'+msg+'</p>');
+ },
+
+ register: function() {
+ // Registers the plugin to jQuery
+ },
+
+});
+from types import StringTypes
+
from operator import (
and_, or_, inv, add, mul, sub, mod, truediv, lt, le, ne, gt, ge, eq, neg
)
-from manifold.util.misc import contains
-from types import StringTypes
+
+# Define the inclusion operators
+class contains(type): pass
+class included(type): pass
+
# New modifier: { contains
class Predicate:
operators = {
- "==" : eq,
- "!=" : ne,
- "<" : lt,
- "<=" : le,
- ">" : gt,
- ">=" : ge,
- "&&" : and_,
- "||" : or_,
- "contains" : contains
+ '==' : eq,
+ '!=' : ne,
+ '<' : lt,
+ '<=' : le,
+ '>' : gt,
+ '>=' : ge,
+ '&&' : and_,
+ '||' : or_,
+ 'CONTAINS' : contains,
+ 'INCLUDED' : included
}
operators_short = {
- "=" : eq,
- "~" : ne,
- "<" : lt,
- "[" : le,
- ">" : gt,
- "]" : ge,
- "&" : and_,
- "|" : or_,
- "}" : contains
+ '=' : eq,
+ '~' : ne,
+ '<' : lt,
+ '[' : le,
+ '>' : gt,
+ ']' : ge,
+ '&' : and_,
+ '|' : or_,
+ '}' : contains,
+ '{' : included
}
def __init__(self, *args, **kwargs):
elif len(args) == 1 and isinstance(args[0], Predicate):
key, op, value = args[0].get_tuple()
else:
- raise Exception, "Bad initializer for Predicate"
+ raise Exception, "Bad initializer for Predicate (args=%r)" % args
+
+ assert not isinstance(value, (frozenset, dict, set)), "Invalid value type (the only valid containers are tuples and lists) (type = %r)" % type(value)
+ if isinstance(value, list):
+ value = tuple(value)
+
self.key = key
+ if isinstance(op, StringTypes):
+ op = op.upper()
if op in self.operators.keys():
self.op = self.operators[op]
elif op in self.operators_short.keys():
self.op = self.operators_short[op]
else:
self.op = op
- if isinstance(value, (list, set)):
+
+ if isinstance(value, list):
self.value = tuple(value)
else:
self.value = value
def __str__(self):
- return "Pred(%s, %s, %s)" % self.get_str_tuple()
+ key, op, value = self.get_str_tuple()
+ if isinstance(value, (tuple, list, set, frozenset)):
+ value = [repr(v) for v in value]
+ value = "[%s]" % ", ".join(value)
+ return "%s %s %r" % (key, op, value)
def __repr__(self):
- return self.__str__()
+ return "Predicate<%s %s %r>" % self.get_str_tuple()
def __hash__(self):
return hash(self.get_tuple())
+ def __eq__(self, predicate):
+ if not predicate:
+ return False
+ return self.get_tuple() == predicate.get_tuple()
+
+ def get_key(self):
+ return self.key
+
+ def set_key(self, key):
+ self.key = key
+
+ def get_op(self):
+ return self.op
+
+ def get_value(self):
+ return self.value
+
+ def set_value(self, value):
+ self.value = value
+
def get_tuple(self):
return (self.key, self.op, self.value)
elif self.op == contains:
method, subfield = self.key.split('.', 1)
return not not [ x for x in dic[method] if x[subfield] == self.value]
+ elif self.op == included:
+ return dic[self.key] in self.value
else:
- raise Exception, "Unexpected table format: %r", dic
+ raise Exception, "Unexpected table format: %r" % dic
def filter(self, dic):
"""
print "----"
return dic if self.match(dic) else None
+ def get_field_names(self):
+ if isinstance(self.key, (list, tuple, set, frozenset)):
+ return set(self.key)
+ else:
+ return set([self.key])
+
+ def get_value_names(self):
+ if isinstance(self.value, (list, tuple, set, frozenset)):
+ return set(self.value)
+ else:
+ return set([self.value])
--- /dev/null
+from unfold.plugin import Plugin
+from manifold.util.predicate import eq, ne, lt, le, gt, ge, and_, or_, contains, included
+
+# NOTE: Python should pass templates to javascript for creating new filters
+# - option variable
+# - or, better, hidden div in the page
+# In the meantime, templates are duplicated in the javascript code
+# RECIPES FOR PLUGINS
+
+# NOTE: having classes would help
+
+class ActiveFilters(Plugin):
+
+ def __init__ (self, query=None, **settings):
+ Plugin.__init__ (self, **settings)
+
+ self.query = query
+
+ def template_file (self):
+ return "active_filters.html"
+
+ def template_env (self, request):
+
+ def get_op_str(predicate):
+ map = {
+ eq : 'eq',
+ ne : 'ne',
+ lt : 'lt',
+ le : 'le',
+ gt : 'gt',
+ ge : 'ge',
+ and_ : 'and',
+ or_ : 'or',
+ contains: 'contains',
+ included: 'included'
+ }
+ return map[predicate.get_op()]
+
+ filters = [[f.get_key(), get_op_str(f), f.get_value()] for p in self.query.get_where()]
+ env={}
+ env.update(self.__dict__)
+ env['filters'] = filters
+ return env
+
+ def requirements (self):
+ reqs = {
+ 'js_files' : [
+ 'js/active_filters.js',
+ ],
+ 'css_files': [
+ 'css/demo_table.css',
+ 'css/active_filters.css'
+ ]
+ }
+ return reqs
+
+ def json_settings_list (self):
+ return ['plugin_uuid', 'domid', 'query_uuid']
+
+ def export_json_settings (self):
+ return True
--- /dev/null
+/*
+ Document : ActiveFilters
+ Created on : 26 juil. 2012, 11:19:10
+ Author : loicbaron
+ Description:
+ Purpose of the stylesheet follows.
+*/
+
+.filterButton {
+ border: 1px solid #AAA;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ padding: 2px 5px;
+ margin: 0 3px;
+ background-color:#D3D6FF;
+}
+.closeButton{
+ cursor: pointer;
+ vertical-align:middle;
+}
\ No newline at end of file
--- /dev/null
+<div id='myActiveFilters' style='clear:both;'>
+ <div id='{{domid}}-template' class='filterButton' style='float:left;margin-bottom:10px;visibility: hidden;'>
+ <span id='{{domid}}-template-filter'>KEY OP VALUE</span>
+ </div>
+ {% for filter in filters %}
+ <div id='{{domid}}-filter-{{filter.key}}{{filter.op_str}}{{filter.value}}' class='filterButton' style='float:left;margin-bottom:10px;visibility: hidden;'>
+ <span id='{{domid}}-template-filter'>{{filter.key}}{{filter.op}}{{filter.value}}</span>
+ </div>
+ {% endfor %}
+</div>
+
+<div id='clearFilters' class='paging_full_numbers' style='clear:both;'>
+ <span class='paginate_button'>Clear</span>
+</div>
+<div style='clear:both;'></div>
--- /dev/null
+/**
+ * Description: ActiveFilters plugin
+ * Copyright (c) 2012-2013 UPMC Sorbonne Universite
+ * License: GPLv3
+ */
+
+(function($){
+
+ var ActiveFilters = Plugin.extend({
+
+ init: function(options, element) {
+ this._super(options, element);
+
+ this.listen_query(options.query_uuid);
+
+ $("#clearFilters").click(function () {
+ manifold.raise_event(options.query_uuid, CLEAR_FILTERS);
+ });
+ },
+
+ // This should be provided in the API
+ // make_id_from_filter, etc
+ getOperatorLabel: function(op)
+ {
+ if (op == "=" || op == "==") {
+ return 'eq';
+ } else if (op == "!=") {
+ return "ne";
+ } else if (op == ">") {
+ return "gt";
+ } else if (op == ">=") {
+ return "ge";
+ } else if (op == "<") {
+ return "lt";
+ } else if (op == "<=") {
+ return "le";
+ } else {
+ return false;
+ }
+ },
+
+ // Visual actions on the component
+
+ clear_filters: function() {
+ $("#clearFilters").hide();
+ },
+
+ on_filter_added: function(filter) {
+ var key = filter[0];
+ var op = filter[1];
+ var value = filter[2];
+ var op_str = this.getOperatorLabel(op);
+ var id = 'filter_' + key + "_" + op_str;
+
+ // Add a button for a filter
+ $('#myActiveFilters').append("<div id='" + id + "' class='filterButton' style='float:left;margin-bottom:10px;'/>");
+ $('#' + id).append(key + op + value);
+
+ // Add a close button to remove the filter
+ $('#' + id).append("<img id='close-" + id + "' src='/all-static/img/details_close.png' class='closeButton' style='padding-left:3px;'/>");
+ // Add an event on click on the close button, call function removeFilter
+ $('#close-' + id).click(function(event) {
+ manifold.raise_event(options.query_uuid, FILTER_REMOVED, filter);
+ });
+ // If there are active filters, then show the clear filters button
+ $("#clearFilters").show();
+ },
+
+ on_filter_removed: function(filter) {
+ var key = filter[0];
+ var op = filter[1];
+ var value = filter[2];
+ var op_str = this.getOperatorLabel(op);
+ var id = 'filter_' + key + "_" + op_str;
+
+ $('#' + id).remove()
+ // Count the number of filter _inside_ the current plugin
+ count = $('.filterButton', $('#myActiveFilters')).length;
+ if (count == 0) {
+ jQuery("#clearFilters").hide();
+ }
+ },
+
+ on_filter_clear: function(filter) {
+ $("#clearFilters").hide();
+
+ },
+ });
+
+ $.plugin('ActiveFilters', ActiveFilters);
+
+})(jQuery);
$this.data('Manifold', plugin);
$this.set_query_handler(options.query_uuid, plugin.query_handler);
+ // This is used for autocomplete
$this.set_record_handler(options.query_uuid, plugin.record_handler);
}); // this.each
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');
- $this.set_query_handler(options.query_uuid, hazelnut.query_handler);
- $this.set_record_handler(options.query_uuid, hazelnut.record_handler);
-
- /* XXX Subscribe to query updates to maintain current state of query (multiple editors) */
- jQuery.subscribe('/query/' + options.query_uuid + '/changed', {instance: $this}, query_changed);
- jQuery.subscribe('/query/' + options.query_uuid + '/diff', {instance: $this}, query_changed_diff);
- /* Subscribe to results in order to redraw the table when updates arrive */
- jQuery.subscribe('/results/' + options.query_uuid + '/changed', {instance: $this}, update_autocomplete);
-
});
}, // destroy
{
var d = data;
+
+ jQuery('.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;
+
+ manifold.raise_event(object.options.query_uuid, FILTER_ADDED, [key, op, value]);
+ });
jQuery('.queryeditor-filter').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);
+ 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]);
});
jQuery('.queryeditor-filter-min').change(function(event) {
query = data.current_query;
{
// This replaces the complex set_query function
// The plugin does not need to remember the query anymore
- switch(event_type) {
- // Filters
- // When Query changed, Then we need to update the filters of
- // QueryEditor plugin if the filter is active, set the value
- // (the update can come from another plugin) else set the
- // filter value to null PB if the filter is composed of MIN/MAX
- // values
- case FILTER_ADDED:
- 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]);
- }
- case FILTER_REMOVED:
- 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);
- }
- case CLEAR_FILTERS:
- break;
-
- // Fields
- /* Hide/unhide columns to match added/removed fields */
- // XXX WRONG IDENTIFIERS
- case FIELD_ADDED:
- object.check(data);
- break;
- case FIELD_REMOVED:
- object.uncheck(data);
- break;
- case CLEAR_FIELDS:
- alert(PLUGIN_NAME + '::clear_fields() not implemented');
- break;
- } // switch
+// switch(event_type) {
+// // Filters
+// // When Query changed, Then we need to update the filters of
+// // QueryEditor plugin if the filter is active, set the value
+// // (the update can come from another plugin) else set the
+// // filter value to null PB if the filter is composed of MIN/MAX
+// // values
+// case FILTER_ADDED:
+// 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]);
+// }
+// case FILTER_REMOVED:
+// 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);
+// }
+// case CLEAR_FILTERS:
+// break;
+//
+// // Fields
+// /* Hide/unhide columns to match added/removed fields */
+// // XXX WRONG IDENTIFIERS
+// case FIELD_ADDED:
+// object.check(data);
+// break;
+// case FIELD_REMOVED:
+// object.uncheck(data);
+// break;
+// case CLEAR_FIELDS:
+// alert(PLUGIN_NAME + '::clear_fields() not implemented');
+// break;
+// } // switch
}
function ResourcesSelected(options)
{
/* member variables */
-
this.options = options;
-
var object = this;
/* The resources that are in the slice */
from plugins.senslabmap.senslabmap import SensLabMap
from plugins.querycode.querycode import QueryCode
from plugins.query_editor import QueryEditor
+from plugins.active_filters import ActiveFilters
from plugins.quickfilter.quickfilter import QuickFilter
from plugins.messages.messages import Messages
from plugins.updater.updater import Updater
)
stack_resources.insert(resource_query_editor)
+ resource_active_filters = ActiveFilters(
+ page = page,
+ query = sq_resource,
+ )
+ stack_resources.insert(resource_active_filters)
+
# --------------------------------------------------------------------------
# Different displays = DataTables + GoogleMaps
#
//
// storing toggle's status in localStorage
// NOTE that localStorage only stores strings, so true becomes "true"
-var plugin = {
+var plugin_helper = {
debug:false,
////////// use local storage to remember open/closed toggles
store_status : function (domid,status) {
var key='toggle.'+domid;
- if (plugin.debug) messages.debug("storing toggle status " + status + " for " + domid + " key=" + key);
+ if (plugin_helper.debug) messages.debug("storing toggle status " + status + " for " + domid + " key=" + key);
$.localStorage.setItem(key,status);
},
// restore last status
var retrieved=$.localStorage.getItem(key);
// set default to true
if (retrieved==null) retrieved="true";
- if (plugin.debug) messages.debug ("retrieved toggle status for " + domid + " (key=" + key + ") -> " + retrieved);
+ if (plugin_helper.debug) messages.debug ("retrieved toggle status for " + domid + " (key=" + key + ") -> " + retrieved);
return retrieved;
},
set_toggle_status : function (domid,status) {
var hidebtn=$('#hide-'+domid);
if (status=="true") { plugindiv.slideDown(); hidebtn.show(); showbtn.hide(); }
else { plugindiv.slideUp(); hidebtn.hide(); showbtn.show(); }
- plugin.store_status(domid,status);
+ plugin_helper.store_status(domid,status);
},
set_from_saved_status : function (domid) {
- var previous_status=plugin.retrieve_last_status (domid);
- if (plugin.debug) messages.debug("restoring initial status for domid " + domid + " -> " + previous_status);
- plugin.set_toggle_status (domid,previous_status);
+ var previous_status=plugin_helper.retrieve_last_status (domid);
+ if (plugin_helper.debug) messages.debug("restoring initial status for domid " + domid + " -> " + previous_status);
+ plugin_helper.set_toggle_status (domid,previous_status);
},
// triggered upon $(document).ready
init_all_plugins : function() {
// let us first make sure the right parts are turned on
$('.persistent-toggle').each(function() {
var domid=this.id.replace('complete-','');
- plugin.set_from_saved_status(domid);
+ plugin_helper.set_from_saved_status(domid);
});
// program the hide buttons so they do the right thing
$('.plugin-hide').each(function() {
$(this).click(function () {
var domid=this.id.replace('hide-','');
- plugin.set_toggle_status(domid,"false");
+ plugin_helper.set_toggle_status(domid,"false");
})});
// same for show buttons
$('.plugin-show').each(function() {
$(this).click(function () {
var domid=this.id.replace('show-','');
- plugin.set_toggle_status(domid,"true");
+ plugin_helper.set_toggle_status(domid,"true");
})});
// arm tooltips
$('.plugin-tooltip').each(function(){ $(this).tooltip({'selector':'','placement':'right'}); });
/* upon document completion, we locate all the hide and show areas,
* and configure their behaviour
*/
-$(document).ready(plugin.init_all_plugins)
+$(document).ready(plugin_helper.init_all_plugins)
--- /dev/null
+{# This is required by insert_above #}{% insert_handler %}<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html lang="en"> <head>
+<title> MySlice - {{ title }} </title>
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+{# This is where insert_str will end up #}{% media_container prelude %}
+{% include 'messages-header.html' %}
+<script type="text/javascript"> {# raw js code - use {% insert prelude_js %} ... {% endinsert %} #} {% container prelude_js %}</script>
+<style type="text/css">{# In case we need to add raw css code #}{% container prelude_css %}</style>
+{{ header_prelude }}
+{% block head %} {% endblock head %}
+</head>{# let's add these ones no matter what #}
+{# not yet needed {% insert_str prelude "css/layout-unfold1.css" %} #}
+{% insert_str prelude "js/jquery.min.js" %}
+{% insert_str prelude "js/jquery.html5storage.min.js" %}
+{% insert_str prelude "js/messages-runtime.js" %}
+{% insert_str prelude "js/class.js" %}
+{% insert_str prelude "js/plugin_helper.js" %}
+{% insert_str prelude "js/plugin.js" %}
+{% insert_str prelude "js/manifold.js" %}
+<body>
+{% block container %}
+<div id="container">
+ {% block topmenu %}
+ {% include 'widget-topmenu.html' %}
+ {% endblock topmenu %}
+{% include 'messages.html' %}
+<div class="container-fluid">
+ <div class="row-fluid">
+
+ {% block base_content%}{% endblock %}
+
+ </div><!--raw-fluid-->
+</div><!--container-fluid-->
+{% endblock container %}
+</body>
+</html>
-{# This is required by insert_above #}{% insert_handler %}<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html lang="en"> <head>
-<title> MySlice - {{ title }} </title>
-<meta name="viewport" content="width=device-width, initial-scale=1.0">
-{# This is where insert_str will end up #}{% media_container prelude %}
-{% include 'messages-header.html' %}
-<script type="text/javascript"> {# raw js code - use {% insert prelude_js %} ... {% endinsert %} #} {% container prelude_js %}</script>
-<style type="text/css">{# In case we need to add raw css code #}{% container prelude_css %}</style>
-{{ header_prelude }}
-{% block head %} {% endblock head %}
-</head>{# let's add these ones no matter what #}
-{# not yet needed {% insert_str prelude "css/layout-unfold1.css" %} #}
-{% insert_str prelude "js/jquery.min.js" %}
-{% insert_str prelude "js/jquery.html5storage.min.js" %}
-{% insert_str prelude "js/messages-runtime.js" %}
-{% insert_str prelude "js/plugin.js" %}
-<body>
-{% block container %}
-<div id="container">
- {% block topmenu %}
- {% include 'widget-topmenu.html' %}
- {% endblock topmenu %}
-{% include 'messages.html' %}
-<div class="container-fluid">
- <div class="row-fluid">
+{% extends "base.html" %}
+
+{% block base_content %}
<div id="unfold1-main" class="span12 columns">
{% block unfold1_main %}
"The main content area (define block 'unfold1_main')"
{% endblock unfold1_main %}
</div><!--span12-->
- </div><!--raw-fluid-->
-</div><!--container-fluid-->
-{% endblock container %}
-</body>
-</html>
+{% endblock %}
-{# This is required by insert_above #}{% insert_handler %}<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html lang="en"> <head>
-<title> MySlice - {{ title }} </title>
-<meta name="viewport" content="width=device-width, initial-scale=1.0">
-{# This is where insert_str will end up #}{% media_container prelude %}
-<script type="text/javascript"> {# raw js code - use {% insert prelude_js %} ... {% endinsert %} #} {% container prelude_js %}</script>
-<style type="text/css">{# In case we need to add raw css code #}{% container prelude_css %}</style>
-{{ header_prelude }}
-</head>{# let's add these ones no matter what #}
-{% insert_str prelude "css/layout-unfold2.css" %}
-{% insert_str prelude "js/jquery.min.js" %}
-{% insert_str prelude "js/jquery.html5storage.min.js" %}
-{% insert_str prelude "js/messages-runtime.js" %}
-{% insert_str prelude "js/plugin.js" %}
-<body>
-{% block container %}
-<div id="container">
- {% block topmenu %}
- {% include 'widget-topmenu.html' %}
- {% endblock topmenu %}
-<div class="container-fluid">
- <div class="row-fluid">
+{% extends "base.html" %}
+
+{% block base_content %}
<div id="unfold2-main" class="span9 columns">
{% block unfold2_main %}
"The main content area (define block 'unfold2_main')"
"The related content area (define block 'related_main')"
{% endblock unfold2_margin %}
</div><!--span3-->
- </div><!--raw-fluid-->
-</div><!--container-fluid-->
-{% endblock container %}
-</body>
-</html>
+{% endblock %}