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();""".format(target=target,
>                                                                           
>          new_exp_num=form.vars.exp_num)
>     elif form.errors:
>         response.flash = ''
>     else:
>         response.flash = ''
>     return dict(form=form)
>
> *# Then you set the widget to your field *
>
> widget=AutocompleteWidgetSelectOrAddOption(
>                                                 request=request,
>                                                 
> field=db.table.representing_field,
>                                                 id_field=db.table.id_field,
>                                                 limitby=(0, 10),  # your 
> pref
>                                                 min_length=6,  # your pref
>                                                 form_title=T('Add new 
> element'),
>                                                 controller="ref",
>                                                 function="add_function", 
>  # Name of your add_function()
>                                                 button_text=T('Add new'),
>                                                 placeholder=T('Start 
> typing...'))
>
> Give feedback here...
>
> You may consider to try it first in a dummy app so you can share it here 
> in case you have some difficulties to set it up... It will be easier to 
> help you that way, once you will have understand all the sensitive part you 
> will be able to set it up in you prod app rapidly...
>
> Richard
>
> On Tue, Apr 28, 2015 at 7:04 PM, LoveWeb2py <atayl...@gmail.com 
> <javascript:>> wrote:
>
> I'd love to see it, Richard! I'm banging my head against the wall with 
> this other method.
>
> On Tuesday, April 28, 2015 at 6:58:25 PM UTC-4, Richard wrote:
>
> My own mix of SELECT_OR_ADD_OPTION() widget and web2py 
> SQLFORM.widget.autocomplete...
>
> As wrote above I can share the code here...
>
> Richard
>
> On Tue, Apr 28, 2015 at 5:06 PM, LoveWeb2py <atayl...@gmail.com> wrote:
>
> What do you use as a replacement? 
>
> On Tuesday, April 28, 2015 at 4:59:32 PM UTC-4, Richard wrote:
>
> in view in script tag is a good place for start... just make sure you have 
> the rigth id for you modal main div... In my case modal_id was coming from 
> an .fromat(modal_id='id')...
>
> But I don't recall the exact way this tutorial was doing and I was just 
> exposing to 2 generals reasons why form into modal won't submit 
> correctly... In my case my widget was appending my modal with a LOAD 
> component inside a form of the so the load form has to be put outside the 
> main form... 
>
> I try the ressource you are using and give up because it was not full fill 
> all my requirement...
>
> Richard
>
> On Tue, Apr 28, 2015 at 4:54 PM, LoveWeb2py <atayl...@gmail.com> wrote:
>
> This is what I'm using in my layout:
>
>
>    $(function() {
>     $("td.w2p_fc").each(function (){
>     var comment = $(this).html();
>     if (comment){
>     $(this).html('<div><i class="icon info icon-info-sign"></i></div>'); 
>     $(this).children('div').attr('title',comment); 
>     $(this).children('div').tooltip({ placement : 'right',
>     html : true,
>     trigger : 'click' });
>     }
>     });
>     });
>    
> This makes the comment field available as an "Information Icon"
>
> When I use the modal class referenced in the link it works great, the problem 
> is nothing stores because the form can't process properly. I'm struggling to 
> solve that last piece of the puzzle.
>
> When I 
>
>
>
> On Tuesday, April 28, 2015 at 4:50:34 PM UTC-4, LoveWeb2py wrote:
>
> Thank you, Richard. Where do I put  $("#{modal_id}").appendTo("
> body");
>
> Could I just put that in the HTML file? Something like...
>
> <script>
>  $("#{modal_id}").appendTo("
> body");
> </script>
>
> I tried hardcoding the div_id of my modal into your code, but it didn't 
> work. The database doesn't update properly with the correct foreign key. I 
> also have some date value fields and the calendar.js doesn't pop down so 
> I'm thinking this has something to do with 
> http://linuxapuntes.blogspot.com.ar/2013/03/plugin-modal-bootstrap-web2py.html
>
> Do you have an example of where you'd put the appendTo ?
>
>
>
>
> On Tuesday, April 28, 2015 at 1:04:57 PM UTC-4, Richard wrote:
>
> There is different issue when embed for into a bootstrap 2.3.2 (at 
> least)... One that I found were that <form> tag get ripped off... The other 
> depend of the way the modal form compoenent is included into the main 
> form... Depending how the widget is write the extra are embed beside the 
> original input field which don't work in case of a <form> tag since html 
> <form> can't be nested... Modal don't offer any convenient support à this 
> level and you have to manage this by yourself... But it is easy, you just 
> need to use jquery .appendTo() :
>
> Like that : $("#{modal_id}").appendTo("body");
>
> And extract your component modal form which is nested into the main page 
> form and append it to the body instead...
>
> This is basically what jQuery Dialog is doing out of the box which 
> boostrap modal don't that make the usage of modal with component in web2py 
> so difficult...
>
> :)
>
> Richard
>
>
> On Tue, Apr 28, 2015 at 12:40 PM, LoveWeb2py <atayl...@gmail.com> wrote:
>
> Richard,
>
> This is working great. 
> http://linuxapuntes.blogspot.com.ar/2013/03/plugin-modal-bootstrap-web2py.html
>
> I currently use it like this:
>
> def my_controller():
>     from modalplugins Import Modal
>     field = db.mytable.field
>     modal = Modal(field, ' Add', 'Add area','Area')
>     db.mytable.field.comment = modal.create()
>     grid=SQLFORM.smartgrid(db.my_other_table)
>     formModal = modal.formModal()
>     return(grid=grid, formModal=formModal)
>
> The problem I am having now is that I can't process the modal. Do you have 
> any thoughts on how to do this?
>
> On Friday, April 17, 2015 at 9:50:15 AM UTC-4, Richard wrote:
>
> 'reference tablename' = 1 to many
> 'list:reference tablename' = "many to many" it denormalised that why I put 
> it between double quotes
>
> Richard
>
> On Thu, Apr 16, 2015 at 5:13 PM, LoveWeb2py <atayl...@gmail.com> wrote:
>
> Richard,
>
> I did want to have a foreign key for info_about_field1. I guess I could do 
> a reference field1 ?
>
>
>
> On Thursday, April 16, 2015 at 3:02:51 PM UTC-4, Richard wrote:
>
> There is no relation between both tables... You can embed 2 forms as 
> component (LOAD())
>
> if you were having list:reference type field it is differents and you have 
> to question yourself if you are not better to have something like 
> SELECT_OR_ADD_OPTION() or even better AutocompleteSelectOrAddOption() 
> widget... I recently update my old AutocompleteSelectOrAddOption() widget 
> (not finish yet) in order to move from jquery ui dialog to bootstrap 
> modal... I will publish a web2py slice when done.
>
> Just ask if it interest you I can publish preview here...
>
> Richard
>
> On Thu, Apr 16, 2015 at 2:08 PM, LoveWeb2py <atayl...@gmail.com> wrote:
>
> Hello,
>
> I'd like to have two SQLFORMs right next to each other. 
>
> The second SQLFORM is just going to be linked to the field in table 1, but 
> will be used so the student can make additional comments about a field. 
> Model will look like this:
>
> db.define_table('main_table',
>         Field('field1','string'),
>         Field('field2','string'),
>         migrate=False)
>
> db.define_table('second_table',
>         Field('info_about_field1','list:string'),
>         Field('info_about_field2','list:string')
>         migrate=False)
>
> My question is... is it possible to have the second_table as a link 
> underneath the main_table field. I want to have a modal pop up so they can 
> enter additional information about the field
>
>
>  -- 
> 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.
> 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.
> 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.
> 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.
> For more options, visit https:/ <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.

Reply via email to