def test_decode(self): T = languages.translator(self.langpath, self.http_accept_language) elem = SPAN(T("Complete")) self.assertEqual(elem.flatten(), "Complete") elem = SPAN(T("Cannot be empty", language="ru")) self.assertEqual(elem.xml(), to_bytes('<span>Пустое значение недопустимо</span>')) self.assertEqual(elem.flatten(), 'Пустое значение недопустимо')
def host_a_maker(record=None): """ Give a host record, return a A object that will open a new window to that host record """ from gluon.html import A, I, URL, SPAN if record is None: return A() if isinstance(record, type([str, int])): record = get_host_record(record) host_a = A(host_title_maker(record), _target="host_detail_%s" % (record.id), _href=URL('hosts', 'detail', extension='html', args=record.id)) info_a = SPAN(A(I(_class='icon-info-sign'), _href='#', _class='withajaxpopover', **{ '_data-load': URL('hosts', 'popover.json', args=record.id), '_data-trigger': 'hover', '_data-delay': "{show: 500, hide: 100}", '_data-placement': 'right', '_data-html': 'true', '_data-container': '#popoverwrap' }), _id="popoverwrap") return SPAN(host_a, info_a)
def get_delete_lst(fields_lst): rtable = TABLE(_style="width: 100%;") rtable.append(TR(TD(DIV(T("SELECT ROW"),_class="div_label",_style="color: #FFD700;"),_class="td_label", _style="width: auto;border-bottom-style: double;border-width: 4px;border-color: #8B8B83;"), TD(SPAN("1",_class="div_label",_style=checklabel_style), INPUT(_type="checkbox",_value="on",_checked="checked",_disabled="disabled",_name="selrow",_id="row_1",_class="boolean", _style="vertical-align: middle;"), _class="td_input", _style=checkbox_style), TD(SPAN("2",_class="div_label",_style=checklabel_style), INPUT(_type="checkbox",_value="on",_name="selrow",_id="row_2",_class="boolean", _style="vertical-align: middle;"), _class="td_input", _style=checkbox_style), TD(SPAN("3",_class="div_label",_style=checklabel_style), INPUT(_type="checkbox",_value="on",_name="selrow",_id="row_3",_class="boolean", _style="vertical-align: middle;"), _class="td_input", _style=checkbox_style), TD(SPAN("4",_class="div_label",_style=checklabel_style), INPUT(_type="checkbox",_value="on",_name="selrow",_id="row_4",_class="boolean", _style="vertical-align: middle;"), _class="td_input", _style=checkbox_style), )) for field in fields_lst: if field["fieldcat"]==0: rtable.append(TR(TD(DIV(field["label"],_class="div_label"),_class="td_label",_style="width: auto;"), TD(field["widget"],_class="td_input", _style="width: auto;", _id="1"), TD(field["widget"],_class="td_input", _style="width: auto;", _id="2"), TD(field["widget"],_class="td_input", _style="width: auto;", _id="3"), TD(field["widget"],_class="td_input", _style="width: auto;", _id="4") )) return rtable
def imp_info(imp): iorder = imp[1] lbl = SPAN('%s-%s' % (rik, iorder)) if uses_iid: lbl.append(' ') lbl.append(B(imp[2])) if uses_sgn: lbl.append(' ') lbl.append(imp[3]) imp_id = "%s" % imp[0] return A(lbl, _href=(URL(c, f, args=imp_id) if c else URL(f, args=imp_id)) if f else "#", _data_id=imp_id, _class='btn btn-warning')
def test_DIV(self): # Empty DIV() self.assertEqual(DIV().xml(), b'<div></div>') self.assertEqual(DIV('<>', _a='1', _b='2').xml(), b'<div a="1" b="2"><></div>') # attributes can be updated like in a dict div = DIV('<>', _a='1') div['_b'] = '2' self.assertEqual(div.xml(), b'<div a="1" b="2"><></div>') # also with a mapping div.update(_b=2, _c=3) self.assertEqual(div.xml(), b'<div a="1" b="2" c="3"><></div>') # length of the DIV is the number of components self.assertEqual(len(DIV('a', 'bc')), 2) # also if empty, DIV is True in a boolean evaluation self.assertTrue(True if DIV() else False) # parent and siblings a = DIV(SPAN('a'), DIV('b')) s = a.element('span') d = s.parent d['_class'] = 'abc' self.assertEqual(a.xml(), b'<div class="abc"><span>a</span><div>b</div></div>') self.assertEqual([el.xml() for el in s.siblings()], [b'<div>b</div>']) self.assertEqual(s.sibling().xml(), b'<div>b</div>') # siblings with wrong args self.assertEqual(s.siblings('a'), []) # siblings with good args self.assertEqual(s.siblings('div')[0].xml(), b'<div>b</div>') # Check for siblings with wrong kargs and value self.assertEqual(s.siblings(a='d'), []) # Check for siblings with good kargs and value # Can't figure this one out what is a right value here?? # Commented for now... # self.assertEqual(s.siblings(div='<div>b</div>'), ???) # No other sibling should return None self.assertEqual(DIV(P('First element')).element('p').sibling(), None) # -------------------------------------------------------------------------------------------------------------- # This use unicode to hit xmlescape() line : # """ # elif isinstance(data, unicode): # data = data.encode('utf8', 'xmlcharrefreplace') # """ self.assertEqual(DIV(u'Texte en français avec des caractères accentués...').xml(), b'<div>Texte en fran\xc3\xa7ais avec des caract\xc3\xa8res accentu\xc3\xa9s...</div>') # -------------------------------------------------------------------------------------------------------------- self.assertEqual(DIV('Test with an ID', _id='id-of-the-element').xml(), b'<div id="id-of-the-element">Test with an ID</div>') self.assertEqual(DIV().element('p'), None) # Corner case for raise coverage of one line # I think such assert fail cause of python 2.6 # Work under python 2.7 # with self.assertRaises(SyntaxError) as cm: # DIV(BR('<>')).xml() # self.assertEqual(cm.exception[0], '<br/> tags cannot have components') # test .get('attrib') self.assertEqual(DIV('<p>Test</p>', _class="class_test").get('_class'), 'class_test')
def myfolderwidget(field, value, **attributes): _id = "%s_%s" % (field._tablename, field.name) attr = attributes attributes['_class'] = "%sfolders span10" % attributes.get('_class', ' ') _style = "display: inline-block;" attributes['_style'] = _style default_input = SQLFORM.widgets.string.widget(field, value, **attributes) return DIV(SPAN(I(_class="icon-folder-open"),_class="add-on"),default_input, _class="input-prepend span9", _style=_style)
def myfolderwidgetmultiple(field, value, **attributes): _id = '%s_%s' % (field._tablename, field.name) _name = field.name _class = 'string folders span10' _style = "display: inline-block;" requires = field.requires if isinstance(field.requires, (IS_NOT_EMPTY, IS_LIST_OF)) else None items = [ LI( DIV(SPAN(I(_class="icon-folder-open"), _class="add-on"), INPUT(_class=_class, _name=_name, value=v, hideerror=True, requires=requires, _style=_style), _class="input-prepend span9", _style=_style)) for v in value or [''] ] script = SCRIPT(""" // from http://refactormycode.com/codes/694-expanding-input-list-using-jquery (function(){ jQuery.fn.grow_input_fold = function() { return this.each(function() { var ul = this; jQuery(ul).find(":text").after('<a href="javascript:void(0)">+</a>').keypress(function (e) { return (e.which == 13) ? pe(ul) : true; }).next().click(function(){ pe(ul) }); }); }; function pe(ul) { var new_line = ml(ul); rel(ul); new_line.appendTo(ul); new_line.find(":text").focus().after('<a href="javascript:void(0)">+</a>').keypress(function (e) { return (e.which == 13) ? pe(ul) : true; }).next().click(function(){ pe(ul) }); new_line.find(":text").scanfolders(); return false; } function ml(ul) { var line = jQuery(ul).find("li:first").clone(); line.find(':text').val(''); line.find('a').remove(); return line; } function rel(ul) { return; jQuery(ul).find("li").each(function() { var trimmed = jQuery.trim(jQuery(this.firstChild).val()); if (trimmed=='') jQuery(this).remove(); else jQuery(this.firstChild).val(trimmed); }); } })(); jQuery(document).ready(function(){ jQuery('#%s_grow_input').grow_input_fold(); }); """ % _id) attributes['_id'] = _id + '_grow_input' return TAG[''](UL(*items, _class="unstyled", **attributes), script)
def nice_worker_stats(stats): collect = [] if 'errors' in stats: collect.append(SPAN("Errors", SPAN(stats['errors'], _class="badge"), _class="list-group-item")) if 'total' in stats: collect.append(SPAN("Total", SPAN(stats['total'], _class="badge"), _class="list-group-item")) if 'sleep' in stats: collect.append(SPAN("Sleep", SPAN(stats['sleep'], _class="badge"), _class="list-group-item")) if 'empty_runs' in stats: collect.append(SPAN("Empty loops", SPAN(stats['empty_runs'], _class="badge"), _class="list-group-item")) return DIV(collect, _class="list-group")
def _inner(form, fields): form.add_class('form-horizontal') label_col_class = "col-sm-%d" % col_label_size col_class = "col-sm-%d" % (12 - col_label_size - col_help_size) col_class_rest = "col-sm-%d" % (12 - col_label_size) offset_class = "col-sm-offset-%d" % col_label_size help_class = "col-sm-%d" % col_help_size parent = CAT() for id, label, controls, help in fields: # wrappers _help = DIV(SPAN(help, _class='help-block'), _class="%s" % (help_class)) # embed _help into _controls _controls = DIV(controls, _class="%s" % (col_class)) if isinstance(controls, INPUT): if controls['_type'] == 'submit': controls.add_class('btn btn-primary') _controls = DIV(DIV(controls, _class="btn-group-sm"), _class="%s %s" % (col_class_rest, offset_class)) if controls['_type'] == 'button': controls.add_class('btn btn-default') elif controls['_type'] == 'file': controls.add_class('input-file') controls.add_class(input_class) elif controls['_type'] in ('text', 'password'): controls.add_class('form-control') controls.add_class(input_class) elif controls['_type'] == 'checkbox': label['_for'] = None label.insert(0, controls) label.insert(1, ' ') _controls = DIV(DIV(label, _class="checkbox"), _class="%s %s" % (offset_class, col_class)) label = '' elif isinstance(controls, (SELECT, TEXTAREA)): controls.add_class('form-control') controls.add_class(input_class) elif isinstance(controls, SPAN): _controls = P(controls.components, _class="form-control-static %s" % col_class) elif isinstance(controls, UL): for e in controls.elements("input"): e.add_class('form-control') else: _controls = DIV(controls, _class="small %s" % (col_class)) if isinstance(label, LABEL): label['_class'] = add_class( label.get('_class'), '%s %s' % (control_label, label_col_class)) parent.append(DIV(label, _controls, _help, _class='row', _id=id)) return DIV(parent, _class='form-group')
def highlightWords(text, words): if not text or not words: return text if type(words) is str: if re.search(words, text, re.IGNORECASE): begin = re.search(words, text, re.IGNORECASE).start() end = begin + len(words) return CAT(text[:begin], SPAN(text[begin:end], _class="highlighted"), highlightWords(text[end:], words)) else: return text
def mybootstrap(form, fields): ''' bootstrap format form layout ''' form.add_class('form-horizontal') parent = FIELDSET() for id, label, controls, help in fields: # wrappers _help = SPAN(help, _class='help-inline') if isinstance(controls, (str, int, SPAN)): controls = SPAN(controls, _class="input-xlarge uneditable-input") # embed _help into _controls _controls = DIV(controls, _help, _class='controls') # submit unflag by default _submit = False if isinstance(controls, INPUT): controls.add_class('input-xlarge') if controls['_type'] == 'submit': # flag submit button _submit = True controls['_class'] = 'btn btn-primary' if controls['_type'] == 'file': controls['_class'] = 'input-file' # For password fields, which are wrapped in a CAT object. if isinstance(controls, CAT) and isinstance(controls[0], INPUT): controls[0].add_class('input-xlarge') if isinstance(controls, SELECT): controls.add_class('input-xlarge') if isinstance(controls, TEXTAREA): controls['_rows'] = 1 controls.add_class('input-xlarge') if isinstance(label, LABEL): label['_class'] = 'control-label' if _submit: # submit button has unwrapped label and controls, different class parent.append(DIV(label, controls, _class='form-actions', _id=id)) # unflag submit (possible side effect) _submit = False else: # unwrapped label parent.append(DIV(label, _controls, _class='control-group', _id=id)) script = SCRIPT(""" $(function() { $('<span class="help-block">' + $('.error_wrapper .error').text() + '</span>'). appendTo($('.error_wrapper').closest('.controls')); $('.error_wrapper').hide().closest('.control-group').addClass('error'); })""") parent.append(script) return parent
def testJSON(self): # the main and documented "way" is to use the json() function # it has a few corner-cases that make json() be somewhat # different from the standard buyt being compliant # it's just a matter of conventions # incompatible spacing, newer simplejson already account # for this but it's still better to remember weird = {'JSON': u"ro" + u'\u2028' + u'ck' + u'\u2029' + u's!'} rtn = json(weird) self.assertEqual(rtn, u'{"JSON": "ro\\u2028ck\\u2029s!"}') # date, datetime, time strictly as strings in isoformat, minus the T objs = [ datetime.datetime(2014, 1, 1, 12, 15, 35), datetime.date(2014, 1, 1), datetime.time(12, 15, 35) ] iso_objs = [obj.isoformat()[:19].replace('T', ' ') for obj in objs] json_objs = [json(obj) for obj in objs] json_web2pyfied = [json(obj) for obj in iso_objs] self.assertEqual(json_objs, json_web2pyfied) # int or long int()ified # self.assertEqual(json(1), json(1)) # decimal stringified obj = {'a': decimal.Decimal('4.312312312312')} self.assertEqual(json(obj), u'{"a": "4.312312312312"}') # lazyT translated T = TranslatorFactory('', 'en') lazy_translation = T('abc') self.assertEqual(json(lazy_translation), u'"abc"') # html helpers are xml()ed before too self.assertEqual(json(SPAN('abc'), cls=None), u'"<span>abc</span>"') self.assertEqual(json(SPAN('abc')), u'"\\u003cspan\\u003eabc\\u003c/span\\u003e"') # unicode keys make a difference with loads_json base = {u'è': 1, 'b': 2} base_enc = json(base) base_load = loads_json(base_enc) self.assertTrue(base == base_load) # if unicode_keys is false, the standard behaviour is assumed base_load = loads_json(base_enc, unicode_keys=False) self.assertFalse(base == base_load)
def nice_species_name(scientific=None, common=None, the=False, html=False, leaf=False, first_upper=False, break_line=None): """ Constructs a nice species name, with common name in there too. If leaf=True, add a 'species' tag to the scientific name If break_line == 1, put a line break after common (if it exists) If break_line == 2, put a line break after sciname (even if common exists) TODO - needs internationalization """ from gluon.html import CAT, I, SPAN, BR db = current.db species_nicename = (scientific or '').replace('_', ' ').strip() common = (common or '').strip() if the: common = add_the(common, leaf) if first_upper: common = common.capitalize() if html: if species_nicename: if leaf: #species in italics species_nicename = I(species_nicename, _class=" ".join(["taxonomy", "species"])) else: species_nicename = SPAN(species_nicename, _class="taxonomy") if common: if break_line: return CAT(common, BR(), '(', species_nicename, ')') else: return CAT(common, ' (', species_nicename, ')') else: if break_line == 2: return CAT(BR(), species_nicename) else: return species_nicename else: return common else: if common and species_nicename: if break_line: return common + '\n(' + species_nicename + ')' else: return common + ' (' + species_nicename + ')' else: if break_line == 2: return common + "\n" + species_nicename else: return common + species_nicename
def gridbutton(buttonclass='buttonadd', buttontext='Add', buttonurl=url(args=[]), callback=None, delete=None, trap=True): if showbuttontext: if callback: return A(SPAN(_class=ui.get(buttonclass)), SPAN(T(buttontext), _title=buttontext, _class=ui.get('buttontext')), callback=callback, delete=delete, _class=trap_class(ui.get('button'), trap)) else: return A(SPAN(_class=ui.get(buttonclass)), SPAN(T(buttontext), _title=buttontext, _class=ui.get('buttontext')), _href=buttonurl, _class=trap_class(ui.get('button'), trap)) else: if callback: return A(SPAN(_class=ui.get(buttonclass)), callback=callback, delete=delete, _title=buttontext, _class=trap_class(ui.get('buttontext'), trap)) else: return A(SPAN(_class=ui.get(buttonclass)), _href=buttonurl, _title=buttontext, _class=trap_class(ui.get('buttontext'), trap))
def custom_formstyle(form, fields): col_label_size = 4 label_col_class = "col-sm-%d" % col_label_size col_class = "col-sm-%d" % (12 - col_label_size) offset_class = "col-sm-offset-%d" % col_label_size parent = TABLE(_class='table table-sm', _style='margin-top: 1.5rem') for id, label, controls, help in fields: # wrappers _help = SPAN(help, _class='help-block') # embed _help into _controls _controls = DIV(controls, _help, _class="%s" % (col_class)) if isinstance(controls, INPUT): if controls['_type'] == 'submit': controls.add_class('btn btn-primary') _controls = DIV(controls, _class="%s %s" % (col_class, offset_class)) if controls['_type'] == 'button': controls.add_class('btn btn-secondary') elif controls['_type'] == 'file': controls.add_class('input-file') elif controls['_type'] in ('text', 'password'): controls.add_class('form-control') elif controls['_type'] == 'checkbox' or controls['_type'] == 'radio': controls.add_class('form-check-input') label.add_class('form-check-label') label.insert(0, controls) _controls = DIV( DIV(label, _help, _class="form-check"), _class="%s" % col_class) label = DIV(_class="sm-hidden %s" % label_col_class) elif isinstance(controls, SELECT): controls.add_class('custom-select') elif isinstance(controls, TEXTAREA): controls.add_class('form-control') elif isinstance(controls, SPAN): _controls = P(controls.components, _class="form-control-plaintext %s" % col_class) elif isinstance(controls, UL): for e in controls.elements("input"): e.add_class('form-control') elif isinstance(controls, CAT) and isinstance(controls[0], INPUT): controls[0].add_class('form-control') if isinstance(label, LABEL): label.add_class( 'form-control-label font-weight-bold %s' % label_col_class) parent.append( DIV(label, _controls, _class='form-group row', _id=id)) return parent
def get_update_lst(fields_lst): rtable = TABLE(_style="width: 100%;") rtable.append(TR( TD(_style=checkbox_style2), TD(SPAN("1",_class="div_label",_style=checklabel_style), _class="td_input", _style=checkbox_style2+"padding-left:10px;padding-right:0px;"), TD(SPAN(T("ROW"),_class="div_label",_style=checklabel_style), _class="td_input", _style=checkbox_style2+"padding-left:0px;"), TD(SPAN("2",_class="div_label",_style=checklabel_style), _class="td_input", _style=checkbox_style2+"padding-right:0px;"), TD(SPAN(T("ROW"),_class="div_label",_style=checklabel_style), _class="td_input", _style=checkbox_style2+"padding-left:0px;"), TD(SPAN("3",_class="div_label",_style=checklabel_style), _class="td_input", _style=checkbox_style2+"padding-right:0px;"), TD(SPAN(T("ROW"),_class="div_label",_style=checklabel_style), _class="td_input", _style=checkbox_style2+"padding-left:0px;"), TD(SPAN("4",_class="div_label",_style=checklabel_style), _class="td_input", _style=checkbox_style2+"padding-right:0px;"), TD(SPAN(T("ROW"),_class="div_label",_style=checklabel_style), _class="td_input", _style=checkbox_style2+"padding-left:0px;") )) fieldcat=0 for field in fields_lst: style="width: auto;vertical-align: middle;" if field["fieldcat"]==2: style += "font-style:italic;" if fieldcat<2: style+="border-top-style: double;border-width: 4px;border-color: #8B8B83;" fieldcat=field["fieldcat"] rtable.append(TR( TD(DIV(field["label"],_class="div_label"), _class="td_label",_style=style), TD(INPUT(_type="checkbox",_value="on",_name="selfield",_id="select_"+field["fieldname"]+"_1",_class="boolean", _style="vertical-align: middle;"),_class="td_input", _style=style+"padding-right:0px;padding-left:10px;"), TD(field["widget"],_class="td_input", _style=style+"padding-left:0px;", _id="1"), TD(INPUT(_type="checkbox",_value="on",_name="selfield",_id="select_"+field["fieldname"]+"_2",_class="boolean", _style="vertical-align: middle;"),_class="td_input", _style=style+"padding-right:0px;padding-left:5px;"), TD(field["widget"],_class="td_input", _style=style+"padding-left:0px;", _id="2"), TD(INPUT(_type="checkbox",_value="on",_name="selfield",_id="select_"+field["fieldname"]+"_3",_class="boolean", _style="vertical-align: middle;"),_class="td_input", _style=style+"padding-right:0px;padding-left:5px;"), TD(field["widget"],_class="td_input", _style=style+"padding-left:0px;", _id="3"), TD(INPUT(_type="checkbox",_value="on",_name="selfield",_id="select_"+field["fieldname"]+"_4",_class="boolean", _style="vertical-align: middle;"),_class="td_input", _style=style+"padding-right:0px;padding-left:5px;"), TD(field["widget"],_class="td_input", _style=style+"padding-left:0px;", _id="4") )) return rtable
def mybootstrap(form, fields): ''' bootstrap format form layout ''' form.add_class('form-horizontal') parent = FIELDSET() for id, label, controls, help in fields: # wrappers _help = None if help: _help = SPAN(help, _class='help-block') if isinstance(controls, (str, int, SPAN)): controls = P(controls, _class="form-control-static") # submit unflag by default _submit = False if isinstance(controls, INPUT): if controls['_type'] == 'submit': # flag submit button _submit = True controls['_class'] = 'btn btn-primary' if controls['_type'] == 'file': controls['_class'] = 'input-file' if isinstance(label, LABEL): label['_class'] = 'col-sm-2 control-label' if _submit: # submit button has unwrapped label and controls, different class parent.append(DIV(DIV(controls,_class="col-sm-offset-2 col-sm-10"), _class='form-group form-group-sm', _id=id)) # unflag submit (possible side effect) _submit = False else: # unwrapped label if _help: parent.append(DIV(label, DIV(controls, _help, _class="col-sm-10"), _class='form-group form-group-sm', _id=id)) else: parent.append(DIV(label, DIV(controls, _class="col-sm-10"), _class='form-group form-group-sm', _id=id)) return parent
def test_SPAN(self): self.assertEqual( SPAN('<>', _a='1', _b='2').xml(), b'<span a="1" b="2"><></span>')
def __call__(self, field, value): mylogger.debug(message='current.request.vars:%s' % current.request.vars) mylogger.debug(message='field._tablename:%s' % (str(field._tablename))) mylogger.debug(message='field:%s' % (str(field))) mylogger.debug(message='field.name:%s' % (str(field.name))) mylogger.debug(message='field.type:%s' % (str(field.type))) mylogger.debug(message='field.requires:%s' % (str(field.requires))) mylogger.debug(message='type(value):%s' % (str(type(value)))) mylogger.debug(message='value:%s' % (str(value))) if current.request and current.request['function']: function = current.request['function'] function_configuration = self.configuration[ '*'] if self.configuration.keys().count( '*') > 0 else self.configuration[ function] if function in self.configuration.keys() else '' # query parameter not used yet... if 'query' in function_configuration: query = function_configuration['query'].as_json() else: query = None if 'disable_validate' in function_configuration: disable_validate = function_configuration['disable_validate'] else: disable_validate = False if 'add_in_db' in function_configuration: add_in_db = function_configuration['add_in_db'] else: add_in_db = False if 'multiple' in function_configuration: multiple = function_configuration['multiple'] else: multiple = False if 'submit_on_select' in function_configuration: submit_on_select = function_configuration['submit_on_select'] else: submit_on_select = False max_nb_item = 20 if 'max_nb_item' in function_configuration: max_nb_item = function_configuration['max_nb_item'] func_lambda = '' if 'func_lambda' in function_configuration: func_lambda = function_configuration['func_lambda'] # use this option for no required fields only, to force the user to confirm that the field is empty if 'confirm_empty' in function_configuration: confirm_empty = function_configuration['confirm_empty'] else: confirm_empty = current.request.vars[ 'confirm_empty_%s' % field. name] == 'on' if 'confirm_empty_%s' % field.name in current.request.vars else False is_not_a_reference = (field._tablename == self.ref_field._tablename) disabled = '_disabled' in self.attributes.keys() mylogger.debug(message='add_in_db:%s' % (str(add_in_db))) mylogger.debug(message='multiple:%s' % (str(multiple))) mylogger.debug(message='disabled:%s' % (str(disabled))) mylogger.debug(message='max_nb_item:%s' % (str(max_nb_item))) mylogger.debug(message='is_not_a_reference:%s' % (str(is_not_a_reference))) if (value) and (type(value) is StringType) and (value == '0'): nb_item = 0 elif (value) and (type(value) is StringType) and (value == '|0|'): nb_item = 0 elif (value) and (type(value) is ListType) and (value[0] == 0): nb_item = 0 elif (value) and (type(value) is ListType) and (value[0] == '|0|'): nb_item = 0 elif (value) and (type(value) is ListType): nb_item = len(value) elif value and value != '': nb_item = 1 else: nb_item = 0 if value and not type(value) is ListType and value != '': value = [value] mylogger.debug(message='nb_item:%s' % (str(nb_item))) # # basic widget structure # checkboxes_form = DIV() suggestions_form = DIV( _id='%s_suggestions' % (self.uid), _class='CHIMITHEQUE_MULTIPLE_widget_suggestions') message_form = DIV(_id='%s_message' % (self.uid), _class='CHIMITHEQUE_MULTIPLE_widget_message', _style='display: none;') search_input_form = DIV(INPUT(_name='%s_search' % self.uid, _type='text', _title='%s_search' % self.uid), suggestions_form, _id='%s_search' % (self.uid), _class='search_input_form') # # adding a confirm empty checkbox if needed # if confirm_empty: confirm_empty_form = DIV( INPUT(_name='confirm_empty_%s' % field.name, _id='confirm_empty_%s' % field.name, _type='checkbox', _title=self.text_confirm_empty_form_field, _class='CHIMITHEQUE_MULTIPLE_widget_confirm_empty', _onclick='''$('div[id=%(uid)s]').empty(); if ($('input[type=checkbox][name=confirm_empty_%(field_name)s]').is(':checked')) { $('div[id=%(uid)s]').append('<span id="%(field_name)s_span_no_selected"></span>'); } else { $('div[id=%(uid)s]').append('<span id="%(field_name)s_span_no_selected">%(no_item_selected)s</span>'); } ''' % { 'uid': self.uid, 'field_name': field.name, 'no_item_selected': self.text_no_item_selected })) confirm_empty_form.append( IMG(_src=self.image_disable_url, _alt='disable', _id='%s_disable' % self.uid, _title=self.text_confirm_empty_form_field)) else: confirm_empty_form = DIV() # # building the AJAX query parameters # _ajax_parameters = { 'uid': self.uid, 'multiple': multiple, 'disable_validate': disable_validate, 'add_in_db': add_in_db, 'field_tablename': field._tablename, 'ref_field_tablename': self.ref_field._tablename, 'ref_field_name': self.ref_field.name, 'max_nb_item': max_nb_item, 'max_item_length': self.max_item_length, 'lambda': func_lambda, 'query': query, 'text_close_list': str(self.text_close_list), 'text_submit': str(self.text_submit), 'image_select_url': self.image_select_url, 'submit_on_select': submit_on_select } ajax_parameters = json.dumps(_ajax_parameters) # # adding the "add" image # if not disabled and add_in_db: search_input_form.append( IMG(_src=self.image_insert_url, _alt='submit', _id='%s_add' % self.uid, _title=self.text_submit, _style='visibility: hidden;', _class='CHIMITHEQUE_MULTIPLE_widget_addindb', _onclick=''' // adding the search parameter to the JSON object ajax_parameters = %(ajax_parameters)s; ajax_parameters["search"] = $('input[name=%(uid)s_search]').val(); var ret = $.ajax({ type: "POST", url: "/%(application)s/chimitheque_multiple_widget/item_add", data: JSON.stringify(ajax_parameters), dataType: "json", contentType: "application/json; charset=utf-8", async: false }).done(function(data) { var _action = data['action']; var _id = data['id']; var _val = data['val']; var _encval = data['encval']; var funcCall = "addReplaceCheckBox%(uid)s" + "('" + _action + "','" + _id + "','" + _val + "','" + _encval + "')"; eval(funcCall); $('img#%(uid)s_add').attr('style', 'visibility: hidden;'); }); ''' % { 'uid': self.uid, 'application': current.request.application, 'ajax_parameters': ajax_parameters })) # # adding the selected items DIV # if nb_item == 0: if 'confirm_empty_%s' % field.name in current.request.vars: checkboxes_form.append(SPAN()) else: checkboxes_form.append( SPAN(XML(self.text_no_item_selected), _id='%s_span_no_selected' % field.name)) hidden_box_form = DIV( INPUT(_name='%s' % field.name, _id='%s_hidden' % field.name, _type='checkbox', _value='', _style='visibility: hidden; height: 0px;', _checked='checked', requires=field.requires)) else: hidden_box_form = DIV() # # prepopulating the form # for i in range(0, nb_item): mylogger.debug(message='i:%i' % (i)) prepop_value_id = None prepop_value_label = None if is_not_a_reference: # just populating with the value passed in parameter mylogger.debug(message='case 1') prepop_value_id = value[i] prepop_value_label = value[i] else: # the parameter value is an id in the reference table, then querying the table mylogger.debug(message='case 2') prepop_value = current.db( current.db['%s' % self.ref_field._tablename]['id'] == ( value[i])).select().first() if prepop_value is not None: prepop_value_label = current.db[ '%s' % self.ref_field._tablename]._format(prepop_value) prepop_value_id = value[i] mylogger.debug(message='prepop_value_id:%s' % prepop_value_id) mylogger.debug(message='prepop_value_label:%s' % prepop_value_label) if prepop_value_id: # # adding the checkboxes or radio for the selected items # if multiple: _input = INPUT( _name='%s' % field.name, _id='%s' % field.name, _type='checkbox', _class='CHIMITHEQUE_MULTIPLE_widget_selected', _encvalue=self.uid, _value=prepop_value_id, value=True, requires=field.requires) else: if is_not_a_reference: _input = INPUT( _name='%s' % field.name, _id='%s' % field.name, _type='radio', _class='CHIMITHEQUE_MULTIPLE_widget_selected', _encvalue=self.uid, _value= prepop_value_label, # or prepop_value_id, don't mind... value= prepop_value_label, # or prepop_value_id, don't mind... requires=field.requires) else: _input = INPUT( _name='%s' % field.name, _id='%s' % field.name, _type='radio', _class='CHIMITHEQUE_MULTIPLE_widget_selected', _encvalue=self.uid, _value=prepop_value_id, value=prepop_value_id, requires=field.requires) # # then the delete selected item image # if not disabled and not multiple: img_del = IMG(_src=self.image_delete_url, _alt=self.text_delete, _title=self.text_delete, _onclick='deleteItem%s();' % self.uid, _style='float: left;') else: img_del = SPAN() # # then the label # checkboxes_form.append( DIV(_input, img_del, XML('%s' % prepop_value_label), _class='CHIMITHEQUE_MULTIPLE_widget_selected')) else: # TODO: code identical to line 232... if 'confirm_empty_%s' % field.name in current.request.vars: checkboxes_form.append(SPAN()) else: checkboxes_form.append( SPAN(XML(self.text_no_item_selected), _id='%s_span_no_selected' % field.name)) hidden_box_form = DIV( INPUT(_name='%s' % field.name, _id='%s_hidden' % field.name, _type='checkbox', _value='', _style='visibility: hidden; height: 0px;', _checked='checked', requires=field.requires)) # # building the final form # final_form = DIV( DIV( DIV(checkboxes_form, _id='%s' % self.uid, _class='%s_%s' % (self.ref_field._tablename, self.ref_field.name)), **self.attributes)) if not disabled: final_form.insert(0, confirm_empty_form) final_form.insert(0, search_input_form) # hidden field to export the uid for the pages uid_field = INPUT(_name='uid_%s' % field.name, _type='hidden', value='%s' % self.uid, style='visibility: hidden; height: 0px;') return DIV(final_form, uid_field, hidden_box_form, message_form, SCRIPT( """ function disableAddButton%(uid)s() { $('#%(uid)s_add').attr('style', 'visibility: hidden;'); } function displayMessage%(uid)s(message) { $('#%(uid)s_message span').remove(); $('#%(uid)s_message').append('<span class="error">' + message + '</span>'); } function deleteItem%(uid)s() { $('#%(uid)s').find('div[class=CHIMITHEQUE_MULTIPLE_widget_selected]').remove(); console.log($('input[name=%(field_name)s]').length); /* enabling the hidden field if needed */ if ($('input[name=%(field_name)s]').length <= 1) { console.log("input name '%(field_name)s' was the last element"); $('input[id=%(field_name)s_hidden]').removeAttr('disabled'); $('div[id=%(uid)s]').append('<span id="%(field_name)s_span_no_selected">%(no_item_selected)s</span>'); } else { console.log("input name '%(field_name)s' was not the last element"); } } function addReplaceCheckBox%(uid)s(action, id, val, encval) { console.log(arguments.callee.name); console.log('action:' + action); console.log('id:' + id); console.log('val:' + val); console.log('encval:' + encval); /* base64 decoding the string */ val = Base64.decode(val); /* disabling the hidden field */ $('input[id=%(field_name)s_hidden]').attr('disabled','true'); $('span[id=%(field_name)s_span_no_selected]').remove(); if ($('#%(uid)s').find('input[value="'+id+'"][encvalue='+encval+']').length != 0) { alert('%(text_item_already_selected)s'); } else { var newDiv = $('<div class="CHIMITHEQUE_MULTIPLE_widget_selected"/>'); var newDel = $('<img/>').attr({ 'src': '%(image_delete_url)s', 'alt': '%(image_delete_alt)s', 'title': '%(image_delete_title)s', 'onclick': 'deleteItem%(uid)s();' }); var newElem = $('<input/>').attr({ 'id': '%(field_name)s', 'type': '%(type)s', 'checked': 'checked', 'name': '%(field_name)s', 'value': id, 'class': 'CHIMITHEQUE_MULTIPLE_widget_selected', 'encvalue': encval, }); if (action == 'replace') { newDiv.append(newDel); } newDiv.append(newElem); newDiv.append(val); if (action == 'replace') { $('#%(uid)s div').remove(); } $('#%(uid)s').append(newDiv); } $('input[name=%(uid)s_search]').val(''); $('#' + encval + '_suggestions div').remove(); } function autocomplete%(uid)s() { $elem = $('input[type=text][name=%(uid)s_search]') var inputLength = $elem.val().length; if (inputLength >= %(minchar)s) { // adding the search parameter to the JSON object ajax_parameters = %(ajax_parameters)s; ajax_parameters["search"] = $elem.val(); var ret = $.ajax({ type: "POST", url: "/%(application)s/chimitheque_multiple_widget/item_selector", data: JSON.stringify(ajax_parameters), dataType: "json", contentType: "application/json; charset=utf-8", async: false }).responseText; $('#%(uid)s_suggestions > *').remove(); $('#%(uid)s_message').show(); $('#%(uid)s_message').text(''); if (ret.substr(0, 5) == 'ERROR') { $('#%(uid)s_message').text(ret); $('#%(uid)s_add').attr('style', 'visibility: hidden;'); }else if (ret.substr(0, 4) == 'INDB'){ $('#%(uid)s_add').attr('style', 'visibility: hidden;'); $('#%(uid)s_suggestions').append(ret); }else if (ret.substr(0, 4) == 'NONE'){ $('#%(uid)s_add').attr('style', 'visibility: visible;'); } else { $('#%(uid)s_add').attr('style', 'visibility: visible;'); $('#%(uid)s_suggestions').append(ret); } } } $(document).ready(function() { jQuery('input[type=text][name=%(uid)s_search]').bind('paste', function(e) { setTimeout(function() { autocomplete%(uid)s(); }, 0); }); timer = 0; jQuery('input[type=text][name=%(uid)s_search]').bind('keypress click paste input',function() { if (timer) { clearTimeout(timer); } timer = setTimeout(autocomplete%(uid)s, 400); }); }); """ % { 'disable_validate': disable_validate, 'add_in_db': add_in_db, 'multiple': multiple, 'uid': self.uid, 'field_tablename': field._tablename, 'field_name': field.name, 'field_label': field.label, 'ref_field_tablename': self.ref_field._tablename, 'ref_field_name': self.ref_field.name, 'minchar': self.minchar, 'image_delete_url': self.image_delete_url, 'image_delete_alt': self.text_delete, 'image_delete_title': self.text_delete, 'type': 'checkbox' if multiple else 'radio', 'max_nb_item': max_nb_item, 'max_item_length': self.max_item_length, 'lambda': func_lambda, 'image_delete_small': self.image_delete_url, 'text_item_already_selected': self.text_item_already_selected, 'no_item_selected': self.text_no_item_selected, 'application': current.request.application, 'ajax_parameters': ajax_parameters }), _class='CHIMITHEQUE_MULTIPLE_widget')
# -*- coding: utf-8 -*- from gluon.html import SPAN, FIELDSET, DIV, INPUT, TEXTAREA, LABEL, P from gluon.sqlhtml import FormWidget TASK_STATUS = { 'QUEUED' : ('#3A87AD', SPAN('QUEUED', _class="label label-info")), 'RUNNING' : ('#F89406', SPAN('RUNNING', _class="label label-warning")), 'COMPLETED': ('#468847', SPAN('COMPLETED', _class="label label-success")), 'FAILED' : ('#B94A48', SPAN('FAILED', _class="label label-danger")), 'STOPPED' : ('#B94A48', SPAN('STOPPED', _class="label label-danger")), 'EXPIRED' : ('#F89406', SPAN('EXPIRED', _class="label label-warning")), 'ASSIGNED' : ('#FAA732', SPAN('ASSIGNED', _class="label label-warning")), 'TIMEOUT' : ('#B94A48', SPAN('TIMEOUT', _class="label label-warning")), } WORKER_STATUS = { 'ACTIVE': SPAN("ACTIVE", _class="label label-success"), 'PICK': SPAN("PICK", _class="label label-info"), 'DISABLED': SPAN("DISABLED", _class="label label-warning"), 'TERMINATE': SPAN("TERMINATE", _class="label label-danger"), 'KILL': SPAN("KILL", _class="label label-danger") } def nice_worker_status(status): if status in WORKER_STATUS: return WORKER_STATUS[status] else: return SPAN(status, _class="label label-default")
def nice_worker_status(status): if status in WORKER_STATUS: return WORKER_STATUS[status] else: return SPAN(status, _class="label label-default")
def rdrt_member_profile_header(r): """ Custom profile header to allow update of RDRT roster status """ record = r.record if not record: return "" person_id = record.person_id from s3 import s3_fullname, s3_avatar_represent name = s3_fullname(person_id) table = r.table # Organisation comments = table.organisation_id.represent(record.organisation_id) from s3 import s3_unicode from gluon.html import A, DIV, H2, LABEL, P, SPAN # Add job title if present job_title_id = record.job_title_id if job_title_id: comments = (SPAN("%s, " % \ s3_unicode(table.job_title_id.represent(job_title_id))), comments) # Determine the current roster membership status (active/inactive) atable = current.s3db.deploy_application status = atable.active query = atable.human_resource_id == r.id row = current.db(query).select(atable.id, atable.active, limitby=(0, 1)).first() if row: active = 1 if row.active else 0 status_id = row.id roster_status = status.represent(row.active) else: active = None status_id = None roster_status = current.messages.UNKNOWN_OPT if status_id and \ current.auth.s3_has_permission("update", "deploy_application", record_id=status_id): # Make inline-editable roster_status = A(roster_status, data = {"status": active}, _id = "rdrt-roster-status", _title = T("Click to edit"), ) s3 = current.response.s3 script = "/%s/static/themes/IFRC/js/rdrt.js" % r.application if script not in s3.scripts: s3.scripts.append(script) script = '''$.rdrtStatus('%(url)s','%(active)s','%(inactive)s','%(submit)s')''' from gluon import URL options = {"url": URL(c="deploy", f="application", args=["%s.s3json" % status_id]), "active": status.represent(True), "inactive": status.represent(False), "submit": T("Save"), } s3.jquery_ready.append(script % options) else: # Read-only roster_status = SPAN(roster_status) # Render profile header return DIV(A(s3_avatar_represent(person_id, tablename="pr_person", _class="media-object", ), _class="pull-left", ), H2(name), P(comments), DIV(LABEL(status.label + ": "), roster_status), _class="profile-header", )
def nice_task_status(status): if status in TASK_STATUS: return TASK_STATUS[status][1] else: return SPAN(status, _class="label")