Finally it there were still a issue with the above code in case length was
greater then 0 but the typeahead field was alter before submit... Here a
fix :
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(){
var labels = []
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) {
$.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('')}
else
if($('#%(table_name)s_%(field_name)s').val()!=mapped[$(this).val()])
{$('#%(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})
)
On Tue, Mar 19, 2013 at 2:39 PM, Richard Vézina <[email protected]
> wrote:
> 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.