web2py - Dropdown menu

2019-08-05 05:01发布

问题:

I'm trying to have a dropdown menu for the user to select the database table. I have defined few tables in db.py and I want the user the to select a particular table from a dropdown menu and insert entries. Right now I use SQLFORM:

def index():
    form=SQLFORM(db.selectedtable)  #want to change the table name#
    if form.process().accepted:
       response.flash = 'form accepted'
    elif form.errors:
       response.flash = 'form has errors'
    else:
       response.flash = 'please fill out the form'
    return dict(form=form)

I need the user to select 'selectedtable' value from a dropdown list that shows all the available tables in the DB. I do not necessarily want to retrieve the table values from DB. I am OK with defining a list with the available tables and the dropdown menu can pull the table names from that list. So far I only found IS_IN_DB to automatically create a dropdown and PluginDropdown() but that does not serve my purpose. If soemebody can direct me to the proper way of handling this task I'd be really thankful.

Regards.


Update:

After Anthony's suggession I tried the following with , as I'm not that familiar with JS.

{{extend 'layout.html'}}
{{select='NONE'}}

<form>    
<select>
{{for item in TOOLS:}}
<option value="{{select=item}}">{{=item}}</option>{{pass}}
</select>
 <input type="submit" value="Go!"/>
</form>

<h2>Input form</h2>
{{=form}}

<h2>{{=select}}</h2>

As you might see this doesn't work properly. What I tried to do is to get the user chose value to 'select' variable. But it doesn't work. It always gets the last element in ITEMS (this list is defined in db.py). My next option would be to be call another controller function, passing the user selected value as an argument. Then it can prepare the form with the passed value and send to a view to display

<h2>Input form</h2>
    {{=form}}

But I'm not sure how I can assign the user chosen value to an argument and then call another controller function with that arugument value. If you have any suggestion how I can modify this to get the user chosen value thats very much appreciated. Thank you.

回答1:

You could create a <select> element listing all the tables, and then load the form associated with the selected table as a web2py component via Ajax. In the view of the main page (e.g., /views/default/index.html):

<script>
jQuery(function() {
  jQuery('#table').change(function() {
    web2py_component("{{=URL('default', 'form.load')}}" + "/" +
      jQuery(this).val(), target='form')
  })
})
</script>
{{=SELECT('Select a table', *db.tables, _id='table')}}
<div id="form"></div>

And in a controller (e.g., default.py):

def form():
    if request.args(0) in db.tables:
        response.generic_patterns = ['load']
        return dict(form=SQLFORM(db[request.args(0)]).process())
    else:
        raise HTTP(404)

Note, db.tables is a list of all the tables defined on the db connection object -- it is used in the SELECT() helper in the view to generate a <select> list of all the tables. The script in the view registers a jQuery event handler that fires whenever a different table is selected from the dropdown. The handler calls the web2py_component() function (which is in /static/js/web2py.js), which loads the form component via Ajax into the div with id="form". It appends the value of the selected table to the URL.

In the controller, the form() function checks for the db table name in request.args(0). It then sets response.generic_patterns so the "generic.load" view will be allowed (by default, generic views are only enabled for local requests). Alternatively, you could define your own "form.load" view, or even use a different extension (e.g., "form.html").

Because the form is loaded as a web2py Ajax component, the form submission will be trapped and submitted via Ajax as well, so it will not result in a full page reload.