SQLFORM.grid, how to edit non-visible field in the onvalidate function?

567 views
Skip to first unread message

A36_Marty

unread,
Feb 7, 2014, 9:43:19 AM2/7/14
to web...@googlegroups.com
I'm stumped.  Have tried this with the grid, custom forms, etc. 

Could someone advise how to achieve the questions highlighted below - or - if it can't be done with a grid, how to achieve it?

db.define_table('table',
                Field('field_hidden', 'string'),
                Field('field_not_hidden', 'string'))

def index():
    
    Question: Code to hide 'field_hidden' to user but still make it available in the validate_grid function?
    
    grid = SQLFORM.grid(table, onvalidation=validate_grid)

    return grid
    
def validate_grid(form):
    
    Question: Code to be able to modify 'field_hidden' here & have it written to the database?
    
    form.accepted = True

Massimo Di Pierro

unread,
Feb 7, 2014, 2:43:09 PM2/7/14
to web...@googlegroups.com
What makes it hidden in the first place? I do not see a difference in the fields  except for the names.

A36_Marty

unread,
Feb 8, 2014, 12:55:26 AM2/8/14
to web...@googlegroups.com
I've given up on trying hide a field in the grid yet still be able to see and modify it in the onvalidation route.

I tried for a few hours to achieve the same via custom forms by using hidden={'fieldname':value}.  I could see the hidden field in the validation function of the custom form, but couldn't get the value in the storage fields to make it back to the database.

Having given up on the custom form route, I'm now trying to simply hide the field in question using jQuery on the form.  i.e. $("#table_hidden_field__row").hide(), however, the jQuery doesn't select the element on the document.ready() even though it has a unique id -- maybe because it is in a component and shown by Ajax / not caught by document.ready?  

Have re-read the Overview, Core, and Forms and Validators section of the manual again -- thinking I'm missing some key concept -- but don't see what I'm missing.

Have read dozens of Google Group posts with no luck.

Planning on downloading some sample web2py applications again like the CRM project and hopefully see something in the code there that enlightens me.

If anyone can provide advice or nudge in the right direction of what to try next, please let me know.    

I'm just a hobbyist, trying to learn, but am fast thinking I should just stick to spreadsheets / this is proving to be over my head.

LightDot

unread,
Feb 8, 2014, 2:36:33 AM2/8/14
to web...@googlegroups.com
Hello Marty,


On Saturday, February 8, 2014 6:55:26 AM UTC+1, A36_Marty wrote:
I've given up on trying hide a field in the grid yet still be able to see and modify it in the onvalidation route.

I tried for a few hours to achieve the same via custom forms by using hidden={'fieldname':value}.  I could see the hidden field in the validation function of the custom form, but couldn't get the value in the storage fields to make it back to the database. (..cut..)

You're probably not missing much here. The SQLFORM does not process hidden fields automatically, that's a security measure. You need to manually transfer such values from request.vars back into form.vars, for example:

form=SQLFORM(....)
form.vars.field_hidden=request.vars.field_hidden
if form.accepts(....)

Keep in mind that hidden form fields can be altered by the user. You have no guarantee what the value of the hidden field is after you've received it back.
 
I'm just a hobbyist, trying to learn, but am fast thinking I should just stick to spreadsheets / this is proving to be over my head.

Nah, keep at it! :) Sure, some issues will take time to troubleshoot, but it gets easier after every one. Web2py is very intuitive and the Web2py Book, this group, slices, etc. are great resources.

Regards

A36_Marty

unread,
Feb 8, 2014, 2:14:46 PM2/8/14
to web...@googlegroups.com
Thanks for your help LightDot.   It's nice to be pointed in direction after several days of getting nothing done.

One question on hidden fields that I'm missing -- as I have everything working except for hiding the field from the user.

<Model>
db.define_table('table',
                Field('field_hidden', 'string'),
                Field('field_not_hidden', 'string'))

<Controller>
grid = SQLGRID

If request.args(0) in ['new]:
    response.view = 'default/custom_edit.html'
    form = SQLFORM(db.table, hidden={'field_hidden':0})
    forms.vars.field_hidden = request.vars.field_hidden

    if form.process(onvalidation=form_validation).accepted:
        redirect to appropriate page

def form_validation(form):
    
    modify form.vars as needed
    form.accepted = True


Everything works except I am unable to hide the field 'field_hidden' on the customer SQLFORM with the hidden attribute (hidden={'field_hidden':0}). The field is just shown as normal.    Triple checked the field spelling, etc.   If I use db.table.field_hidden.readable, .writable = False, it is not shown, but I am then unable to change the field values in the form_validation function... 

Not sure what I'm missing with the hidden syntax....   Any help is appreciated.




On Friday, February 7, 2014 8:43:19 AM UTC-6, A36_Marty wrote:

Larry Weinberg

unread,
Feb 8, 2014, 4:19:02 PM2/8/14
to web...@googlegroups.com
 will one of these work?

form.element('input',_name="field_hidden")['_type'] = "hidden"

form.element('input[name="field_hidden"]')['_type'] = "hidden"

A36_Marty

unread,
Feb 9, 2014, 2:56:48 AM2/9/14
to web...@googlegroups.com
Made some progress -- got a the field not showing to user yet visible in the onvalidation function.

Now, a new problem.   When I change the value of the hidden field in the onvalidate function, it doesn't get written to the database.  The value remains whatever was passed as the default in the SQLFORM(hidden=dict())

The code

db.define_table('person',
                Field('name', 'string'),
                Field('hidden', 'string'))

def index():
    form = SQLFORM(db.person, fields=['name'], hidden=dict(hidden="Default hidden text"))

    form.vars.hidden = request.vars.
    
    if form.process(onvalidation=validate_form).accepted:
        pass

    return dict(form=form)

def validate_form(form):

    form.vars.hidden = "Changed hidden text"   #Never gets written to database
    form.accepted = True


In the code above the field db.person.hidden always receives the value "Default hidden text".   What needs to change to get it to what it is set to in validate_form, "Changed hidden text"?


On Friday, February 7, 2014 8:43:19 AM UTC-6, A36_Marty wrote:

A36_Marty

unread,
Feb 9, 2014, 11:26:27 AM2/9/14
to web...@googlegroups.com
A little more progress -- hopefully to help someone else that Googles for this and ends up stumped like I was...  I've spent an inordinate amount of time and frustration figuring out little nuances that I wouldn't wish upon anyone...   

Gotca's that I learned:

1) To hide a field, first remove it from the fields to be shown in the SQLFORM, then add it back with the hidden= attribute.  Just specifying it as hidden does not remove it.

i.e. This does NOT work, the field 'hidden' is shown to the user:
db.define_table('person',
               Field('name', 'string'),
               Field('hidden', 'string'))

def index():
   form = SQLFORM(db.person, hidden=dict(hidden="Default hidden text"))

    form.vars.hidden = request.vars.
   

This DOES work:

db.define_table('person',
              Field('name', 'string'),
              Field('hidden', 'string'))

def index():
  form = SQLFORM(db.person, fields=['name'], hidden=dict(hidden="Default hidden text"))

    form.vars.hidden = request.vars.


2) To get a list of fields to show (from a larger table definition, so as to not hand-type each field name), you must get a copy of the fields from the table object, not just a reference to the fields.

i.e. This DOES NOT work.  The field will be be removed and unseen by the user, however since Python works by reference, the field is removed from the table definition and the form.accepted() will fail as web2py will try to insert a value into field that no longer exists.

db.define_table('person',
              Field('name', 'string'),
              Field('hidden', 'string'))

def index():

  fields_to_show = db.person.fields
  fields_to_show.remove('hidden')

  form = SQLFORM(db.person, fields= fields_to_show, hidden=dict(hidden="Default hidden text"))



    form.vars.hidden = request.vars.Enter code here...

This DOES work (only 3 characters difference) - making a copy of the fields list instead of getting it by reference:

db.define_table('person',
              Field('name', 'string'),
              Field('hidden', 'string'))

def index():

  fields_to_show = db.person.fields[:]
  fields_to_show.remove('hidden')

  form = SQLFORM(db.person, fields= fields_to_show, hidden=dict(hidden="Default hidden text"))



    form.vars.hidden = request.vars.Enter code here...


3. To update the value of the hidden fields (or any fields), the form.vars modification must be before the form.process call.

i.e. This DOES NOT work.

db.define_table('person',
                Field('name', 'string'),
                Field('hidden', 'string'))

def index():
    form = SQLFORM(db.person, fields=['name'], hidden=dict(hidden="Default hidden text"))

    form.vars.hidden = request.vars.
    
    if form.process(onvalidation=validate_form).accepted:
        pass

    return dict(form=form)

def validate_form(form):

    form.vars.hidden = "Changed hidden text"   #Never gets written to database
    form.accepted = True

This does work:

db.define_table('person',
                Field('name', 'string'),
                Field('hidden', 'string'))

def index():
    form = SQLFORM(db.person, fields=['name'], hidden=dict(hidden="Default hidden text"))

    form.vars.hidden = request.vars.

    form.vars.hidden = "Changed hidden text"   #Successfully written to database
    
    if form.process(onvalidation=validate_form).accepted:
        pass

    return dict(form=form)

def validate_form(form):

    form.accepted = True

Take care...


Mirek Zvolský

unread,
Aug 3, 2014, 6:03:23 PM8/3/14
to web...@googlegroups.com
Thank you very much.
But seems following works for me too:

    form = SQLFORM.factory(
        Field('find_contact_string', label="Choose from contacts"),
        Field('contact_id', readable=False, writable=False),
        hidden=dict(contact_id='')
        )
    if form.process(onvalidation=_validate_form).accepted:
        db.invoice[request.args(0)] = dict(contact_id=form.vars.contact_id)
        redirect(URL(......))        
    return dict(form=form)

def _validate_form(form):
    if request.vars.contact_id:
        form.vars.contact_id = request.vars.contact_id
    else:
        form.errors.find_contact_string = "Enter a text to find the customer"

I assign the errors message to the visible field (find_contact_string).
contact_id I change with jQuery:
$('[name=contact_id]').val(2);





Dne neděle, 9. února 2014 17:26:27 UTC+1 A36_Marty napsal(a):
Reply all
Reply to author
Forward
0 new messages