Finally solve my problem like that... Not very elegant :
def autocomplete_typeahead_widget(f, v, referenced_table, represent_field, id_field, controller, **kwargs):
table_name = f._tablename
field_requires = f.requires
field_value = v
options = {'_data-provide':'typeahead', '_autocomplete': 'off'}
options.update(kwargs)
return CAT(
INPUT(_type="text", _class="string", _id="%s_%s_ac" % (table_name, field_name), _value="", **options),
INPUT(_type="hidden", _id="%s_%s" % (table_name, field_name), _name=field_name, _value=field_value, requires=field_requires),
SCRIPT("""jQuery(document).ready(function(){
var mapped = {}
$(function() { $('#%(table_name)s_%(field_name)s_ac').typeahead(
{ minLength: 0,
items: 10,
source: function (query, process) {
$.get('%(url)s',
{ q: query },
function (data) {
var labels = []
$.each(data.options, function (i, item) {
labels.push(item.option)
})
process(labels)
}
)
},
updater:function(item){ $('#%(table_name)s_%(field_name)s').val(mapped[item]); return item;}
})
});
$('input#%(table_name)s_%(field_name)s_ac').blur(
function(){
if($(this).val().length==0) {$('#%(table_name)s_%(field_name)s').val('')}
else if($('#%(table_name)s_%(field_name)s').val()!=mapped[$(this).val()]) {$('#%(table_name)s_%(field_name)s').val('')}
});
if($('#%(table_name)s_%(field_name)s_ac').val().length==0 && $('#%(table_name)s_%(field_name)s').val().length!=0)
{
var reverseMap = {}
$.get('%(url)s',
function (data) {
$.each(data.options, function (i, item) {
})
$('#%(table_name)s_%(field_name)s_ac').val(reverseMap[$('#%(table_name)s_%(field_name)s').val()])
}
)
}
});""" % {'url': URL(c=controller,
f='autocomplete_typeahead_widget_json_feed.json',
vars=dict(referenced_table=referenced_table,
represent_field=represent_field,
id_field=id_field)),
'table_name': table_name,
'field_name': field_name})
)
I attach the corrected app...