Thanks haha. Just checking. Still not having much luck. I'm getting a 500 error on the add function and can't figure out why
when I try to edit my site I am getting an error for the "add function" specified to add the https://www.mywebsite.com/add_function/second_table_field def add_function(): """ Modal form for adding element """ buttons = [TAG.button((I('', _class='icon-ok icon-large icon-white'), CAT(' '), STRONG(T('Add'))), _type='submit', _class='btn btn-small btn-primary', _id='add_button_id', _name='add_button', )] form = SQLFORM(db.table, buttons=buttons, formstyle=formstyle, separator =separator) response.js = '$(document).ready(function(){ $(".input_wrapper").has(".error").addClass("inputError"); ' \ '$(".w2p_fw").has(".error").addClass("control-group error"); ' \ '$(".w2p_fw").each(function(){ $(this).find(".error_wrapper").appendTo(this); }); });' response.js += '$(document).ready(function(){ $("textarea").elastic(); });' response.js += '$(document).ready(function () { $("[rel=tooltip]").tooltip(); });' if form.process(formname='add_form').accepted: response.flash = T("Added") target = request.args(0) # close modal response.js = '$("#{target}_modal-form").modal("hide");'.format( target=target) # update the select options response.js += """$("#{target}").append( "<option value='{new_id}'> {new_id} </option>");""".format(target=target, new_id= form.vars.id) # select newly added option response.js += """$("#{target}").val("{new_exp_num}"); $('#{target}').keyup(); $('#{target}').blur(); """.format(target=target, new_exp_num=form.vars.exp_num) elif form.errors: response.flash = '' else: response.flash = '' return dict(form=form) Do I need to actually specify the db.table? From the looks of the class I thought it would be defined on its own... am I wrong? Sorry for asking so many questions. I think this will be really helpful when it's all finished. On Monday, May 11, 2015 at 2:59:21 PM UTC-4, Richard wrote: > > The commented lines in the class was there because I recently refactor it > to make it use boostrap modal instead of jquery ui dialog as you may > understand carefully reading the code!! > > :-P > > Richard > > On Mon, May 11, 2015 at 2:40 PM, LoveWeb2py <atayl...@gmail.com > <javascript:>> wrote: > >> Are the commented lines necessary or was that for self reference? >> >> # js += '$("#%s_option_add_trigger"). >> click(function() {' \ >> # ' $("#%s_dialog-form").dialog("open");' \ >> # ' return false;' \ >> # ' }); ' % (my_select_id, my_select_id) >> >> >> >> On Thursday, May 7, 2015 at 9:33:28 AM UTC-4, Richard wrote: >>> >>> you need bootstrap 2.3.2 (not tested with BS3, but I am pretty sure it >>> is not working, too differents)... >>> >>> Did you try it with a recent web2py setup? I would suggest you try with >>> web2py 2.9.5 which is what I use actually and it works... >>> >>> Richard >>> >>> On Thu, May 7, 2015 at 9:20 AM, LoveWeb2py <atayl...@gmail.com> wrote: >>> >>>> Another observation: >>>> >>>> All of this code: >>>> >>>> >>>> >>>>> js += '$(function() {' \ >>>>> ' $("#%s_option_add_trigger").button({' \ >>>>> ' text: true,' \ >>>>> ' icons: {' \ >>>>> ' primary: "ui-icon-circle-plus"' \ >>>>> ' }' \ >>>>> ' });' \ >>>>> '});' % (my_select_id) >>>>> js += '$(function() { ' \ >>>>> ' $( "#%s_option_add_trigger" ).css("margin-left", >>>>> "+=5"); ' \ >>>>> '});' % (my_select_id) >>>>> js += >>>>> '$("#{modal_id}").appendTo("body");'.format(modal_id=my_select_id >>>>> + "_modal-form") >>>>> >>>>>> >>>>>> Get's commented out when it's rendered so it ends up looking like >>>> this <!-- $(document).read(function() .... .appendTo("body");}); //--> >>>> >>>> Any idea why that could be happening and would that impact the button >>>> showing the modal >>>> >>>> On Thursday, May 7, 2015 at 8:45:49 AM UTC-4, LoveWeb2py wrote: >>>> >>>>> Hi Richard! >>>>> >>>>> I think I'm getting close. No more errors, and I applied the widget to >>>>> the field successfully. I see the + sign next to my field, but nothing >>>>> happens when I click it so I'm going over the javascript with a fine >>>>> tooth >>>>> comb. Is there any additional .js or .css files I need to include? >>>>> >>>>> This is really looking promising! >>>>> >>>>> On Wednesday, May 6, 2015 at 12:42:34 PM UTC-4, Richard wrote: >>>>> >>>>> Let say the FK field is field2 : >>>>> >>>>> Field('field2','reference main_table', # Better syntax thand >>>>> "db.main_table" >>>>> widget=AutocompleteWidgetSelectOrAddOption( >>>>> request=request, >>>>> >>>>> field=db.main_table.field1, # which is you reprensting field >>>>> id_field= >>>>> db.main_table.id, >>>>> limitby=(0, 10), # >>>>> how much records you want in the dropbox >>>>> min_length=6, # when >>>>> you want the autocomplete pop in or how many caracters user have to >>>>> entered >>>>> before the autocomplete kickin >>>>> form_title=T('Add new >>>>> title'), >>>>> controller="controler >>>>> name that contains the below function", >>>>> function="your add >>>>> function name", >>>>> button_text=T('Add >>>>> new'), >>>>> placeholder=T('Start >>>>> typing...')) >>>>> >>>>> Richard >>>>> >>>>> On Wed, May 6, 2015 at 12:34 PM, LoveWeb2py <atayl...@gmail.com> >>>>> wrote: >>>>> >>>>> Thank you, Richard. I think i'm getting closer. Could you show me an >>>>> example of how you apply this to a specific field in SQLFORM? >>>>> >>>>> Going back to my original model: >>>>> >>>>> db.define_table('main_table', >>>>> Field('field1','string'), >>>>> Field('field2','string'), >>>>> migrate=False) >>>>> >>>>> db.define_table('second_table', >>>>> Field('field1','db.main_table'), >>>>> Field('field2','db.main_table') >>>>> migrate=False) >>>>> >>>>> How could I integrate your widget with field 2 for a SQLFORM? >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> On Wednesday, May 6, 2015 at 9:40:02 AM UTC-4, Richard wrote: >>>>> >>>>> The id field and what field you want to show as a representation of >>>>> the id field of the referenced table... >>>>> >>>>> Start by putting the widget class in model file even if it not a good >>>>> thing to see if you can make it works... >>>>> >>>>> In the module I have these imports : >>>>> >>>>> from gluon.html import * >>>>> from gluon.sqlhtml import * >>>>> from gluon import current >>>>> from gluon.compileapp import LOAD >>>>> >>>>> >>>>> Which may not be related to the widget class... >>>>> >>>>> Richard >>>>> >>>>> >>>>> On Tue, May 5, 2015 at 4:28 PM, LoveWeb2py <atayl...@gmail.com> wrote: >>>>> >>>>> Hi Richard, >>>>> >>>>> I'm trying to get this setup, but am receiving an error self.url = >>>>> URL(args=request.args)\nNameError: global name \'URL\' is not defined\n'. >>>>> I'm wondering if this is because the gluon hasn't been imported yet. >>>>> >>>>> Also, could you ellaborate more on this? >>>>> >>>>> >>>>> field=db.table.representing_field, >>>>> >>>>> id_field=db.table.id_field, >>>>> >>>>> id_field should be the foreignkey table if I am not mistaking? >>>>> db.table.representing field, and db.table2.id_field (with foreign key) >>>>> does >>>>> that sound right? >>>>> >>>>> >>>>> On Wednesday, April 29, 2015 at 10:04:35 AM UTC-4, Richard wrote: >>>>> >>>>> *# In a modules :* >>>>> >>>>> 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, >>>>> # >>>>> ------------------------------------------------------------- >>>>> # From : SelectOrAddOption >>>>> controller=None, function=None, form_title=None, >>>>> button_text = None, dialog_width=1000, >>>>> # >>>>> ------------------------------------------------------------- >>>>> placeholder=None >>>>> ): >>>>> 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] >>>>> self.placeholder = placeholder >>>>> 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 >>>>> # >>>>> ---------------------------------------------------------------------- >>>>> # From : SelectOrAddOption >>>>> if form_title is None: >>>>> self.form_title = current.T('Add New') >>>>> else: >>>>> self.form_title = current.T(form_title) >>>>> if button_text is None: >>>>> self.button_text = current.T('Add') >>>>> else: >>>>> self.button_text = current.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): >>>>> # >>>>> ---------------------------------------------------------------------- >>>>> # From : SelectOrAddOption >>>>> my_select_id = '%s_%s' % (field._tablename, field.name) >>>>> # '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) >>>>> form_loader_div = DIV(DIV(BUTTON('x', _type='button', >>>>> _class='close', >>>>> **{'_data-dismiss': 'modal', >>>>> '_aria-hidden': 'true'}), >>>>> H3(self.form_title, >>>>> _id='myModalLabel'), _class='modal-header'), >>>>> DIV(LOAD(c=self.controller, >>>>> f=self.function, args=add_args, ajax=True, ajax_trap=True), >>>>> _class='modal-body'), >>>>> _id=my_select_id + "_modal-form", >>>>> _class='modal hide fade', >>>>> **{'_tabindex': '-1', '_role': 'dialog', >>>>> '_aria-labelledby': 'myModalLabel', >>>>> '_aria-hidden': 'true'}) >>>>> # generate the "add" button that will appear next the options >>>>> widget and open our modal >>>>> activator_button = A(I(_class='icon-plus-sign icon-2x'), >>>>> _id=my_select_id+"_option_add_trigger", >>>>> _class='add-and-select-button') >>>>> # 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_modal-form").modal({ backdrop: true, keyboard: >>>>> true, show: false });' % (my_select_id) >>>>> # js += '$("#%s_option_add_trigger").click(function() {' \ >>>>> # ' $("#%s_dialog-form").dialog("open");' \ >>>>> # ' return false;' \ >>>>> # ' }); ' % (my_select_id, my_select_id) >>>>> js += '$("#%s_option_add_trigger").click(function() ' \ >>>>> '{ $("#%s_modal-form").modal("show"); 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) >>>>> js += '$(function() { ' \ >>>>> ' $( "#%s_option_add_trigger" ).css("margin-left", >>>>> "+=5"); ' \ >>>>> '});' % (my_select_id) >>>>> js += >>>>> '$("#{modal_id}").appendTo("body");'.format(modal_id=my_select_id + >>>>> "_modal-form") >>>>> # jQuery .appendTo() move modal div in body to avoid nested >>>>> form which are not allow in HTML >>>>> js = """$(document).ready(function() { >>>>> %s >>>>> });""" % js >>>>> jq_script = SCRIPT(js, _type="text/javascript") >>>>> >>>>> wrapper = DIV(_id=my_select_id+"_adder_wrapper") >>>>> # >>>>> ---------------------------------------------------------------------- >>>>> default = dict( >>>>> _type='text', >>>>> value=(not value is None and str(value)) or '', >>>>> ) >>>>> attr = StringWidget._attributes(field, default, >>>>> _placeholder=self.placeholder, **attributes) >>>>> div_id = self.keyword+'_div' >>>>> attr['_autocomplete'] = 'off' >>>>> if self.is_reference: >>>>> key2 = self.keyword+'_aux' >>>>> key3 = self.keyword+'_auto' >>>>> # >>>>> ----------------------------------------------------------------------------- >>>>> # find the longest record and set input size attribute >>>>> accordingly >>>>> length = self.fields[0].len() >>>>> longest_record_length = >>>>> len(self.db().select(self.fields[0], >>>>> >>>>> orderby=~length, >>>>> limitby=(0, >>>>> 1)).first()[self.fields[0].name]) >>>>> attr['_size'] = int(longest_record_length * 1.20) # 20% >>>>> wider field width >>>>> # >>>>> ----------------------------------------------------------------------------- >>>>> 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'] = >>>>> "$('#%(div_id)s').delay(1000).fadeOut();" % \ >>>>> dict(div_id=div_id, u='F'+self.keyword) >>>>> # delay(500) is pretty important for "$('#%s').keyup(); >>>>> $('#%s').blur();" >>>>> # from the add_eregistry function >>>>> attr['_onkeyup'] = \ >>>>> "$('#%(key3)s').val('');" \ >>>>> "var e = event.which?event.which:event.keyCode;" \ >>>>> "function %(u)s() {" \ >>>>> " $('#%(id)s').val($('#%(key)s >>>>> :selected').text());" \ >>>>> " $('#%(key3)s').val($('#%(key)s').val())" \ >>>>> "};" \ >>>>> "if (e == 39) %(u)s();" \ >>>>> "else if (e == 40) {" \ >>>>> " if ($('#%(key)s option:selected').next().length)" >>>>> \ >>>>> " $('#%(key)s >>>>> option:selected').attr('selected', null).next().attr('selected', >>>>> 'selected'); %(u)s();" \ >>>>> "} else if (e == 38) {" \ >>>>> " if ($('#%(key)s option:selected').prev().length)" >>>>> \ >>>>> " $('#%(key)s >>>>> option:selected').attr('selected', null).prev().attr('selected', >>>>> 'selected'); %(u)s();" \ >>>>> "} else if ($('#%(id)s').val().length >= >>>>> %(min_length)s)" \ >>>>> " $.get('%(url)s?%(key)s=' + >>>>> encodeURI($('#%(id)s').val()), function(data) {" \ >>>>> " if (data == '')" \ >>>>> " $('#%(key3)s').val('');" \ >>>>> " else {" \ >>>>> " $('#%(id)s').next('.error').hide();" \ >>>>> " >>>>> $('#%(div_id)s').html(data).show().focus();" \ >>>>> " $('#%(div_id)s select').css('width', >>>>> $('#%(id)s').css('width'));" \ >>>>> " $('#%(key3)s').val($('#%(key)s').val());" >>>>> \ >>>>> " $('#%(key)s').change( %(u)s);" \ >>>>> " $('#%(key)s').click( %(u)s);" \ >>>>> " };" \ >>>>> " });" \ >>>>> "else $('#%(div_id)s').fadeOut();" % >>>>> 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'] = >>>>> "$('#%(div_id)s').delay(1000).fadeOut();" % \ >>>>> dict(div_id=div_id, u='F'+self.keyword) >>>>> # delay(500) is pretty important for "$('#%s').keyup(); >>>>> $('#%s').blur();" >>>>> # from the add_eregistry function >>>>> attr['_onkeyup'] = \ >>>>> "var e = event.which?event.which:event.keyCode;" \ >>>>> "function %(u)s() {" \ >>>>> " $('#%(id)s').val($('#%(key)s').val())" \ >>>>> "};" \ >>>>> "if (e == 39) %(u)s();" \ >>>>> "else if (e == 40) {" \ >>>>> " if ($('#%(key)s option:selected').next().length)" >>>>> \ >>>>> " $('#%(key)s >>>>> option:selected').attr('selected', null).next().attr('selected', >>>>> 'selected'); %(u)s();" \ >>>>> "} else if (e == 38) {" \ >>>>> " if ($('#%(key)s option:selected').prev().length) >>>>> $('#%(key)s option:selected').attr('selected', >>>>> null).prev().attr('selected', 'selected'); %(u)s();" \ >>>>> "} else if ($('#%(id)s').val().length >= >>>>> %(min_length)s) $.get('%(url)s?%(key)s=' + encodeURI($('#%(id)s').val()), >>>>> function(data) {" \ >>>>> " $('#%(id)s').next('.error').hide();" \ >>>>> " $('#%(div_id)s').html(data).show().focus();" \ >>>>> " $('#%(div_id)s select').css('width', >>>>> $('#%(id)s').css('width'));" \ >>>>> " $('#%(key)s').change( %(u)s);" \ >>>>> " $('#%(key)s').click( %(u)s);" \ >>>>> "});" \ >>>>> "else $('#%(div_id)s').fadeOut();" % >>>>> 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 >>>>> >>>>> # In a model (a model file which is already call before you set your >>>>> widget...) >>>>> from a_widget import AutocompleteWidgetSelectOrAddOption >>>>> >>>>> *# In your controller * >>>>> >>>>> def add_function(): >>>>> """ >>>>> Modal form for adding element >>>>> """ >>>>> >>>>> buttons = [TAG.button((I('', _class='icon-ok icon-large >>>>> icon-white'), CAT(' '), STRONG(T('Add'))), >>>>> _type='submit', >>>>> _class='btn btn-small btn-primary', >>>>> _id='add_button_id', >>>>> _name='add_button', >>>>> )] >>>>> form = SQLFORM(db.table, buttons=buttons, formstyle=formstyle, >>>>> separator=separator) >>>>> response.js = '$(document).ready(function(){ >>>>> $(".input_wrapper").has(".error").addClass("inputError"); ' \ >>>>> '$(".w2p_fw").has(".error").addClass("control-group >>>>> error"); ' \ >>>>> '$(".w2p_fw").each(function(){ >>>>> $(this).find(".error_wrapper").appendTo(this); }); });' >>>>> response.js += '$(document).ready(function(){ >>>>> $("textarea").elastic(); });' >>>>> response.js += '$(document).ready(function () { >>>>> $("[rel=tooltip]").tooltip(); });' >>>>> if form.process(formname='add_form').accepted: >>>>> response.flash = T("Added") >>>>> target = request.args(0) >>>>> # close modal >>>>> response.js = >>>>> '$("#{target}_modal-form").modal("hide");'.format(target=target) >>>>> # update the select options >>>>> response.js += """$("#{target}").append( >>>>> "<option value='{new_id}'> >>>>> {new_id} >>>>> </option>");""".format(target=target, >>>>> new_id=form.vars.id) >>>>> # select newly added option >>>>> response.js += """$("#{target}").val("{new_exp_num}"); >>>>> $('#{target}').keyup(); >>>>> $('#{target}').blur(); >>>>> >>>>> ... >>>> >>>> -- >>>> Resources: >>>> - http://web2py.com >>>> - http://web2py.com/book (Documentation) >>>> - http://github.com/web2py/web2py (Source code) >>>> - https://code.google.com/p/web2py/issues/list (Report Issues) >>>> --- >>>> 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 web2py+un...@googlegroups.com. >>>> For more options, visit https://groups.google.com/d/optout. >>>> >>> >>> -- >> Resources: >> - http://web2py.com >> - http://web2py.com/book (Documentation) >> - http://github.com/web2py/web2py (Source code) >> - https://code.google.com/p/web2py/issues/list (Report Issues) >> --- >> 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 web2py+un...@googlegroups.com <javascript:>. >> For more options, visit https://groups.google.com/d/optout. >> > > -- Resources: - http://web2py.com - http://web2py.com/book (Documentation) - http://github.com/web2py/web2py (Source code) - https://code.google.com/p/web2py/issues/list (Report Issues) --- 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 web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.