First, I state that I really don“t know if this will always work.
For me it worked so here it goes!
You can put all the code in a file in models folder:
The validator:
class TAGS_LIST:
def __init__(self, separator=',', error_message='This is not a valid list!'):
self.separator = separator
self.e = error_message
def __call__(self,value):
try:
list = value.split(self.separator)
return (list, None)
except:
return (value, self.e)
def formatter(self, value):
tags = ''
for tag in value:
tags += '%(tag)s%(sep)s ' % {'tag':tag,'sep':self.separator}
return tags
The widget:
def tags_widget(field, value, **attributes):
id = "%s_%s" % (field._tablename, field.name) # form field
idu = id + '_u' #user field
idl = id + '_l' #list display
script = SCRIPT(
'function parse() {var s = ""; $("#%(idl)s > li").each(function(){s+=$(this).html()+",";}); $("#%(id)s").val(s)}' % {'id':id,'idl':idl},
'function addTag(tag){var item=$(document.createElement("li")); item.text(tag); item.click(function(){item.remove(); parse();}); $("#%(idl)s").append(item); }' % {'idl':idl},
'function init() {list = $("#%(id)s").val().split(","); list.pop(); $.each(list, function(index,item){addTag(item)}); }' % {'id':id},
'$(document).ready(function (){init();});')
inp_user = INPUT(_id=idu,
_onkeyup='if (event.keyCode==32) {addTag($(this).val()); parse(); $(this).val("");}' % {'idu':idu})
inp_hiden = INPUT(
_type="hidden",
_name=field.name,
_id=id,
_class=field.type,
_value=value,
requires=field.requires,
)
list = UL(_id=idl)
return DIV(script,inp_user,list,inp_hiden)
Now the only thing to do is set validator and widgets attributes of your field.
db.define_table('table',Field('tags','list:string'))
db.table.tags_field.requires = TAGS_LIST()
db.table.tags_field.widget = tags_widget
You can customize the list display with CSS.
If you want a simpler thing you may use only the validator and it will parse the comma separated tags on the form validation.
.playincard....
ross.peoples...
frank
abhishekgupt...