Update ...
I found one problem: when I was dynamically adding form fields as html
elements, I wasn't adding them as field objects to the form object on the
postback so w2p didn't know about the fields for validation.
But I still must be confused how components work. I load the form but the
submit action reloads the entire page and therefore does not process the
form. What am I missing? ...
Action:
def send_msg():
return dict()
View:
{{extend 'layout.html'}}
<div id="send_msg_form">
{{=LOAD('sendmsg','get_msg_vars',ajax=True)}}
</div>
Component:
def get_msg_vars():
fields = []
fields.append(db.msg.msg_typ)
if request.vars['msg_typ']:
db.msg.msg_typ.default = request.vars['msg_typ']
msg_typ = db.msg_typ(request.vars['msg_typ'])
for var in msg_typ.msg_typ_vars:
msg_typ_var_lbl = ' '.join(x.capitalize() for x in
var.split('_'))
fields.append(Field(var, label=msg_typ_var_lbl,
requires=IS_NOT_EMPTY()))
form=SQLFORM.factory(*fields)
mt = form.element(_name='msg_typ')
mt['_onchange'] = XML("ajax('get_msg_vars', ['msg_typ'],
'send_msg_form');")
if form.accepts(request,session):
response.flash="form accepted"
elif form.errors:
response.flash="form is invalid"
else:
response.flash="please fill the form"
return form
On Sunday, August 11, 2013 8:37:15 AM UTC-4, Michael Beller wrote:
>
> Thanks Derek,
>
> I've tried a few approaches and can't get a good scenario to work.
>
> If I add an onchange event using:
> form=SQLFORM(db.msg, fields=['msg_typ'])
> mt = form.element(_name='msg_typ')
> mt['_onchange'] = XML("ajax('get_msg_vars', ['msg_typ'],
> 'send_msg_form');")
>
> I then added the div to the form using:
> dv = DIV('', _id='send_msg_form')
> mtvars = form.element(_id='msg_msg_typ__row')
> mtvars.append(dv)
>
> and then have the function get_msg_vars retrieve the list:string and add
> the input fields to the div, I can't get the form to validate the fields.
>
> I tried also tried using a LOAD component for the entire form but then the
> onchange event doesn't work. This was my alternate approach and it almost
> works - you have to hit submit for the form to update:
>
> def send_msg():
> return dict(form=LOAD(url=URL(r=request,f='get_msg_vars.load'),
> ajax=True, target='send_msg_form'))
>
> def get_msg_vars():
> fields = []
> fields.append(db.msg.msg_typ)
> if request.vars['msg_typ']:
> db.msg.msg_typ.default = request.vars['msg_typ']
> msg_typ = db.msg_typ(request.vars['msg_typ'])
> for var in msg_typ.msg_typ_vars:
> msg_typ_var_lbl = ' '.join(x.capitalize() for x in
> var.split('_'))
> fields.append(Field(var, label=msg_typ_var_lbl,
> requires=IS_NOT_EMPTY()))
> form=SQLFORM.factory(*fields)
> mt = form.element(_name='msg_typ')
> mt['_onchange'] = XML("ajax('get_msg_vars', ['msg_typ'],
> 'send_msg_form');")
> if form.accepts(request.vars):
> response.flash = 'ok'
> return dict(message="Hello %s" % form.vars)
> return dict(form=form)
>
> I read some other posts that indicate there may be problems with the
> hidden form fields that are generated if I try to replace the entire form
> using ajax and the load as above.
>
> My only other option that I can think of is to not use ajax or a component
> and recreate the form each postback but this would require setting the
> msg_type to read only and having a reset button. I'm going to try that
> next unless anybody has a better idea.
>
> Is there something I'm missing about using ajax/load to dynamically add
> fields to the form?
>
> Thanks.
>
> On Monday, August 5, 2013 7:00:17 PM UTC-4, Derek wrote:
>>
>> Rig up the onchange of the message type dropdown to the load function...
>>
>> On Monday, August 5, 2013 1:00:45 PM UTC-7, Michael Beller wrote:
>>>
>>> I have a requirement to create a message based on the user selecting a
>>> message type. Each message type has a fixed text component and a set of
>>> zero, one, or more variable components.
>>>
>>> Ideally, I'd like the user to select the message type from a list and
>>> have the form dynamically display zero, one, or more fields for entering
>>> each variable component without posting back the entire page. I've
>>> researched LOAD and Ajax options in the book, along with using a field type
>>> of list:string, but I haven't defined a good approach. I've also read
>>> about the conditional fields but not how to have a dynamic set of
>>> conditional fields.
>>>
>>> Worst case, I could just postback the form and display a page with the
>>> new form for that message type (and make the message type read only).
>>>
>>> Any ideas? Thanks.
>>>
>>> Here is the base model ...
>>>
>>> db.define_table('msg_typ',
>>> Field('msg_typ_id'),
>>> Field('msg_typ_name'),
>>> Field('msg_typ_body'),
>>> Field('msg_typ_vars', type='list:string'),
>>> format='%(msg_typ_name)s',
>>> migrate=True)
>>>
>>> db.define_table('msg',
>>> Field('msg_typ', type='reference msg_typ'),
>>> Field('msg_vars', type='list:string'), # ideally, this would be a
>>> dictionary with the vars from the msg_typ table along with their values
>>> migrate=True)
>>>
>>>
>>>
--
---
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 [email protected].
For more options, visit https://groups.google.com/groups/opt_out.