def widget(self, field, value,**attributes): #generate the standard widget for this field if self.multiple == True: select_widget = MultipleOptionsWidget.widget(field, value, size=7) attr = MultipleOptionsWidget._attributes(field, {'value':value}, **attributes) else: select_widget = OptionsWidget.widget(field, value) attr = OptionsWidget._attributes(field, {'value':value}, **attributes) #get the widget's id (need to know later on so can tell receiving controller what to update) my_select_id = select_widget.attributes.get('_id', None) add_args = [my_select_id] #create a div that will load the specified controller via ajax form_loader_div = DIV(LOAD(c=self.controller, f=self.function, args=add_args,ajax=True), _id=my_select_id+"_dialog-form", _title=self.form_title) #generate the "add" button that will appear next the options widget and open our dialog activator_button = A(XML('<button type="button" class="btn btn-primary" data-toggle="button">'+T(self.button_text)+'</button>'), _id=my_select_id+"_option_add_trigger") #create javascript for creating and opening the dialog js = '$( "#%s_dialog-form" ).dialog({autoOpen: false, show: "blind", hide: "explode", width: %s});' % (my_select_id, self.dialog_width) js += '$( "#%s_option_add_trigger" ).click(function() { $( "#%s_dialog-form" ).dialog( "open" );return false;}); ' % (my_select_id, my_select_id) #decorate our activator button for good measure js += '$(function() { $( "#%s_option_add_trigger" ).button({text: true, icons: { primary: "ui-icon-circle-plus"} }); });' % (my_select_id) jq_script=SCRIPT(js, _type="text/javascript") wrapper = DIV(_id=my_select_id+"_adder_wrapper") wrapper.components.extend([select_widget, form_loader_div, activator_button, jq_script]) return wrapper
def _select_field(self, list_fields, form_values=None, **attr): """ Returns a SELECT of field names @param list_fields: the fields to include in the options list @param attr: the HTML attributes for the SELECT """ name = attr["_name"] if form_values: value = form_values.get(name, "") else: value = "" table = self.table lfields, joins, left, distinct = self.resource.resolve_selectors(list_fields) options = [] for f in lfields: if (f.field is None or f.field.name != table._id.name) and f.show: options.append((f.selector, f.label)) dummy_field = Storage(name=name, requires=IS_IN_SET(options)) return OptionsWidget.widget(dummy_field, value, **attr)
def widget(self, field, value,**attributes): attr = OptionsWidget._attributes(field, {'value':value}, **attributes) opts = [OPTION('')] + [ OPTGROUP( _label=group, *[OPTION(v, _value=k) for (k, v) in options.items()]) for group, options in self.groups.items() ] #d_id = "multiselect-" + str(uuid.uuid4())[:8] #wrapper = DIV(_id=d_id) wrapper = SELECT(*opts, **attr) #inp = SELECT(*opts, **attr) scr = SCRIPT('$(".selectpicker").selectpicker();') #opts = 'minLength: %s, delay: %s, disabled: %s' % \ # (self.min_length,self.delay,str(self.disabled).lower()) #if self.url: #scr = SCRIPT('jQuery("#%s input").autocomplete({source: "%s", %s});' % \ # (d_id, self.url, opts)) #else: # rows = f._db(f._table['id']>0).select(f,distinct=True) # itms = [str(t[f.name]) for t in rows] # scr = SCRIPT('var data = "%s".split("|");'\ # 'jQuery("#%s input").autocomplete({source: data, %s});' % \ # ("|".join(itms),d_id,opts)) #wrapper.append(inp) wrapper.append(scr) return wrapper
def _select_field(self, list_fields, form_values=None, **attr): """ Returns a SELECT of field names @param list_fields: the fields to include in the options list @param attr: the HTML attributes for the SELECT """ name = attr["_name"] if form_values: value = form_values.get(name, "") else: value = "" table = self.table lfields, joins, left, distinct = self.resource.resolve_selectors(list_fields, skip_components=False) options = [] for f in lfields: if (f.field is None or f.field.name != table._id.name) and f.show: options.append((f.selector, f.label)) dummy_field = Storage(name=name, requires=IS_IN_SET(options)) return OptionsWidget.widget(dummy_field, value, **attr)
def _select_field(self, list_fields, form_values=None, **attr): """ Returns a SELECT of field names @param list_fields: the fields to include in the options list @param attr: the HTML attributes for the SELECT """ resource = self.resource name = attr["_name"] if form_values: value = form_values.get(name, "") else: value = "" if "." not in value.split("$", 1)[0]: value = "%s.%s" % (resource.alias, value) table = self.table rfields, j, l, d = resource.resolve_selectors(list_fields, skip_components=False) options = [(f.selector, f.label) for f in rfields if f.show and (f.field is None or f.field.name != table._id.name)] dummy_field = Storage(name=name, requires=IS_IN_SET(options)) return OptionsWidget.widget(dummy_field, value, **attr)
def _select_method(methods, form_values=None, **attr): """ Returns a SELECT of aggregation methods @param methods: list of methods to show @param attr: the HTML attributes for the SELECT """ supported_methods = S3Report.METHODS if methods: methods = [(m, supported_methods[m]) for m in methods if m in supported_methods] else: methods = supported_methods.items() name = attr["_name"] if form_values: value = form_values[name] else: value = None options = [] for method, label in methods: options.append((method, label)) dummy_field = Storage(name=name, requires=IS_IN_SET(options)) return OptionsWidget.widget(dummy_field, value, **attr)
def widget(self, field, value, **attributes): attr = OptionsWidget._attributes(field, {'value': value}, **attributes) opts = [OPTION('')] + [ OPTGROUP(_label=group, *[OPTION(v, _value=k) for (k, v) in options.items()]) for group, options in self.groups.items() ] #d_id = "multiselect-" + str(uuid.uuid4())[:8] #wrapper = DIV(_id=d_id) wrapper = SELECT(*opts, **attr) #inp = SELECT(*opts, **attr) scr = SCRIPT('$(".selectpicker").selectpicker();') #opts = 'minLength: %s, delay: %s, disabled: %s' % \ # (self.min_length,self.delay,str(self.disabled).lower()) #if self.url: #scr = SCRIPT('jQuery("#%s input").autocomplete({source: "%s", %s});' % \ # (d_id, self.url, opts)) #else: # rows = f._db(f._table['id']>0).select(f,distinct=True) # itms = [str(t[f.name]) for t in rows] # scr = SCRIPT('var data = "%s".split("|");'\ # 'jQuery("#%s input").autocomplete({source: data, %s});' % \ # ("|".join(itms),d_id,opts)) #wrapper.append(inp) wrapper.append(scr) return wrapper
def axis_options(self, axis, options=None, get_vars=None, widget_id=None): """ Construct an OptionsWidget for rows or cols axis @param axis: "rows" or "cols" @param options: the report options @param get_vars: the GET vars if the request (as dict) @param widget_id: the HTML element ID for the widget """ resource = self.resource prefix = resource.prefix_selector # Get all selectors if options and axis in options: fields = options[axis] else: fields = resource.get_config("list_fields") if not fields: fields = [f.name for f in resource.readable_fields()] # Resolve the selectors pkey = str(resource._id) resolve_selector = resource.resolve_selector rfields = [] append = rfields.append for f in fields: if isinstance(f, (tuple, list)): label, selector = f[:2] else: label, selector = None, f rfield = resolve_selector(selector) if rfield.colname == pkey: continue if label: rfield.label = label append(rfield) # Get current value if get_vars and axis in get_vars: value = get_vars[axis] else: value = "" if value: value = prefix(value) # Dummy field opts = [(prefix(rfield.selector), rfield.label) for rfield in rfields] dummy_field = Storage(name=axis, requires=IS_IN_SET(opts)) # Construct widget return OptionsWidget.widget(dummy_field, value, _id=widget_id, _name=axis, _class="pt-%s" % axis)
def rating_widget(f,v): from gluon.sqlhtml import OptionsWidget import uuid id = str(uuid.uuid4()) for path in DEPENDENCIES: response.files.append(path) return DIV(SPAN(_id="stars-cap"), DIV(OptionsWidget.widget(f,v),_id=id), SCRIPT("jQuery(function(){jQuery('#%s').stars({inputType: 'select'});});" % id))
def widget(field, value, **attributes): """ generates a TABLE tag, including INPUT checkboxes (multiple allowed) see also: :meth:`FormWidget.widget` """ # was values = re.compile('[\w\-:]+').findall(str(value)) if isinstance(value, (list, tuple)): values = [str(v) for v in value] else: values = [str(value)] attr = OptionsWidget._attributes(field, {}, **attributes) requires = field.requires if not isinstance(requires, (list, tuple)): requires = [requires] if requires: if hasattr(requires[0], 'options'): options = requires[0].options() else: raise SyntaxError('widget cannot determine options of %s' % field) options = [(k, v) for k, v in options if k != ''] opts = [] cols = attributes.get('cols', 1) totals = len(options) mods = totals % cols rows = totals / cols if mods: rows += 1 for r_index in range(rows): tds = [] for k, v in options[r_index * cols:(r_index + 1) * cols]: if k in values: r_value = k else: r_value = [] tds.append( LI( INPUT(_type='checkbox', _id='%s%s' % (field.name, k), _name=field.name, requires=attr.get('requires', None), hideerror=True, _value=k, value=r_value), LABEL(v, _for='%s%s' % (field.name, k)))) opts.append(UL(tds, _style='list-style-type: none;')) if opts: opts[-1][0][0]['hideerror'] = False return DIV(*opts, **attr)
def time_options(self, options=None, get_vars=None, widget_id=None): T = current.T resource = self.resource prefix = resource.prefix_selector # Time options: if options and "time" in options: opts = options["time"] else: # (label, start, end, slots) # If you specify a start, then end is relative to that - without start, end is relative to now opts = (("All up to now", "", "", ""), ("Last Year", "-1year", "", "months"), ("Last 6 Months", "-6months", "", "weeks"), ("Last Quarter", "-3months", "", "weeks"), ("Last Month", "-1month", "", "days"), ("Last Week", "-1week", "", "days"), ("All/+1 Month", "", "+1month", ""), ("All/+2 Month", "", "+2month", ""), ("-6/+3 Months", "-6months", "+9months", "months"), ("-3/+1 Months", "-3months", "+4months", "weeks"), ("-4/+2 Weeks", "-4weeks", "+6weeks", "weeks"), ("-2/+1 Weeks", "-2weeks", "+3weeks", "days"), ) widget_opts = [] for opt in opts: label, start, end, slots = opt widget_opts.append(("|".join((start, end, slots)), T(label))) # Get current value if get_vars: start = get_vars.get("start", "") end = get_vars.get("end", "") slots = get_vars.get("slots", "") else: start = end = slots = "" value = "|".join((start, end, slots)) # Dummy field dummy_field = Storage(name="time", requires=IS_IN_SET(widget_opts)) # Construct widget return OptionsWidget.widget(dummy_field, value, _id=widget_id, _name="time", _class="tp-time", )
def time_options(self, options=None, get_vars=None, widget_id=None): T = current.T resource = self.resource prefix = resource.prefix_selector # Time options: if options and "time" in options: opts = options["time"] else: # (label, start, end, slots) # If you specify a start, then end is relative to that - without start, end is relative to now opts = ( ("All up to now", "", "", ""), ("Last Year", "-1year", "", "months"), ("Last 6 Months", "-6months", "", "weeks"), ("Last Quarter", "-3months", "", "weeks"), ("Last Month", "-1month", "", "days"), ("Last Week", "-1week", "", "days"), ("All/+1 Month", "", "+1month", ""), ("All/+2 Month", "", "+2month", ""), ("-6/+3 Months", "-6months", "+9months", "months"), ("-3/+1 Months", "-3months", "+4months", "weeks"), ("-4/+2 Weeks", "-4weeks", "+6weeks", "weeks"), ("-2/+1 Weeks", "-2weeks", "+3weeks", "days"), ) widget_opts = [] for opt in opts: label, start, end, slots = opt widget_opts.append(("|".join((start, end, slots)), T(label))) # Get current value if get_vars: start = get_vars.get("start", "") end = get_vars.get("end", "") slots = get_vars.get("slots", "") else: start = end = slots = "" value = "|".join((start, end, slots)) # Dummy field dummy_field = Storage(name="time", requires=IS_IN_SET(widget_opts)) # Construct widget return OptionsWidget.widget( dummy_field, value, _id=widget_id, _name="time", _class="tp-time", )
def widget(self, f, v): uid = str(uuid.uuid4())[:8] opts = 'disabled: %s, oneVoteOnly: %s' % (str( self.disabled).lower(), str(self.single_vote).lower()) wrapper = DIV(SPAN(_id="stars-cap"), _id="stars-wrapper_%s" % uid) from gluon.sqlhtml import OptionsWidget inp = OptionsWidget.widget(f, v) scr = SCRIPT('jQuery("#stars-wrapper_%s").stars('\ '{inputType: "select", %s});' % (uid, opts)) wrapper.append(inp) wrapper.append(scr) return wrapper
def create_widget(self, field, value, clean_val, multi, restricted, rval): """create either a single select widget or multiselect widget""" if multi: w = MultipleOptionsWidget.widget(field, value) # TODO: Create filtered multiple options widget class else: if rval: w = FilteredOptionsWidget.widget(field, value, restricted, rval) else: w = OptionsWidget.widget(field, value) return w
def create_widget(self, field, value, clean_val, multi, restricted, rval): """create either a single select widget or multiselect widget""" if multi: w = MultipleOptionsWidget.widget(field, value) #TODO: Create filtered multiple options widget class else: if rval: w = FilteredOptionsWidget.widget(field, value, restricted, rval) else: w = OptionsWidget.widget(field, value) return w
def widget(field, value, **attributes): """ generates a TABLE tag, including INPUT radios (only 1 option allowed) see also: :meth:`FormWidget.widget` """ attr = OptionsWidget._attributes(field, {}, **attributes) requires = field.requires if not isinstance(requires, (list, tuple)): requires = [requires] if requires: if hasattr(requires[0], 'options'): options = requires[0].options() else: raise SyntaxError('widget cannot determine options of %s' % field) options = [(k, v) for k, v in options if str(v)] opts = [] cols = attributes.get('cols', 1) totals = len(options) mods = totals % cols rows = totals / cols if mods: rows += 1 for r_index in range(rows): tds = [] for k, v in options[r_index * cols:(r_index + 1) * cols]: checked = {'_checked': 'checked'} if k == value else {} tds.append( LI( INPUT(_type='radio', _id='%s%s' % (field.name, k), _name=field.name, requires=attr.get('requires', None), hideerror=True, _value=k, value=value, **checked), LABEL(v, _for='%s%s' % (field.name, k)))) opts.append(UL(tds, _style='list-style-type: none;')) if opts: opts[-1][0][0]['hideerror'] = False return DIV(*opts, **attr)
def widget(field, value, **attributes): """ generates a TABLE tag, including INPUT checkboxes (multiple allowed) see also: :meth:`FormWidget.widget` """ # was values = re.compile('[\w\-:]+').findall(str(value)) if isinstance(value, (list, tuple)): values = [str(v) for v in value] else: values = [str(value)] attr = OptionsWidget._attributes(field, {}, **attributes) requires = field.requires if not isinstance(requires, (list, tuple)): requires = [requires] if requires: if hasattr(requires[0], 'options'): options = requires[0].options() else: raise SyntaxError('widget cannot determine options of %s' % field) options = [(k, v) for k, v in options if k != ''] opts = [] cols = attributes.get('cols', 1) totals = len(options) mods = totals % cols rows = totals / cols if mods: rows += 1 for r_index in range(rows): tds = [] for k, v in options[r_index * cols:(r_index + 1) * cols]: if k in values: r_value = k else: r_value = [] tds.append(LI(INPUT(_type='checkbox', _id='%s%s' % (field.name, k), _name=field.name, requires=attr.get('requires', None), hideerror=True, _value=k, value=r_value), LABEL(v, _for='%s%s' % (field.name, k)))) opts.append(UL(tds, _style='list-style-type: none;')) if opts: opts[-1][0][0]['hideerror'] = False return DIV(*opts, **attr)
def widget(self, f, v): uid = str(uuid.uuid4())[:8] opts = 'disabled: %s, oneVoteOnly: %s' % (str(self.disabled).lower(), str(self.single_vote).lower()) wrapper = DIV(SPAN(_id="stars-cap"), _id="stars-wrapper_%s" % uid) from gluon.sqlhtml import OptionsWidget inp = OptionsWidget.widget(f,v) scr = SCRIPT('jQuery("#stars-wrapper_%s").stars('\ '{inputType: "select", %s});' % (uid, opts)) scr2 = SCRIPT('$("form").submit(function() {$("[name=%s]").removeAttr("disabled");});'% f.name) wrapper.append(inp) wrapper.append(scr) wrapper.append(scr2) return wrapper
def widget(field, value, **attributes): """ generates a TABLE tag, including INPUT radios (only 1 option allowed) see also: :meth:`FormWidget.widget` """ attr = OptionsWidget._attributes(field, {}, **attributes) requires = field.requires if not isinstance(requires, (list, tuple)): requires = [requires] if requires: if hasattr(requires[0], 'options'): options = requires[0].options() else: raise SyntaxError('widget cannot determine options of %s' % field) options = [(k, v) for k, v in options if str(v)] opts = [] cols = attributes.get('cols', 1) totals = len(options) mods = totals % cols rows = totals / cols if mods: rows += 1 for r_index in range(rows): tds = [] for k, v in options[r_index * cols:(r_index + 1) * cols]: checked = {'_checked': 'checked'} if k == value else {} tds.append(LI(INPUT(_type='radio', _id='%s%s' % (field.name, k), _name=field.name, requires=attr.get('requires', None), hideerror=True, _value=k, value=value, **checked ), LABEL(v, _for='%s%s' % (field.name, k)))) opts.append(UL(tds, _style='list-style-type: none;')) if opts: opts[-1][0][0]['hideerror'] = False return DIV(*opts, **attr)
def _field_select(self, name, options=None, form_values=None, **attr): """ Returns a SELECT of field names @param name: the element name @param options: the report options @param form_values: the form values to populate the widget @param attr: the HTML attributes for the widget """ resource = self.resource if options and name in options: fields = options[name] else: fields = self._config("list_fields", None) if not fields: fields = [f.name for f in resource.readable_fields()] prefix = ( lambda v: "%s.%s" % (resource.alias, v) if "." not in v.split("$", 1)[0] else v.replace("~", resource.alias) ) attr = Storage(attr) if "_name" not in attr: attr["_name"] = name if "_id" not in attr: attr["_id"] = "report-%s" % name if form_values: value = form_values.get(name, "") else: value = "" if value: value = prefix(value) table = self.table rfields, j, l, d = resource.resolve_selectors(fields) opts = [ (prefix(f.selector), f.label) for f in rfields if f.show and (f.field is None or f.field.name != table._id.name) ] dummy_field = Storage(name=name, requires=IS_IN_SET(opts)) return OptionsWidget.widget(dummy_field, value, **attr)
def _field_select(self, name, options=None, form_values=None, **attr): """ Returns a SELECT of field names @param name: the element name @param options: the report options @param form_values: the form values to populate the widget @param attr: the HTML attributes for the widget """ resource = self.resource if options and name in options: fields = options[name] else: fields = self._config("list_fields", None) if not fields: fields = [f.name for f in resource.readable_fields()] prefix = lambda v: "%s.%s" % (resource.alias, v) \ if "." not in v.split("$", 1)[0] \ else v.replace("~", resource.alias) attr = Storage(attr) if "_name" not in attr: attr["_name"] = name if "_id" not in attr: attr["_id"] = "report-%s" % name if form_values: value = form_values.get(name, "") else: value = "" if value: value = prefix(value) table = self.table rfields, j, l, d = resource.resolve_selectors(fields) opts = [ (prefix(f.selector), f.label) for f in rfields if f.show and (f.field is None or f.field.name != table._id.name) ] dummy_field = Storage(name=name, requires=IS_IN_SET(opts)) return OptionsWidget.widget(dummy_field, value, **attr)
def widget(self, field, value): #generate the standard widget for this field from gluon.sqlhtml import OptionsWidget select_widget = OptionsWidget.widget(field, value) #get the widget's id (need to know later on so can tell #receiving controller what to update) my_select_id = select_widget.attributes.get('_id', None) add_args = [my_select_id] #create a div that will load the specified controller via ajax form_loader_div = DIV(LOAD(c=self.controller, f=self.function, args=add_args,ajax=True), _id=my_select_id+"_dialog-form", _title=self.form_title) #generate the "add" button that will appear next the options #widget and open our dialog activator_button = A(T(self.button_text), _id=my_select_id+"_option_add_trigger") #create javascript for creating and opening the dialog js = 'jQuery( "#%s_dialog-form" ).dialog({autoOpen: false, show: "blind", hide: "explode", width: %s});' % (my_select_id, self.dialog_width) js += 'jQuery( "#%s_option_add_trigger" ).click(function() { jQuery( "#%s_dialog-form" ).dialog( "open" );return false;}); ' % (my_select_id, my_select_id) js += 'jQuery(function() { jQuery( "#%s_option_add_trigger" ).button({text: true, icons: { primary: "ui-icon-circle-plus"} }); });' % (my_select_id) jq_script=SCRIPT(js, _type="text/javascript") wrapper = DIV(_id=my_select_id+"_adder_wrapper") wrapper.components.extend([select_widget, form_loader_div, activator_button, jq_script]) return wrapper
def get_custom_element_function(self,field): from gluon.sqlhtml import OptionsWidget if OptionsWidget.has_options(field): widget=SQLFORM.widgets.options.widget(field,'no_selection').xml() script= """ function (value, options) { var el = document.createElement('div'); el.innerHTML='%s'.replace('>'+value+'<',' selected="selected">'+value+'<'); el.children[0].style.width="100%%"; return el; }""" % widget; return script; elif field.type=='boolean': return "get_bool_widget" else: if field.type=='time': calendar="el.children[0].onfocus=function(){time_setup(this.attributes['id'].value);};" elif field.type=='date': calendar="el.children[0].onfocus=function(){calendar_setup_date(this.attributes['id'].value);};" elif field.type=='datetime': calendar="el.children[0].onfocus=function(){calendar_setup_datetime(this.attributes['id'].value);};" elif field.type=='double': calendar="el.children[0].onfocus=function(){double_setup(this);};" elif field.type=='integer': calendar="el.children[0].onfocus=function(){integer_setup(this);};" else: calendar="" if field.widget: widget=field.widget(field,'a_value').xml().replace('<','\<').replace('>','\>').replace("'","\\'") else: widget=SQLFORM.widgets[field.type].widget(field,'a_value').xml() str=""" function (value, options) {var el = document.createElement('div'); el.innerHTML='%s'.replace('a_value',value); %s el.children[0].style.width="100%%"; return el; }""" return str% (widget,calendar);
def widget(self, field, value): LookupWidget.widget_files() width = self.width or getattr(field, "width_lookup", None) attr = {} if not width: attr["_class"] = "span4" attr["_style"] = "height: 20px; margin-bottom: 14px;" if width: attr["_style"] += "width:%s;" % width wgt_default = OptionsWidget.widget(field, value, **attr) wgt_id = wgt_default.attributes.get("_id", "no_id") js = """ jQuery(document).ready(function(){ jQuery('#%(field_name)s').select2(); }); """ % { "field_name": wgt_id } jq_script = SCRIPT(js, _type="text/javascript") btn_new = "" if self.add_new: btn_new = A( I(_class="fa fa-plus-circle"), _href=self.add_new, _class="btn btn-small", _title=current.T("New record"), _style="margin-top: 0px; margin-left:3px;", **{"_data-toggle": "tooltip"} ) wrapper = DIV(_class="LookupWidget") wrapper.components.extend([wgt_default, btn_new, jq_script]) return wrapper
def layer_options(self, options=None, get_vars=None, widget_id=None): """ Construct an OptionsWidget for the fact layer @param options: the report options @param get_vars: the GET vars if the request (as dict) @param widget_id: the HTML element ID for the widget """ resource = self.resource from s3data import S3PivotTable all_methods = S3PivotTable.METHODS # Get all layers layers = None methods = None if options: if "methods" in options: methods = options["methods"] if "fact" in options: layers = options["fact"] if not layers: layers = resource.get_config("list_fields") if not layers: layers = [f.name for f in resource.readable_fields()] if not methods: methods = all_methods # Resolve layers prefix = resource.prefix_selector opts = [] for layer in layers: # Extract layer option if type(layer) is tuple and \ (isinstance(layer[0], lazyT) or layer[1] not in all_methods): opt = [layer] else: opt = list(layer) \ if isinstance(layer, (tuple, list)) else [layer] # Get field label and selector s = opt[0] if isinstance(s, tuple): label, selector = s else: label, selector = None, s selector = prefix(selector) # Resolve the selector rfield = resource.resolve_selector(selector) if not rfield.field and not rfield.virtual: continue if label is not None: rfield.label = label # Autodetect methods? if len(opt) == 1: # Only field given -> auto-detect aggregation methods is_amount = None ftype = rfield.ftype if ftype == "integer": is_amount = True requires = rfield.requires if not isinstance(requires, (list, tuple)): requires = [requires] for r in requires: if isinstance(r, IS_IN_SET) or \ isinstance(r, IS_EMPTY_OR) and \ isinstance(r.other, IS_IN_SET): is_amount = False elif ftype == "double": is_amount = True elif ftype[:9] == "reference" or \ ftype[:5] == "list:" or \ ftype in ("id", "string", "text"): is_amount = False if ftype in ("datetime", "date", "time"): mopts = ["min", "max", "list"] elif is_amount is None: mopts = ["sum", "min", "max", "avg", "count", "list"] elif is_amount: mopts = ["sum", "min", "max", "avg"] else: mopts = ["count", "list"] opts.extend([(rfield, selector, m) for m in mopts if m in methods]) else: # Explicit method specified opt.insert(0, rfield) opts.append(opt) # Construct default labels T = current.T RECORDS = T("Records") layer_opts = [] mname = S3PivotTable._get_method_label for opt in opts: rfield, selector, method = opt[:3] if method not in methods: continue if len(opt) == 4: layer_label = opt[3] else: mlabel = mname(method) flabel = rfield.label if rfield.label != "Id" else RECORDS layer_label = T("%s (%s)") % (flabel, mlabel) layer_opts.append(("%s(%s)" % (method, selector), layer_label)) # Get current value if get_vars and "fact" in get_vars: layer = get_vars["fact"] else: layer = "" if layer: m = layer_pattern.match(layer) if m is None: layer = "" else: selector, method = m.group(2), m.group(1) selector = prefix(selector) layer = "%s(%s)" % (method, selector) # Field is read-only if there is only 1 option if len(layer_opts) == 1: default = layer_opts[0] return default[1], {"fact": default[0]} # Dummy field dummy_field = Storage(name="fact", requires=IS_IN_SET(layer_opts)) # Construct widget widget = OptionsWidget.widget(dummy_field, layer, _id=widget_id, _name="fact", _class="pt-fact") return widget, {}
def register(): """ Registration for Organisations - custom form """ s3mgr.load("pr_address") # Which type of organisation are we registering? don = False vol = False if "type" in request.vars: if request.vars.type == "don": don = True elif request.vars.type == "vol": vol = True auth.settings.registration_requires_approval = True auth.messages.submit_button = T("I accept. Create my account.") request.args = ["register"] _table_user.language.default = T.accepted_language _table_user.language.readable = False _table_user.language.writable = False form = auth() form.attributes["_id"] = "regform" # Custom class for Submit Button form[0][-1][0][0]["_class"] = "accept-button" # Cancel button form[0][-1][0].append(BR()) #form[0][-1][1].append(INPUT(_type="reset", _value=T("Cancel"))) form[0][-1][0].append(INPUT(_type="button", _value=T("Cancel"), _class="wide-grey-button", _onClick="javascript: history.go(-1)")) formstyle = s3.crud.formstyle # Organisation if form.errors.organisation: organisation_error = DIV(form.errors.organisation, _id="organisation__error", _class="error", _style="display: block;") else: organisation_error = "" if don: label = T("Corporation/Organization Name") else: label = T("Organization Name") row = formstyle(id = "organisation", label = LABEL("%s:" % label, SPAN(" *", _class="req")), widget = DIV(INPUT(_name="organisation", _id="organisation", _class="string"), organisation_error), comment = "") form[0].insert(0, row) # Industry Sector if vol: hidden = True widget = INPUT(_name="sector_id", _id="sector_id", _class="string") else: from gluon.sqlhtml import OptionsWidget hidden = False widget = OptionsWidget.widget(db.org_organisation.sector_id, value="") # dropdown row = formstyle(id = "sector_id", label = LABEL("%s:" % T("Industry Sector")), widget = widget, comment = "", hidden = hidden) form[0].insert(1, row) # freetext box for not listed row = formstyle(id = "sector_other", label = LABEL("%s:" % T("Other Sector not listed"), SPAN(" *", _class="req")), widget = INPUT(_name="sector_other", _id="org_organisation_sector_other", _class="string"), comment = "", hidden = True) form[0].insert(2, row) table = db.org_sector query = (table.uuid == "OTHER_UNLISTED") other_unlisted = db(query).select(table.id, limitby=(0, 1)).first() if other_unlisted: other_unlisted = other_unlisted.id # Primary Contact Person section row = TR(TD(LABEL(T("Primary Contact")), _colspan="3", _class="subheading")) form[0][2].append(row) row = formstyle(id = "middle_name", label = LABEL("%s:" % T("Middle Name")), widget = INPUT(_name="middle_name", _id="middle_name", _class="string"), comment = "") form[0][4].append(row) row = formstyle(id = "secondary_email", label = LABEL("%s:" % T("Secondary Email")), widget = INPUT(_name="secondary_email", _id="secondary_email", _class="string"), comment = "") form[0][12].append(row) # What are you offering? if don or vol: hidden = True else: hidden = False row = formstyle(id = "offer", hidden = hidden, label = LABEL("%s:" % T("We can offer"), SPAN(" *", _class="req")), widget = (T("Items"), INPUT(_type="checkbox", _value="on", value="on" if don else "", _name="has_items", _id="has_items", _class="boolean"), T("Volunteers"), INPUT(_type="checkbox", _value="on", value="on" if vol else "", _name="vols", _id="vols", _class="boolean"), ), comment = "") form[0][12].append(row) # Phone mobile_phone_widget = INPUT(_name="mobile_phone", _id="", _class="string") if form.errors.mobile_phone: mobile_phone_error = DIV(form.errors.mobile_phone, _id="mobile_phone__error", _class="error", _style="display: block;") # Can't wrap widget in a DIV for client-side validation, so only do so # when server-side validation happens mobile_phone_widget = DIV(mobile_phone_widget, mobile_phone_error) work_phone_widget = INPUT(_name="work_phone", _id="", _class="string") if form.errors.work_phone: work_phone_error = DIV(form.errors.work_phone, _id="work_phone__error", _class="error", _style="display: block;") # Can't wrap widget in a DIV for client-side validation, so only do so # when server-side validation happens work_phone_widget = DIV(work_phone_widget, work_phone_error) row = formstyle(id = "phone", label = LABEL("%s:" % T("Work Phone"), SPAN(" *", _class="req")), widget = work_phone_widget, comment = "") form[0][12].append(row) row = formstyle(id = "phone", label = LABEL("%s:" % current.deployment_settings.get_ui_label_mobile_phone(), #SPAN(" *", _class="req") ), widget = mobile_phone_widget, comment = "") form[0][12].append(row) # Address row = TR(TD(LABEL(T("Corporation/Organization Address")), _colspan="3", _class="subheading")) form[0][12].append(row) if form.errors.address1: address1_error = DIV(form.errors.address1, _id="address1__error", _class="error", _style="display: block;") else: address1_error = "" row = formstyle(id = "address1", label = LABEL("%s:" % T("Address 1"), SPAN(" *", _class="req") ), widget = (INPUT(_name="address1", _id="address1", _class="string"), address1_error), comment = "") form[0][12].append(row) row = formstyle(id = "address2", label = LABEL("%s:" % T("Address 2")), widget = INPUT(_name="address2", _id="address2", _class="string"), comment = "") form[0][12].append(row) row = formstyle(id = "city", label = LABEL("%s:" % T("City"), SPAN(" *", _class="req")), widget = INPUT(_name="city", _id = "city", _class = "string"), comment = "") form[0][12].append(row) states = S3LocationDropdownWidget(level="L1", default="California", empty=False) widget = states(db.pr_address.location_id, None) row = formstyle(id = "state", label = LABEL("%s:" % T("State"), SPAN(" *", _class="req")), widget = widget, comment = "") form[0][12].append(row) if form.errors.zip: zip_error = DIV(form.errors.zip, _id="zip__error", _class="error", _style="display: block;") else: zip_error = "" row = formstyle(id = "zip", label = LABEL("%s:" % T("Zip"), SPAN(" *", _class="req") ), widget = ( INPUT(_name="zip", _id="zip", _class="string"), zip_error ), comment = "") form[0][12].append(row) #form[0][-2].append(TR(TD(LABEL(T("Terms of Service:"), # _id="terms_of_service__label"), # _class="w2p_fl"), # TD(LABEL(TEXTAREA(deployment_settings.get_terms_of_service(), # _onfocus="this.rows=10", # _readonly="readonly", # _style="width:100%;text-align:", # _cols="80", _rows="10"), # _id="terms_of_service"), # _class="w2p_fw", # _colspan="2"), # _id="terms_of_service__row")) # Add client-side validation # simplified copy of s3_register_validation() script = "".join(( """ $('#org_organisation_sector_id').change(function() { var sector = $(this).val(); if (sector == '""", str(other_unlisted), """') { $('#sector_other1').show(); $('#sector_other').show(); } else { $('#sector_other1').hide(); $('#sector_other').hide(); } }); var required = '""", str(T("This field is required.")), """'; $('#regform').validate({ errorClass: 'req', rules: { first_name: { required: true }, last_name: { required: true }, email: { required: true, email: true }, organisation: { required: true }, sector_other: { required: true }, //mobile_phone: { // required: true //}, work_phone: { required: true }, address1: { required: true }, city: { required: true }, zip: { required: true }, password: { required: true }, password_two: { required: true, equalTo: '.password:first' } }, messages: { first_name: '""", str(T("Enter your firstname")), """', last_name: required, email: { required: '""", str(T("Please enter a valid email address")), """', minlength: '""", str(T("Please enter a valid email address")), """' }, organisation: required, sector_other: required, //mobile_phone: required, work_phone: required, address1: required, city: required, zip: required, password: { required: '""", str(T("Provide a password")), """' }, password_two: { required: '""", str(T("Repeat your password")), """', equalTo: '""", str(T("Enter the same password as above")), """' } }, errorPlacement: function(error, element) { error.appendTo( element.parent().next() ); }, submitHandler: function(form) { form.submit(); } });""" )) response.s3.jquery_ready.append( script ) if session.s3.debug: response.s3.scripts.append( "%s/jquery.validate.js" % s3_script_dir ) response.s3.scripts.append( "%s/jquery.pstrength.1.3.js" % s3_script_dir ) else: response.s3.scripts.append( "%s/jquery.validate.min.js" % s3_script_dir ) response.s3.scripts.append( "%s/jquery.pstrength.1.3.min.js" % s3_script_dir ) response.s3.jquery_ready.append("$('.password:first').pstrength();\n") response.s3.js_global.append("".join(( "S3.i18n.password_chars = '%s';\n" % T("The minimum number of characters is "), "S3.i18n.very_weak = '%s';\n" % T("Very Weak"), "S3.i18n.weak = '%s';\n" % T("Weak"), "S3.i18n.medium = '%s';\n" % T("Medium"), "S3.i18n.strong = '%s';\n" % T("Strong"), "S3.i18n.very_strong = '%s';\n" % T("Very Strong"), "S3.i18n.too_short = '%s';\n" % T("Too Short"), "S3.i18n.unsafe_password = '******';\n" % T("Unsafe Password Word!"), ))) response.title = T("Register") response.s3.has_required = True return dict(form=form)
def _method_select(self, name, options, form_values=None, **attr): """ Returns a SELECT of (field:method) options @param name: the element name @param options: the report options @param form_values: the form values to populate the widget @param attr: the HTML attributes for the widget """ RECORDS = current.T("Records") if "methods" in options: all_methods = options["methods"] else: all_methods = S3Report.METHODS resource = self.resource if options and name in options: methods = options[name] else: methods = self._config("list_fields", None) if not methods: methods = [f.name for f in resource.readable_fields()] prefix = lambda v: "%s.%s" % (resource.alias, v) \ if "." not in v.split("$", 1)[0] else v attr = Storage(attr) if "_name" not in attr: attr["_name"] = name if "_id" not in attr: attr["_id"] = "report-%s" % name if form_values: value = form_values.get(name, "") else: value = "" if value: value = prefix(value) # Backward-compatiblity: render aggregate if given -------------------- if "aggregate" in form_values and ":" not in value: value = "%s:%s" % (form_values["aggregate"], value) # Resolve selectors, add method options ------------------------------- opts = [] for o in methods: if type(o) is tuple and isinstance(o[0], lazyT): # Backward compatibility opt = [o] else: opt = list(o) if isinstance(o, (tuple, list)) else [o] s = opt[0] if isinstance(s, tuple): label, selector = s else: label, selector = None, s selector = prefix(selector) rfield = resource.resolve_selector(selector) if label is not None: rfield.label = label else: label = rfield.label if rfield.label != "Id" else RECORDS if len(opt) == 1: is_amount = None # Only field given -> auto-detect aggregation methods ftype = rfield.ftype if ftype == "integer": is_amount = True requires = rfield.requires if not isinstance(requires, (list, tuple)): requires = [requires] for r in requires: if isinstance(r, IS_IN_SET) or \ isinstance(r, IS_EMPTY_OR) and \ isinstance(r.other, IS_IN_SET): is_amount = False elif ftype == "double": is_amount = True elif ftype[:9] == "reference" or \ ftype[:5] == "list:" or \ ftype in ("id", "string", "text"): is_amount = False if ftype in ("datetime", "date", "time"): mopts = ["min", "max", "list"] elif is_amount is None: mopts = ["sum", "min", "max", "avg", "count", "list"] elif is_amount: mopts = ["sum", "min", "max", "avg"] else: mopts = ["count", "list"] opts.extend([(rfield, opt[0], m) for m in mopts if m in all_methods]) else: opt.insert(0, rfield) opts.append(opt) # Construct missing labels -------------------------------------------- _methods = [] for opt in opts: if len(opt) == 3: # field+method -> construct label mlabel = self.mname(opt[2]) flabel = opt[0].label if opt[0].label != "Id" else RECORDS label = current.T("%s (%s)") % (flabel, mlabel) _methods.append((opt[0].selector, opt[2], label)) else: _methods.append((opt[0].selector, opt[2], opt[3])) # Build the widget ---------------------------------------------------- opts = [("%s:%s" % (m[1], m[0]), m[2]) for m in _methods] if len(opts) == 1: opt = opts[0] return opt[1], {name: opt[0]} dummy_field = Storage(name=name, requires=IS_IN_SET(opts)) return OptionsWidget.widget(dummy_field, value, **attr), {}
opt = w.element(_value=self.value) i = w.elements().index(opt) w.append(opt) del w[i - 1] else: print e except Exception, e: print e, type(e) pprint([e["_value"] for e in w.elements()]) else: if self.orderby or self.rval or self.restrictor: w = FilteredOptionsWidget.widget( self.field, self.value, orderby=self.orderby, restricted=self.restricted, rval=self.rval ) else: w = OptionsWidget.widget(self.field, self.value) w["_id"] = "{}_{}".format(self.fieldset[0], self.fieldset[1]) w["_name"] = self.fieldset[1] myclasses = "plugin_ajaxselect " if not self.multi in [None, False, "False"]: myclasses += "multiple " if not self.restrictor in [None, "None", "none"]: myclasses += "restrictor for_{} ".format(self.restrictor) if not self.restricted in [None, "None", "none"]: myclasses += "restricted by_{} ".format(self.restricted) w["_class"] = myclasses return w def _make_refresher(self, wrappername, linktable, uargs, uvars):
def layer_options(self, options=None, get_vars=None, widget_id=None): """ Construct an OptionsWidget for the fact layer @param options: the report options @param get_vars: the GET vars if the request (as dict) @param widget_id: the HTML element ID for the widget """ resource = self.resource from s3data import S3PivotTable all_methods = S3PivotTable.METHODS # Get all layers layers = None methods = None if options: if "methods" in options: methods = options["methods"] if "fact" in options: layers = options["fact"] if not layers: layers = resource.get_config("list_fields") if not layers: layers = [f.name for f in resource.readable_fields()] if not methods: methods = all_methods # Resolve layer options T = current.T RECORDS = T("Records") mname = S3PivotTable._get_method_label def layer_label(rfield, method): """ Helper to construct a layer label """ mlabel = mname(method) flabel = rfield.label if rfield.label != "Id" else RECORDS # @ToDo: Exclude this string from admin/translate exports return T("%s (%s)") % (flabel, mlabel) prefix = resource.prefix_selector layer_opts = [] for layer in layers: # Parse option if type(layer) is tuple: label, s = layer else: label, s = None, layer match = layer_pattern.match(s) if match is not None: s, m = match.group(2), match.group(1) else: m = None # Resolve the selector selector = prefix(s) rfield = resource.resolve_selector(selector) if not rfield.field and not rfield.virtual: continue if m is None and label: rfield.label = label if m is None: # Only field given -> auto-detect aggregation methods is_amount = None ftype = rfield.ftype if ftype == "integer": is_amount = True requires = rfield.requires if not isinstance(requires, (list, tuple)): requires = [requires] for r in requires: if isinstance(r, IS_IN_SET) or \ isinstance(r, IS_EMPTY_OR) and \ isinstance(r.other, IS_IN_SET): is_amount = False elif ftype == "double": is_amount = True elif ftype[:9] == "reference" or \ ftype[:5] == "list:" or \ ftype in ("id", "string", "text"): is_amount = False if ftype in ("datetime", "date", "time"): mopts = ["min", "max", "list"] elif is_amount is None: mopts = ["sum", "min", "max", "avg", "count", "list"] elif is_amount: mopts = ["sum", "min", "max", "avg"] else: mopts = ["count", "list"] for method in mopts: if method in methods: label = layer_label(rfield, method) layer_opts.append( ("%s(%s)" % (method, selector), label)) else: # Explicit method specified if label is None: label = layer_label(rfield, m) layer_opts.append(("%s(%s)" % (m, selector), label)) # Get current value if get_vars and "fact" in get_vars: layer = get_vars["fact"] else: layer = "" if layer: match = layer_pattern.match(layer) if match is None: layer = "" else: selector, method = match.group(2), match.group(1) selector = prefix(selector) layer = "%s(%s)" % (method, selector) if len(layer_opts) == 1: # Field is read-only if there is only 1 option default = layer_opts[0] widget = TAG[""](default[1], INPUT(_type="hidden", _id=widget_id, _name=widget_id, _value=default[0])) single = True else: # Render Selector dummy_field = Storage(name="fact", requires=IS_IN_SET(layer_opts)) widget = OptionsWidget.widget(dummy_field, layer, _id=widget_id, _name="fact", _class="pt-fact") single = False return widget, single
def _create_widget(self): """ Create either a single select widget or multiselect widget """ if self.multi not in [None, False, 'False']: if self.orderby or self.rval: w = FilteredMultipleOptionsWidget.widget( self.field, self.value, orderby=self.orderby, multiple='multiple', restricted=self.restricted, rval=self.rval) else: w = MultipleOptionsWidget.widget(self.field, self.value) # place selected items at end of sortable select widget if self.sortable: print('trying to sort values =============') print('value is', self.value) try: for v in self.value: print('1') opt = w.element(_value=str(v)) print('2') i = w.elements().index(opt) print('3') w.append(opt) print('4') del w[i - 1] except AttributeError as e: print('error with', v) if type(v) == 'IntType': opt = w.element(_value=self.value) i = w.elements().index(opt) w.append(opt) del w[i - 1] else: print(e) except Exception as e: print(e, type(e)) pprint([elem['_value'] for elem in w.elements()]) else: if self.orderby or self.rval or self.restrictor: w = FilteredOptionsWidget.widget(self.field, self.value, orderby=self.orderby, restricted=self.restricted, rval=self.rval) else: w = OptionsWidget.widget(self.field, self.value) w['_id'] = '{}_{}'.format(self.fieldset[0], self.fieldset[1]) w['_name'] = self.fieldset[1] myclasses = 'plugin_ajaxselect ' if self.multi not in [None, False, 'False']: myclasses += 'multiple ' if self.restrictor not in [None, 'None', 'none']: myclasses += 'restrictor for_{} '.format(self.restrictor) if self.restricted not in [None, 'None', 'none']: myclasses += 'restricted by_{} '.format(self.restricted) w['_class'] = myclasses return w
def layer_options(self, options=None, get_vars=None, widget_id=None): """ Construct an OptionsWidget for the fact layer @param options: the report options @param get_vars: the GET vars if the request (as dict) @param widget_id: the HTML element ID for the widget """ resource = self.resource from s3data import S3PivotTable all_methods = S3PivotTable.METHODS # Get all layers layers = None methods = None if options: if "methods" in options: methods = options["methods"] if "fact" in options: layers = options["fact"] if not layers: layers = resource.get_config("list_fields") if not layers: layers = [f.name for f in resource.readable_fields()] if not methods: methods = all_methods # Resolve layer options T = current.T RECORDS = T("Records") mname = S3PivotTable._get_method_label def layer_label(rfield, method): """ Helper to construct a layer label """ mlabel = mname(method) flabel = rfield.label if rfield.label != "Id" else RECORDS return T("%s (%s)") % (flabel, mlabel) prefix = resource.prefix_selector layer_opts = [] for layer in layers: # Parse option if type(layer) is tuple: label, s = layer else: label, s = None, layer match = layer_pattern.match(s) if match is not None: s, m = match.group(2), match.group(1) else: m = None # Resolve the selector selector = prefix(s) rfield = resource.resolve_selector(selector) if not rfield.field and not rfield.virtual: continue if m is None and label: rfield.label = label if m is None: # Only field given -> auto-detect aggregation methods is_amount = None ftype = rfield.ftype if ftype == "integer": is_amount = True requires = rfield.requires if not isinstance(requires, (list, tuple)): requires = [requires] for r in requires: if isinstance(r, IS_IN_SET) or \ isinstance(r, IS_EMPTY_OR) and \ isinstance(r.other, IS_IN_SET): is_amount = False elif ftype == "double": is_amount = True elif ftype[:9] == "reference" or \ ftype[:5] == "list:" or \ ftype in ("id", "string", "text"): is_amount = False if ftype in ("datetime", "date", "time"): mopts = ["min", "max", "list"] elif is_amount is None: mopts = ["sum", "min", "max", "avg", "count", "list"] elif is_amount: mopts = ["sum", "min", "max", "avg"] else: mopts = ["count", "list"] for method in mopts: if method in methods: label = layer_label(rfield, method) layer_opts.append(("%s(%s)" % (method, selector), label)) else: # Explicit method specified if label is None: label = layer_label(rfield, m) layer_opts.append(("%s(%s)" % (m, selector), label)) # Get current value if get_vars and "fact" in get_vars: layer = get_vars["fact"] else: layer = "" if layer: match = layer_pattern.match(layer) if match is None: layer = "" else: selector, method = match.group(2), match.group(1) selector = prefix(selector) layer = "%s(%s)" % (method, selector) if len(layer_opts) == 1: # Field is read-only if there is only 1 option default = layer_opts[0] widget = TAG[""](default[1], INPUT(_type="hidden", _id=widget_id, _name=widget_id, _value=default[0])) single = True else: # Render Selector dummy_field = Storage(name="fact", requires=IS_IN_SET(layer_opts)) widget = OptionsWidget.widget(dummy_field, layer, _id=widget_id, _name="fact", _class="pt-fact") single = False return widget, single
if type(v) == 'IntType': opt = w.element(_value=self.value) i = w.elements().index(opt) w.append(opt) del w[i - 1] else: print e except Exception, e: print e, type(e) else: if self.orderby: w = FilteredOptionsWidget.widget(self.field, self.value, orderby=self.orderby) else: w = OptionsWidget.widget(self.field, self.value) w['_id'] = '{}_{}'.format(self.fieldset[0], self.fieldset[1]) w['_name'] = self.fieldset[1] return w def make_refresher(self, wrappername, linktable, uargs, uvars): ''' Return link to refresh this widget via ajax. The widget is always created, since its href attribute is used to pass several values to the client-side javascripts. If the widget is instantiated with the 'refresher' parameter set to False, then the link is hidden via CSS. ''' refresher_id = '{}_refresh_trigger'.format(linktable)
def has_lookups(self,field): from gluon.sqlhtml import OptionsWidget return OptionsWidget.has_options(field)
def _method_select(self, name, options, form_values=None, **attr): """ Returns a SELECT of (field:method) options @param name: the element name @param options: the report options @param form_values: the form values to populate the widget @param attr: the HTML attributes for the widget """ T = current.T RECORDS = T("Records") if "methods" in options: all_methods = options["methods"] else: all_methods = S3Report.METHODS resource = self.resource if options and name in options: methods = options[name] else: methods = self._config("list_fields", None) if not methods: methods = [f.name for f in resource.readable_fields()] prefix = lambda v: "%s.%s" % (resource.alias, v) \ if "." not in v.split("$", 1)[0] \ else v.replace("~", resource.alias) attr = Storage(attr) if "_name" not in attr: attr["_name"] = name if "_id" not in attr: attr["_id"] = "report-%s" % name if form_values: value = form_values.get(name, "") else: value = "" if value: value = prefix(value) # Backward-compatiblity: render aggregate if given if "aggregate" in form_values and ":" not in value: value = "%s:%s" % (form_values["aggregate"], value) # Resolve selectors, add method options opts = [] for o in methods: if type(o) is tuple and isinstance(o[0], lazyT): # Backward compatibility opt = [o] else: opt = list(o) if isinstance(o, (tuple, list)) else [o] s = opt[0] if isinstance(s, tuple): label, selector = s else: label, selector = None, s selector = prefix(selector) rfield = resource.resolve_selector(selector) if not rfield.field and not rfield.virtual: continue if label is not None: rfield.label = label else: label = rfield.label if rfield.label != "Id" else RECORDS if len(opt) == 1: is_amount = None # Only field given -> auto-detect aggregation methods ftype = rfield.ftype if ftype == "integer": is_amount = True requires = rfield.requires if not isinstance(requires, (list, tuple)): requires = [requires] for r in requires: if isinstance(r, IS_IN_SET) or \ isinstance(r, IS_EMPTY_OR) and \ isinstance(r.other, IS_IN_SET): is_amount = False elif ftype == "double": is_amount = True elif ftype[:9] == "reference" or \ ftype[:5] == "list:" or \ ftype in ("id", "string", "text"): is_amount = False if ftype in ("datetime", "date", "time"): mopts = ["min", "max", "list"] elif is_amount is None: mopts = ["sum", "min", "max", "avg", "count", "list"] elif is_amount: mopts = ["sum", "min", "max", "avg"] else: mopts = ["count", "list"] opts.extend([(rfield, opt[0], m) for m in mopts if m in all_methods]) else: opt.insert(0, rfield) opts.append(opt) # Construct missing labels _methods = [] for opt in opts: if len(opt) == 3: # field+method -> construct label mlabel = self.mname(opt[2]) flabel = opt[0].label if opt[0].label != "Id" else RECORDS label = T("%s (%s)") % (flabel, mlabel) _methods.append((opt[0].selector, opt[2], label)) else: _methods.append((opt[0].selector, opt[2], opt[3])) # Build the widget opts = [("%s:%s" % (m[1], m[0]), m[2]) for m in _methods] if len(opts) == 1: opt = opts[0] return opt[1], {name: opt[0]} dummy_field = Storage(name=name, requires=IS_IN_SET(opts)) return OptionsWidget.widget(dummy_field, value, **attr), {}