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.


Reply via email to