Hello,

I made a lot of progress, by changing my approach, instead of trying to use
Autocomplete form SELECT_OR_ADD_OPTION, I bring SELECT_OR_ADD_OPTION into
Autocomplete to create a new AutocompleteWidgetSelectOrAddOption widget...

What I get so far :

class AutocompleteWidgetSelectOrAddOption(object):
    _class = 'string'

    def __init__(self, request, field, id_field=None, db=None,
                 orderby=None, limitby=(0,10),
                 keyword='_autocomplete_%(fieldname)s',
                 min_length=2,
                 # SelectOrAddOption
                 controller=None, function=None, form_title=None,
                 button_text = None, dialog_width=1000):
        self.request = request
        self.keyword = keyword % dict(fieldname=field.name)
        self.db = db or field._db
        self.orderby = orderby
        self.limitby = limitby
        self.min_length = min_length
        self.fields=[field]
        if id_field:
            self.is_reference = True
            self.fields.append(id_field)
        else:
            self.is_reference = False
        if hasattr(request,'application'):
            self.url = URL(args=request.args)
            self.callback()
        else:
            self.url = request
        # SelectOrAddOption
        if form_title == None:
            self.form_title = T('Add New')
        else:
            self.form_title = T(form_title)
        if button_text == None:
            self.button_text = T('Add')
        else:
            self.button_text = T(button_text)
        self.dialog_width = dialog_width

        self.controller = controller
        self.function = function
    def callback(self):
        if self.keyword in self.request.vars:
            field = self.fields[0]
            rows = self.db(field.like(self.request.vars[self.keyword]+'%'))\

.select(orderby=self.orderby,limitby=self.limitby,*self.fields)
            if rows:
                if self.is_reference:
                    id_field = self.fields[1]
                    raise
HTTP(200,SELECT(_id=self.keyword,_class='autocomplete',

_size=len(rows),_multiple=(len(rows)==1),
                                          *[OPTION(s[field.name],_value=s[
id_field.name],
                                                   _selected=(k==0)) \
                                                for k,s in
enumerate(rows)]).xml())
                else:
                    raise
HTTP(200,SELECT(_id=self.keyword,_class='autocomplete',

_size=len(rows),_multiple=(len(rows)==1),
                                          *[OPTION(s[field.name],
                                                   _selected=(k==0)) \
                                                for k,s in
enumerate(rows)]).xml())
            else:

                raise HTTP(200,'')
    def __call__(self,field,value,**attributes):
        #
----------------------------------------------------------------------
        # SelectOrAddOption
        my_select_id = 'test_ph_eregistry_id'
#select_widget.attributes.get('_id', None)
        add_args = [my_select_id]
        #create a div that will load the specified controller via ajax
        form_loader_div = DIV(LOAD(c=self.controller, f=self.function,
args=add_args,ajax=True), _id=my_select_id+"_dialog-form",
_title=self.form_title)
        #generate the "add" button that will appear next the options widget
and open our dialog
        activator_button = A(T(self.button_text),
_id=my_select_id+"_option_add_trigger")
        #create javascript for creating and opening the dialog
        js = '$( "#%s_dialog-form" ).dialog({autoOpen: false, show: "fade",
hide: "fade", width: %s});' % (my_select_id, self.dialog_width)
        js += '$( "#%s_option_add_trigger" ).click(function() { $(
"#%s_dialog-form" ).dialog( "open" );return false;}); ' % (my_select_id,
my_select_id)
        #decorate our activator button for good measure
        js += '$(function() { $( "#%s_option_add_trigger" ).button({text:
true, icons: { primary: "ui-icon-circle-plus"} }); });' % (my_select_id)
        jq_script=SCRIPT(js, _type="text/javascript")

        wrapper = DIV(_id=my_select_id+"_adder_wrapper")
        #wrapper.components.extend([form_loader_div, activator_button,
jq_script])
        #
----------------------------------------------------------------------
        default = dict(
            _type = 'text',
            value = (not value is None and str(value)) or '',
            )
        attr = StringWidget._attributes(field, default, **attributes)
        div_id = self.keyword+'_div'
        attr['_autocomplete']='off'
        if self.is_reference:
            key2 = self.keyword+'_aux'
            key3 = self.keyword+'_auto'
            attr['_class']='string'
            name = attr['_name']
            if 'requires' in attr: del attr['requires']
            attr['_name'] = key2
            value = attr['value']
            record =
self.db(self.fields[1]==value).select(self.fields[0]).first()
            attr['value'] = record and record[self.fields[0].name]

attr['_onblur']="jQuery('#%(div_id)s').delay(3000).fadeOut('slow');" % \
                dict(div_id=div_id,u='F'+self.keyword)
            attr['_onkeyup'] = "jQuery('#%(key3)s').val('');var
e=event.which?event.which:event.keyCode; function
%(u)s(){jQuery('#%(id)s').val(jQuery('#%(key)s
:selected').text());jQuery('#%(key3)s').val(jQuery('#%(key)s').val())};
if(e==39) %(u)s(); else if(e==40) {if(jQuery('#%(key)s
option:selected').next().length)jQuery('#%(key)s
option:selected').attr('selected',null).next().attr('selected','selected');
%(u)s();} else if(e==38) {if(jQuery('#%(key)s
option:selected').prev().length)jQuery('#%(key)s
option:selected').attr('selected',null).prev().attr('selected','selected');
%(u)s();} else if(jQuery('#%(id)s').val().length>=%(min_length)s)
jQuery.get('%(url)s?%(key)s='+escape(jQuery('#%(id)s').val()),function(data){if(data=='')jQuery('#%(key3)s').val('');else{jQuery('#%(id)s').next('.error').hide();jQuery('#%(div_id)s').html(data).show().focus();jQuery('#%(div_id)s
select').css('width',jQuery('#%(id)s').css('width'));jQuery('#%(key3)s').val(jQuery('#%(key)s').val());jQuery('#%(key)s').change(%(u)s);jQuery('#%(key)s').click(%(u)s);};});
else jQuery('#%(div_id)s').fadeOut('slow');" % \
                dict(url=self.url,min_length=self.min_length,
                     key=self.keyword,id=attr['_id'],key2=key2,key3=key3,
                     name=name,div_id=div_id,u='F'+self.keyword)
            if self.min_length==0:
                attr['_onfocus'] = attr['_onkeyup']

wrapper.components.extend([TAG[''](INPUT(**attr),INPUT(_type='hidden',_id=key3,_value=value,

 _name=name,requires=field.requires),
                           DIV(_id=div_id,_style='position:absolute;')),
form_loader_div, activator_button, jq_script])
            return wrapper
        else:
            attr['_name']=field.name

attr['_onblur']="jQuery('#%(div_id)s').delay(3000).fadeOut('slow');" % \
                dict(div_id=div_id,u='F'+self.keyword)
            attr['_onkeyup'] = "var
e=event.which?event.which:event.keyCode; function
%(u)s(){jQuery('#%(id)s').val(jQuery('#%(key)s').val())}; if(e==39)
%(u)s(); else if(e==40) {if(jQuery('#%(key)s
option:selected').next().length)jQuery('#%(key)s
option:selected').attr('selected',null).next().attr('selected','selected');
%(u)s();} else if(e==38) {if(jQuery('#%(key)s
option:selected').prev().length)jQuery('#%(key)s
option:selected').attr('selected',null).prev().attr('selected','selected');
%(u)s();} else if(jQuery('#%(id)s').val().length>=%(min_length)s)
jQuery.get('%(url)s?%(key)s='+escape(jQuery('#%(id)s').val()),function(data){jQuery('#%(id)s').next('.error').hide();jQuery('#%(div_id)s').html(data).show().focus();jQuery('#%(div_id)s
select').css('width',jQuery('#%(id)s').css('width'));jQuery('#%(key)s').change(%(u)s);jQuery('#%(key)s').click(%(u)s);});
else jQuery('#%(div_id)s').fadeOut('slow');" % \
                dict(url=self.url,min_length=self.min_length,

 key=self.keyword,id=attr['_id'],div_id=div_id,u='F'+self.keyword)
            if self.min_length==0:
                attr['_onfocus'] = attr['_onkeyup']

wrapper.components.extend([TAG[''](INPUT(**attr),DIV(_id=div_id,_style='position:absolute;')),
form_loader_div, activator_button, jq_script])
            return wrapper



This also needed :

@auth.requires_login()
def add_eregistry():
    #this is the controller function that will appear in our dialog
    crud.settings.formstyle='divs'
    form = crud.create(db.ref_eregistry)
    for i in range(0,len(form[0])):
        if len(form[0][i][2][0]) > 0:
            form[0][i][0].append(SPAN((helpicon(),
SPAN(form[0][i][2][0])),_class='tooltip'))
        del(form[0][i][2])
    if form.accepts(request.vars):
        #Successfully added new item
        #do whatever else you may want

        #Then let the user know it worked
        response.flash = T("Added")
        target= request.args[0]
        #close the widget's dialog box
        response.js = '$( "#%s_dialog-form" ).dialog( "close" ); ' %(target)
        #update the options they can select their new category in the main
form
        response.js += """$("#%s").append("<option
value='%s'>%s</option>");""" \
            % (target, form.vars.id, db(db.ref_eregistry.id==form.vars.id
).select(db.ref_eregistry.eregistry_id).first().eregistry_id)
        #and select the one they just added
        response.js += """$("#%s").val("%s");""" % (target, db(
db.ref_eregistry.id==form.vars.id
).select(db.ref_eregistry.exp_num).first().exp_num)
        #finally, return a blank form incase for some reason they wanted to
add another option
        return form
    elif form.errors:
        #silly user, just send back the form and it'll still be in our
dialog box complete with error messages
        return form
    else:
        #hasn't been submitted yet, just give them the fresh blank form
        return form



The only remaining problem I have is that I can't get the new created entry
in the foreign table to be attach to the new record because the way I pass
the foreign key to the Autocomplete box... I put the problematic lines in
red in the code above...


I think, I am not using the proper selector or there is something wrong
with the callback, it may be not trigger the way I pass the foreign
record...

Richard





On Wed, Apr 25, 2012 at 10:02 AM, Johann Spies <johann.sp...@gmail.com>wrote:

> I also interested in this but unfortunately am too much of a beginner with
> jquery / javascript to be able to help you now.
>
> Regards
> Johann
>
> --
> Because experiencing your loyal love is better than life itself,
> my lips will praise you.  (Psalm 63:3)
>
>

Reply via email to