I'm using SQLFORM.grid a lot and it is extremely valuable.

I am in a position where I want to use request.args with a grid and I am 
unsure what the right approach is.

Let's say my db.py model is:
db.define_table('person',
                Field('firstname'),
                Field('lastname'), format='%(firstname)s %(lastname)s')
db.define_table('dog',
                Field('name'),
                Field('owner',db.person))


and in my default controller contains:
@auth.requires_login()
def add_dog():
    person = request.args[0]
    grid = SQLFORM.grid(db.dog.owner == person, args=request.args)
    return {'grid':grid}

The objective here is to show a grid of dogs that belong to only a given 
person ("default/add_dog/1" would show a grid of dogs belonging to 
person.id=1) and this works fine. My regarding using the "Add" button.
My desired behavior is as follows: when one clicks the "Add" button the 
form is prepopulated with the correct owner. I am not sure what is the best 
approach.

The options I have been able to think of are:
1. Let the user define whatever owner they want and then update the owner 
using a callback with the 'oncreate' grid argument.
def add_dog():
    person = request.args[0]
    grid = SQLFORM.grid(db.dog.owner == person, args=request.args, oncreate=
add_callback)
    return {'grid':grid}

def add_callback(form):
    db.dog[form.vars.id] = {'owner':int(request.args[0])}
However this is bad UI design as it makes the user think they can define 
something that they can't

2. I can remove the "owner" field from the create form using createargs and 
then define it with the callback, which is a little better:
def add_dog():
    person = request.args[0]
    grid = SQLFORM.grid(db.dog.owner == person, args=request.args, oncreate=
add_callback, createargs={'fields':['name']})
    return {'grid':grid}

def add_callback(form):
    db.dog[form.vars.id] = {'owner':int(request.args[0])}

3. I can completely override the "Add" behavior by looking for "new" in the 
args and defining my own function. But I would like to use the defaults if 
possible.

4. I can mess around with the html in the view but I don't want to do that.

5. Finally the closest I get to what I want to do is this:
def add_dog():
    person = request.args[0]
    if 'new' in request.args:
        db.dog.owner.default = person
    grid = SQLFORM.grid(db.dog.owner == person, args=request.args)
    return {'grid':grid}

however I am unclear as to how this default propagates in other controllers 
or views. Do I run the risk of having "db.dog.owner.default" defined in a 
context where I do not want it defined? 

Any input as to what would be the recommended approach is welcome.

Thanks
Vincent
(using web2py 2.0.8 from trunk)

-- 



Reply via email to