With the SELECT, better initialisation and no more roundtrip to get the
value representation :

def autocomplete_typeahead_widget(field, value, referenced_table,
represent_field, id_field, controller, **kwargs):
    table_name = field._tablename
    field_name = field.name
    field_requires = field.requires
    if value != None and value != '':
        field_value = value
        option = sample_id_represent[int(value)]
    else:
        field_value = ''
        option = ''
    input_args = {'_data-provide':'typeahead', '_autocomplete': 'off'}
    input_args.update(kwargs)
    return CAT(
        INPUT(_type="text", _class="string", _id="%s_%s_ac" % (table_name,
field_name), _value=option, **input_args),
        SELECT(OPTION(option, _value=field_value),
            value=field_value,
            _id="%s_%s" % (table_name, field_name),
            _name=field_name,
            _style='display: none;',
            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) {
                                mapped[item.option] = item.id
                                labels.push(item.option)
                                })

                            process(labels)
                            }
                        )
                  },
                  updater:function(item) {
                    $('#%(table_name)s_%(field_name)s')
                        .find('option')
                        .remove()
                        .end()
                        .append('<option value="'+mapped[item]+'"
selected="selected">'+item+'</option>');
                    return item;
                    }
                })
            });
            $('input#%(table_name)s_%(field_name)s_ac').blur(
                function(){
                    if($(this).val().length==0) {
                        $('#%(table_name)s_%(field_name)s')
                            .find('option')
                            .remove()
                            .end();
                        }
                    else
if($('#%(table_name)s_%(field_name)s').val()!=mapped[$(this).val()]) {
                        $('#%(table_name)s_%(field_name)s')
                            .find('option')
                            .remove()
                            .end();
                        }
                });
            });""" % {'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})
    )


On Wed, Mar 20, 2013 at 5:06 PM, Richard Vézina <[email protected]
> wrote:

> It could be less complicated if the hidden field were of select I guess
> since value and representation could be easier to get on form reload... I
> may refactor this when I get time...
>
> Richard
>
>
> On Wed, Mar 20, 2013 at 5:04 PM, Richard Vézina <
> [email protected]> wrote:
>
>> 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_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), _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) {
>>                                 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('')}
>>                 });
>>             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) {
>>                                 reverseMap[item.id] = item.option
>>                                 })
>>
>> $('#%(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...
>>
>> Richard
>>
>>
>> On Wed, Mar 20, 2013 at 3:21 PM, Richard Vézina <
>> [email protected]> wrote:
>>
>>> My understanding of the problem is that the test2_test1_id_ac input
>>> field is not part of the form and web2py don't keep the value on page
>>> refresh... But I can't figure out how other jquery plugin does ot keep
>>> value of added field... no... I am correcting myseld... I do understand,
>>> since they recreate themself from the dom the get the value from the web2py
>>> input field (test2_test1_id)...
>>>
>>> I my case since the test2_test1_ac input is recreate I guess on form
>>> error when the form is reload with error so the inputed value is
>>> overwrite...
>>>
>>> So I need a piece of js that will set the a value "label" on form
>>> reload, but I am afraid a circular reference thought
>>>
>>> Richard
>>>
>>>
>>> On Wed, Mar 20, 2013 at 3:04 PM, Richard Vézina <
>>> [email protected]> wrote:
>>>
>>>> Here the dummy app (see attach)
>>>>
>>>> To reproduce the behavior I want to correct : You need to submit the
>>>> form without input value for f1 and a picked value with typeahead
>>>> autocomplete widget...
>>>>
>>>> test2 table f1 and test1_id are required field... You will notice that
>>>> if you fill field test1_id but not f1 error message triggers... Then you
>>>> will see that the input value "label" of the inserted choice "a1" for
>>>> instance it not displayed... But there is no error message because the
>>>> hidden field value stays there has it should, but it pretty anoying for a
>>>> user to don't see his input and not having a error message.
>>>>
>>>>
>>>> NOTE: There is duplicated entries in the typeahead drop down don't no
>>>> why it should be the bootstrap used, because here I don't get this kind of
>>>> behavior... So must be a issue with the typeahead bootstrap lib form
>>>> netdna.bootstrapcdn.com, I don't know...
>>>>
>>>> Richard
>>>>
>>>>
>>>>
>>>>
>>>> On Wed, Mar 20, 2013 at 11:08 AM, Richard Vézina <
>>>> [email protected]> wrote:
>>>>
>>>>> You right Richardo,
>>>>>
>>>>> I will do a dummy app... So less time impact on anyone who want to
>>>>> help!
>>>>>
>>>>> I read at your code and no sure where you were going by the little
>>>>> change you made to the code I provide...
>>>>>
>>>>> I get back in a couples of minutes with dummy app.
>>>>>
>>>>> Richard
>>>>>
>>>>>
>>>>> On Tue, Mar 19, 2013 at 9:59 PM, Ricardo Pedroso <[email protected]
>>>>> > wrote:
>>>>>
>>>>>> On Tue, Mar 19, 2013 at 11:15 PM, Richard <
>>>>>> [email protected]> wrote:
>>>>>> > Hello,
>>>>>> >
>>>>>> > I wrote a typeahead autocomplete widget and work around many little
>>>>>> issues,
>>>>>> > but now I have one that I have no clue how to solve...
>>>>>> >
>>>>>> > You can find the code here :
>>>>>> > https://groups.google.com/d/msg/web2py/Fs-tAH75fGY/6VtZ32x6lMAJ
>>>>>> >
>>>>>> > When the form get submit and the validators trigger the input value
>>>>>> key or
>>>>>> > value label is cleared out, but the value of the hidden field stick
>>>>>> so there
>>>>>> > is no problem get the proper value in the database but it is kind
>>>>>> of anoying
>>>>>> > to the user to not see his value and didn't have validator error
>>>>>> message.
>>>>>>
>>>>>> Hi Richard,
>>>>>>
>>>>>> You probably would have more and accurate answers if you made
>>>>>> a simple application with the problem.
>>>>>>
>>>>>> Based on the code you post and the comments I tried to replicate the
>>>>>> problem
>>>>>> you describe.
>>>>>>
>>>>>> Find attached a small and self contained application,
>>>>>> with your widget (with some little changes), and see if it's what you
>>>>>> want.
>>>>>> If not, make a small, self contained application for us to try.
>>>>>>
>>>>>> To run it just drop in an someapp/controllers.
>>>>>>
>>>>>> Regards,
>>>>>> Ricardo
>>>>>>
>>>>>> --
>>>>>>
>>>>>> ---
>>>>>> 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