I have been a little further and I can partly trigger the callback with this :
response.js += """$('#test_ph_eregistry_id').keyup();""" But the autocomplete selecting panel stays there for ever... So I try to trigger a "tab" key stroke event that make it disapear in a real case scenario (I mean when I do it). response.js += """$('#test_ph_eregistry_id').keyup(); var e = jQuery.Event("keydown"); e.which = 9; $("#test_ph_eregistry_id").trigger(e); """ But I think that I have error... Richard On Wed, Apr 25, 2012 at 11:54 AM, Richard Vézina < ml.richard.vez...@gmail.com> wrote: > No, callback issue... > > How can I trigger call back when I set my new foreing entry in > autocomplete widget box?? > > Richard > > On Wed, Apr 25, 2012 at 11:43 AM, Richard Vézina < > ml.richard.vez...@gmail.com> wrote: > >> No, I was wrong, is because I need to strip withe space coming from the >> field type... >> >> Richard >> >> >> On Wed, Apr 25, 2012 at 11:33 AM, Richard Vézina < >> ml.richard.vez...@gmail.com> wrote: >> >>> 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) >>>> >>>> >>> >> >