Ok, here a more generic and a fix for the bootstrap hole (in red) :
def autocomplete_typeahead_widget(f, v, referenced_table, represent_field,
id_field, **kwargs):
table_name = f._tablename
field_name = f.name
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), **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(){
$(function() { $('#%(table_name)s_%(field_name)s_ac').typeahead(
{ minLength: 0,
items: 10,
source: function (query, process) {
$.get('%(url)s',
{ q: query },
function (data) {
labels = []
mapped = {}
$.each(data.options, function (i, item) {
mapped[item.option] = item.id
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('')}
});
});""" % {'url': URL(c='test',
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})
)
def autocomplete_typeahead_widget_json_feed():
referenced_table = request.vars.referenced_table
id_field = request.vars.id_field
represent_field = request.vars.represent_field
rows=db(db[referenced_table][id_field]>0).select(db[referenced_table][id_field],
db[referenced_table][represent_field])
options = []
for i,row in enumerate(rows):
options.append({'option': row[represent_field], 'id': row.id})
from gluon.contrib import simplejson
return simplejson.dumps({'options': options })
db.table.field.widget = lambda field, value:
autocomplete_typeahead_widget(field, value,
referenced_table='referenced_table_name',
represent_field='represent_field_name',
id_field='id_field_name_of_the_referenced_table', _placeholder=T('Start
typing...'))
On Tue, Mar 19, 2013 at 1:29 PM, Richard Vézina <[email protected]
> wrote:
> I found an hole in typeahead updater...
>
> typeahead updater seems to be bit it by a trigger event only when there is
> something that have been selected... But if for instance someone select
> something the hidden field that get submitted is updated with the id if the
> record, but the hidden field is not updated if the field is empty (for some
> reason : USERS) after been filled once... So the id of the previous
> selected record stay there and the form submit correctly if there is no
> other validators that trigger up!!
>
> I googled a lot about this hole and typeahead, maybe I don't have the
> right keywords or the issue have not been identified since bootstrap
> typeahead as only recently get the updated to support key/value field.
>
> Richard
>
>
> On Mon, Mar 18, 2013 at 9:02 PM, Richard <[email protected]>wrote:
>
>> Hello,
>>
>> Wrote this and it may be handy for others in the meantime there is a
>> better integration of autocomplete bootstrap typeahead :
>>
>> # Widget function
>> def autocomplete_typeahead_widget(f, v, **kwargs):
>> table_name = f._tablename
>> field_name = f.name
>> 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), **options),
>> INPUT(_type="hidden", _id="%s_%s" % (table_name, field_name),
>> _name=field_name, _value=field_value, requires=field_requires),
>> SCRIPT("""$(function() {
>> $('#%(table_name)s_%(field_name)s_ac').typeahead(
>> { source: function (query, process) {
>> $.get('%(url)s.json',
>> { q: query },
>> function (data) {
>> labels = []
>> mapped = {}
>> $.each(data.options, function (i, item) {
>> mapped[item.option] = item.id
>> labels.push(item.option)
>> })
>>
>> process(labels)
>> }
>> )
>> },
>> updater:function(item){
>> $('#%(table_name)s_%(field_name)s').val(mapped[item]); return item}
>> })
>> });""" % {'url':URL(c='test',
>> f='autocomplete_typeahead_widget_json_feed'), 'table_name':table_name,
>> 'field_name':field_name})
>> )
>>
>> # Generating JSON function
>> def autocomplete_typeahead_widget_json_feed():
>> rows=db(db.table.field>0).select()
>> options = []
>> for i,row in enumerate(rows):
>> options.append({'option': row.field, 'id': row.id})
>> from gluon.contrib import simplejson
>> return simplejson.dumps({'options': options })
>>
>> # Init of the widget
>> db.other_table.select_field.widget = autocomplete_typeahead_widget
>>
>> or
>>
>> db.other_table.select_field.widget = lambda field, value:
>> autocomplete_typeahead_widget(field, value, MORE_ARGS)
>>
>> Enjoy!
>>
>> Richard
>>
>> --
>>
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "web2py-users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected].
>> For more options, visit https://groups.google.com/groups/opt_out.
>>
>>
>>
>
>
--
---
You received this message because you are subscribed to the Google Groups
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.