simple button in grid question

216 views
Skip to first unread message

Alex Glaros

unread,
Sep 13, 2013, 4:00:56 PM9/13/13
to web...@googlegroups.com
How do I add a button "Add a comment!" in every row of a grid? It's a kind of virtual column.

The below works, it takes user exactly to the correct row in the next table, but I use up one of the fields (Idea.id).  How do I just create text/virtual column that doesn't sacrifice existing field?


 def view_all_suggestions_and_comments(): 
    db.Idea.id.represent = lambda id, r: A('Add a comment!', _href=URL('comment_on_a_suggestion', vars=dict(filter=id)))    
    query = (db.IdeaComment.ideaID==db.Idea.id) & (db.IdeaComment.partyID==db.Party.id)
    grid = SQLFORM.grid(query) 
    return dict(grid = grid) 


I read the book but need exact syntax for this situation.

Thanks,

Alex Glaros

villas

unread,
Sep 13, 2013, 4:33:35 PM9/13/13
to web...@googlegroups.com
Hope this helps...

From the book:

links
is used to display new columns which can be links to other pages. The links argument must be a list of dict(header='name',body=lambda row: A(...)) where header is the header of the new column and body is a function that takes a row and returns a value. In the example, the value is a A(...) helper.

Example:

    linkbtns = [
                 
lambda row: SPAN('Mag',_class="label label-success") \
                                 
if row.status =='Y' else '',
                 
lambda row: SPAN('Web',_class="label label-success") \
                                 
if row.is_active else '',
                 
lambda row: A( I('',_class="icon-eye-open")+' View',
                                    _href
=URL("view",args=[row.id]),
                                    _class
="btn btn-small"
                             
),
                 
lambda row: A( I('',_class="icon-edit")+' Edit',
                                    _href
=URL("edit",args=[row.id]),
                                    _class
="btn btn-small"
                             
),
                 
lambda row: A( I('',_class="icon-road")+' Map',
                                    _href
=URL('default','geocoder',args=['caclient',row.id],vars={'title':row.business}),
                                    _class
="btn btn-small"
                             
),
               
]
    grid
= SQLFORM.grid(....... links=linkbtns, .......)

Alex Glaros

unread,
Sep 13, 2013, 4:57:28 PM9/13/13
to web...@googlegroups.com
I tried this but got "lambda requires 2 args, 1 given" error, plus need to be able to pass Idea.id parm to the button.  How to do that?

    grid = SQLFORM.grid(query,links = [dict(header='Virtual Field',body=lambda id, r: A('Add a comment!', _href=URL('comment_on_a_suggestion', vars=dict(filter=id))))])

Dave S

unread,
Sep 13, 2013, 6:06:45 PM9/13/13
to web...@googlegroups.com

On Friday, September 13, 2013 1:57:28 PM UTC-7, Alex Glaros wrote:
I tried this but got "lambda requires 2 args, 1 given" error, plus need to be able to pass Idea.id parm to the button.  How to do that?

    grid = SQLFORM.grid(query,links = [dict(header='Virtual Field',body=lambda id, r: A('Add a comment!', _href=URL('comment_on_a_suggestion', vars=dict(filter=id))))])

I'm going to guess the "1 given" arg is  "row", and you need to use "filter=row.id" over on the end of your URL().
See below.


On Friday, September 13, 2013 1:33:35 PM UTC-7, villas wrote:
Hope this helps...

From the book:

links
is used to display new columns which can be links to other pages. The links argument must be a list of dict(header='name',body=lambda row: A(...)) where header is the header of the new column and body is a function that takes a row and returns a value. In the example, the value is a A(...) helper.

Example:

    linkbtns = [
                 
lambda row: SPAN('Mag',_class="label label-success") \
                                 
if row.status =='Y' else '',
                 
lambda row: SPAN('Web',_class="label label-success") \
                                 
if row.is_active else '',
                 
lambda row: A( I('',_class="icon-eye-open")+' View',
                                    _href
=URL("view",args=[row.id]),
                                    _class
="btn btn-small"
                             
),
                 
lambda row: A( I('',_class="icon-edit")+' Edit',
                                    _href
=URL("edit",args=[row.id]),

like this this ^^^ (see above)  


                                    _class
="btn btn-small"
                             
),
                 
lambda row: A( I('',_class="icon-road")+' Map',
                                    _href
=URL('default','geocoder',args=['caclient',row.id],vars={'title':row.business}),
                                    _class
="btn btn-small"
                             
),
               
]
    grid
= SQLFORM.grid(....... links=linkbtns, .......)



Apologies if I've gotten this wrong.

/dps
 

villas

unread,
Sep 14, 2013, 7:56:33 AM9/14/13
to web...@googlegroups.com
Try this...

grid = SQLFORM.grid(query,
                                 links = [dict(header='Virtual Field',
                                                   body=lambda row: A('Add a comment!', _href=URL('comment_on_a_suggestion', vars=dict(filter=row.id)))
                                            )]
                                )

Alex Glaros

unread,
Sep 14, 2013, 10:23:49 AM9/14/13
to web...@googlegroups.com
thanks Villas but I receive this error: Row' object has no attribute 'id'

perhaps it doesn't know which of the joined "id"s to reference

this work-around works because it let's system know which id it is:     db.Idea.id.represent = lambda id, r: A('Add a comment!', _href=URL('comment_on_a_suggestion', vars=dict(filter=id)))    

Alex

villas

unread,
Sep 14, 2013, 1:23:00 PM9/14/13
to web...@googlegroups.com
Maybe this would work using row.idea.id like this...

grid = SQLFORM.grid(query,
    links
= [dict(header='Virtual Field',

    body
=lambda row: A('Add a comment!', _href=URL('comment_on_a_suggestion', vars=dict(filter=row.idea.id)))
   
)]
   
)


You can also now include "virtual fields" in grids,  but I haven't needed to try that yet.

Alex Glaros

unread,
Sep 14, 2013, 7:41:24 PM9/14/13
to web...@googlegroups.com
it works correctly Villas, thanks.

how could I turn "Add a comment!" text into a button.  Possible syntax ",_class="btn btn-mini"", but where does it go?

thanks,

Alex

Adi

unread,
Sep 14, 2013, 9:01:33 PM9/14/13
to web...@googlegroups.com
                                lambda row: A('Complete',
                                    _class
='btn', _id='btn_complete',
                                    _onclick
='return confirm("Complete Order %s? (%s %s)")' % (row.id,
                                                                                               row
.shipFirstName,
                                                                                               row
.shipLastName),
                                    _href
=URL(r=request,f='complete_order',args=[row.id]),

Alex Glaros

unread,
Sep 14, 2013, 9:56:24 PM9/14/13
to web...@googlegroups.com
Works perfect Adi and Villas,

much appreciated.

Here's the complete code:

def view_all_suggestions_and_comments(): 
    query = (db.IdeaComment.ideaID==db.Idea.id) & (db.IdeaComment.partyID==db.Party.id
   grid = SQLFORM.grid(query, ,links = [dict(header='Virtual Field',  body=lambda row: A('Add a comment!',_class="btn btn-mini", _href=URL('comment_on_a_suggestion', vars=dict(filter=row.Idea.id))))])
    return dict(grid = grid)   

Alex

Alex Glaros

unread,
Sep 15, 2013, 8:38:45 PM9/15/13
to
What is syntax for two or more  buttons? I've tried several variations. Would it be two "dict" phrases, or two header phrases separated by commas? 

One button will call one function, and the other would call a different function.

thanks,

Alex

Javier Pepe

unread,
Sep 16, 2013, 9:42:22 AM9/16/13
to web...@googlegroups.com
You need pass a list of dict

links = [{'header':'', 'body': lambda row: A('',_title='Procesar',_class='icon-refresh',_href=URL(c='planilla',
          {'header':'', 'body': lambda row: A('',_title='Mail',_class='icon-envelope',_href='index/pedircontadores/%
          {'header':'', 'body': lambda row: A('',_title='Estado',_class='icon-ok',callback=URL(c='planilla',f='estad
          {'header':'', 'body': lambda row: A('',_title='Control',_class='icon-check',_href=URL(c='planilla',f='pdf/
          {'header':'', 'body': lambda row: A('',_title='Control 2',_class='icon-check',_href=URL(c='planilla',f='co
          {'header':'', 'body': lambda row: A('',_title='PDF',_class='icon-print',_href=URL(f='pdf/%s/%s' % (row.id,
          {'header':'', 'body': lambda row: A('',_title='PDF distribuidor',_class='icon-print',_href=URL(f='pdf/%s/%
          {'header':'', 'body': lambda row: A('',_title='Detalle',_class='icon-list',_href=URL(c='detalle',f='index'
          ]



On Sun, Sep 15, 2013 at 9:31 PM, Alex Glaros <alexg...@gmail.com> wrote:
What is syntax for TWO or more  buttons? I've tried several variations. Would it be two "dict" phrases, or two header phrases separated by commas? 

One button will call one function, and the other would call a different function.

thanks,

Alex


On Saturday, September 14, 2013 6:56:24 PM UTC-7, Alex Glaros wrote:

--
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/groups/opt_out.

Adi

unread,
Sep 16, 2013, 10:10:09 AM9/16/13
to web...@googlegroups.com
actually, you can also define a table that links apply to. this way you won't get the error, when applying functionality to a wrong table...

                        links
=dict(purchase_order=[
                           
lambda row:(_get_order_details(row)),
                           
lambda row: A('Duplicate',
                                _class
='button', _href=URL('duplicate_po',args=[row.id])),
                           
lambda row: A('Print', _class='button', _href=URL('print_all',args=[row.id]))
                           
],
                                  other_table
=[
                            lambda row:(_get_something_else(row)),
                                   ],),



Alex Glaros

unread,
Sep 16, 2013, 11:26:18 AM9/16/13
to web...@googlegroups.com
Hi Adi and Javier,

I can't get the syntax to work.  Can you please baby me though the phrasing and just copy the first button twice in this working example so that two identical buttons appear?

def view_suggestions(): 
    db.Idea.id.represent = lambda id, r: A('Post shared services idea', _href=URL('add_sharability_info_to_a_suggestion', vars=dict(filter=id)),_class="btn btn-mini")    
    is_owner = (lambda row: row.created_by == auth.user_id) if auth.user else False  
    grid = SQLFORM.grid(db.Idea,editable=is_owner, deletable=is_owner, user_signature=True,fields=[db.Idea.ideaShortSummary,db.Idea.created_by,db.Idea.id], headers={ 'Idea.ideaShortSummary':'Description'}, maxtextlengths={ 'Idea.ideaShortSummary':140},links = [dict(header='Post comment', body=lambda row: A('Post comment',_class="btn btn-mini", _href=URL('comment_on_a_suggestion', vars=dict(filter=row.id))))]),  
    return dict(grid = grid)  


thanks,

Alex

Adi

unread,
Sep 16, 2013, 11:46:48 AM9/16/13
to web...@googlegroups.com
if you replace the grid part, does this work:


    grid
= SQLFORM.grid(db.Idea,editable=is_owner,
                        deletable
=is_owner,
                        user_signature
=True,
                        fields
=[db.Idea.ideaShortSummary,
                                db
.Idea.created_by,

                                db
.Idea.id],
                        headers
={ 'Idea.ideaShortSummary':'Description'},
                        maxtextlengths
={ 'Idea.ideaShortSummary':140},

                        links
= dict(Idea=[lambda row: A('Post comment',

                                                        _class
="btn btn-mini",
                                                        _href
=URL('comment_on_a_suggestion', vars=dict(filter=row.id))

                                                       
),
                                           
lambda row: A('Post comment',

                                                         _class
="btn btn-mini",
                                                         _href
=URL('comment_on_a_suggestion', vars=dict(filter=row.id))

                                                         
),                                          
                                           
],
                                     
)
                       
)

Alex Glaros

unread,
Sep 16, 2013, 3:33:26 PM9/16/13
to web...@googlegroups.com
looks like it's getting closer, but receive this error: 

<type 'exceptions.TypeError'> 'str' object is not callable

Alex Glaros

unread,
Sep 16, 2013, 8:22:29 PM9/16/13
to web...@googlegroups.com
Could not get syntax to work. I tried workaround below.  Created two variables with same row-id, but representing two different actions.  What happened was that the first variable, postComment, inherits the second one's, sharedServices, represents attributes, and its button looks and acts exactly as the second one. 

Any ideas as to whether (a) this workaround is a good idea (b) if yes, how to make attributes different?

thanks,

Alex
def view_suggestions(): 
    postComment=db.Idea.id
    sharedSerices=db.Idea.id
     ## All variables get populated with db.Ideaid and each represent clause creates href link to a different function
    postComment.represent = lambda id, r: A('Post comment', _href=URL('comment_on_a_suggestion', vars=dict(filter=id)),_class="btn btn-mini")       
    sharedSerices.represent = lambda id, r: A('Post shared services idea', _href=URL('add_sharability_info_to_a_suggestion', vars=dict(filter=id)),_class="btn btn-mini")
    is_owner = (lambda row: row.created_by == auth.user_id) if auth.user else False  
    grid = SQLFORM.grid(db.Idea,editable=is_owner, deletable=is_owner, user_signature=True,fields=[db.Idea.ideaShortSummary,db.Idea.created_by,sharedSerices,postComment], headers={ 'Idea.ideaShortSummary':'Description','sharedServices':'Shared Services'}, maxtextlengths={ 'Idea.ideaShortSummary':140}),  
    return dict(grid = grid) 


Javier Pepe

unread,
Sep 17, 2013, 7:33:06 AM9/17/13
to web...@googlegroups.com
To chage icons, modify "_class", found more icons in:

Alex Glaros

unread,
Sep 17, 2013, 10:50:59 AM9/17/13
to web...@googlegroups.com
Thanks Javier, I did need the bootstrap page for another task,  but for this problem, I'm looking at your "You need pass a list of dict" examples, and the right parenthesis is missing.  Is that a complete example?  I couldn't get it to work either way, and was wondering if you could type your solution for my example, and create two buttons for the grid?  

thanks,

Alex

villas

unread,
Sep 17, 2013, 11:04:28 AM9/17/13
to web...@googlegroups.com
Tip:  when you are struggling,  take something which works and then using 'baby-steps' incrementally change the example until it is transformed into what you need.

Here is something which you previously said was working:


def view_all_suggestions_and_comments(): 
    query = (db.IdeaComment.ideaID==db.Idea.id) & (db.IdeaComment.partyID==db.Party.id
   grid = SQLFORM.grid(query, ,links = [dict(header='Virtual Field',  body=lambda row: A('Add a comment!',_class="btn btn-mini", _href=URL('comment_on_a_suggestion', vars=dict(filter=row.Idea.id))))])
    return dict(grid = grid)  

Try isolating the links into a new variable mylistoflinks and make it a list (so you can have multiple links):

def view_all_suggestions_and_comments(): 
    query = (db.IdeaComment.ideaID==db.Idea.id) & (db.IdeaComment.partyID==db.Party.id)

    mylistoflinks = [
        dict(header='Virtual Field',  body=lambda row: A('Add a comment!',_class="btn btn-mini", _href=URL('comment_on_a_suggestion', vars=dict(filter=row.Idea.id)))),
        dict(header='Virtual Field',  body=lambda row: A('Add a comment!',_class="btn btn-mini", _href=URL('comment_on_a_suggestion', vars=dict(filter=row.Idea.id)))),
    ]

    grid = SQLFORM.grid(query, links = mylistoflinks )
    return dict(grid = grid)  

Hope that works.  Good luck with your iterations! 

Alex Glaros

unread,
Sep 17, 2013, 11:21:03 AM9/17/13
to web...@googlegroups.com
Thanks Villas, it works perfectly.  I really appreciate the help.

Alex
Reply all
Reply to author
Forward
0 new messages