Anyway Bill,

I think there is room for including this in web2py. Your patch is in
the queue...

Thank you.

Massimo

On Oct 20, 7:05 am, billf <[EMAIL PROTECTED]> wrote:
> I have come up with a solution that requires no changes to web2py
> code.  I have written out an explanation 
> athttp://www.wellbehavedsystems.co.uk/web2py/examples/custom_forms.html
>
> For simplicity, I have just put the code in the db.py file but it
> could be in a module.  Any suggestions for improvements gratefully
> received.
>
> On Oct 20, 12:12 am, billf <[EMAIL PROTECTED]> wrote:
>
> > This is where my lack of knowledge of python lets me down - I just
> > didn't know that you could override a method like that.  I will have a
> > play.
>
> > On Oct 19, 11:33 pm, mdipierro <[EMAIL PROTECTED]> wrote:
>
> > > I have not had the time but I do like your second solution. You can do
>
> > > SQLFORM.myfunc=lambda self: myfunc(self)
>
> > > Anyway, If I am not mistaken you only need myfunc in views hence I am
> > > not sure you need it to be a method of SQLFORM, it could simply be a
> > > normal function that acts on the form.
>
> > > Massimo
>
> > > On Oct 19, 2:27 pm, billf <[EMAIL PROTECTED]> wrote:
>
> > > > Massimo
>
> > > > Did you get a chance to look at my modifications to html.py?
>
> > > > FYI I have looked at creating a solution outside of the core web2y
> > > > files either as a totally separate class or extending SQLFORM.
>
> > > > The former is based on the idea of extracting the necessary form
> > > > values from the standard SQLFORM or FORM into a new class and passing
> > > > that to the view but I am having problems supporting the session/
> > > > formkey logic as the formkey is calculated when {{=form}} in the view
> > > > is processed and that would include the standard form in the view
> > > > which is contrary to the whole purpose.
>
> > > > The latter is made more difficult (impossible?) with the addition of
> > > > t2 as the t2 methods use SQLFORM so any subclass would be ignored as
> > > > far as I can see.
>
> > > > So back to my html.py suggestion - any thoughts?
>
> > > > On Oct 15, 9:29 am, billf <[EMAIL PROTECTED]> wrote:
>
> > > > > I have noted one problem with my suggestion.  As coded, a standard,
> > > > > non-custom form throws an error with customview not defined.  I
> > > > > thought that
>
> > > > > if self.customview and self.customview=True:
>
> > > > > in FORM.xml() would catch the absence of customview but doesn't seem
> > > > > to(?) so I have changed it to
>
> > > > > if not self.customview: self.customview=False
> > > > > if self.customview==True:
>
> > > > > Bill
>
> > > > > On Oct 14, 3:15 pm, mdipierro <[EMAIL PROTECTED]> wrote:
>
> > > > > > give me some time to digest this. could email it to me again. the
> > > > > > indentation is messed up.
>
> > > > > > On Oct 14, 5:58 am, billf <[EMAIL PROTECTED]> wrote:
>
> > > > > > > My objective is to be able to hand-code my own view containing a 
> > > > > > > form
> > > > > > > that I can layout exactly as I want but retain the benefits of
> > > > > > > accepts() re validation and db updating.
>
> > > > > > > I found 2 obstacles with web2py out-of-the box:
> > > > > > > 1) In my view (I have less than 1 week of python), I did not have 
> > > > > > > easy
> > > > > > > access to the latest version of a field: defaults could be in
> > > > > > > form.record.my_field (but not for a new record) but if the user 
> > > > > > > has
> > > > > > > input data then it is in form.vars.my_field.  I wanted a 
> > > > > > > consistent
> > > > > > > source and the only place is form.components but extracting the 
> > > > > > > values
> > > > > > > in the view seems difficult due to the nested nature of 
> > > > > > > components.
>
> > > > > > > 2) For dropdown lists, the value is not enough.  I want the whole
> > > > > > > <select><options> etc including which option is selected.
>
> > > > > > > If I can achieve the above there are a couple of other 
> > > > > > > requirements:
> > > > > > > 3) For completeness, support for the session/formkey mechanism 
> > > > > > > and any
> > > > > > > other hidden fields that may be specified.
>
> > > > > > > 4) If I display the whole control (as in 2) above), I don't want 
> > > > > > > any
> > > > > > > pre-formatted errors.  I can get the necessary info from 
> > > > > > > form.errors.
>
> > > > > > > With my solution, the usage is as follows:
> > > > > > > - in a controller, after the SQLFORM(db.recipe) or FORM(whatever) 
> > > > > > > is
> > > > > > > created add form.customview=True
>
> > > > > > > - in a view, after the <form> tag for your custom form add 
> > > > > > > {{=form}} -
> > > > > > > this will create a Storage called 'latest' in FORM with a 'value' 
> > > > > > > and
> > > > > > > a 'component' for each fieldname and return the following:
> > > > > > > <!-- custom view -->
> > > > > > > <input value="130911852535" type="hidden" name="_formkey" />
> > > > > > > <input value="recipe" type="hidden" name="_formname" />
> > > > > > > ... plus any other hidden INPUTS specified in the form
>
> > > > > > > - if you just want the latest value for a fieldname 'name' then 
> > > > > > > code
> > > > > > > something like
> > > > > > > <input type="text" name="name" 
> > > > > > > value="{{=form.latest.name['value']}}"/
>
> > > > > > > - if you just want the whole control then code something like
> > > > > > > {{=form.latest.name['component']}} to get
> > > > > > > <input type="text" class="string" name="name" value="Cornish 
> > > > > > > Pasty"
> > > > > > > id="recipe_name" />"
>
> > > > > > > - or, where the field has IS_IN_SET, code
> > > > > > > {{=form.latest.type['component']}} to get
> > > > > > > <select class="string" name="type" id="recipe_type"><option
> > > > > > > value="A">accompaniment</option><option value="C">component</
> > > > > > > option><option value="R" 
> > > > > > > selected="selected">recipe</option></select>
>
> > > > > > > So, assuming anyone's still interested, what changes did I make 
> > > > > > > to the
> > > > > > > web2py code?  Well, it's all in html.py and makes use of a new 
> > > > > > > Storage
> > > > > > > attribute called 'latest' added to FORM if customview is present 
> > > > > > > and
> > > > > > > True:
>
> > > > > > > a) replace the existing FORM.xml() method with the following:
> > > > > > >     def xml(self):
> > > > > > >         if self.customview and self.customview==True:
> > > > > > >             self._latestdata()
> > > > > > >             # return hidden INPUTs in response to {{=form}}
> > > > > > >             hidden=''
> > > > > > >             field=self.latest['hidden']
> > > > > > >             for component in field['component']:
> > > > > > >                 hidden+=component.xml()+'\n'
> > > > > > >             return '<!-- custom view -->\n'+hidden
> > > > > > >         else:
> > > > > > >             # exactly the same as old xml() except hidden logic in
> > > > > > > common method _hiddendata([])
> > > > > > >             newform=FORM(*self.components,**self.attributes)
> > > > > > >             self._hiddendata(newform.components)
> > > > > > >             return DIV.xml(newform)
> > > > > > >     # common method for creating/storing formkey and creating 
> > > > > > > hidden
> > > > > > > INPUTs - taken from original xml()
> > > > > > >     def _hiddendata(self, components):
> > > > > > >         if self.session!=None:
> > > > > > >             _formkey='_formkey[%s]' % self.formname
> > > > > > >             key=self.session[_formkey]=str(random.random())[2:]
>
> > > > > > > components.append(INPUT(_type='hidden',_name='_formkey',_value=key))
> > > > > > >         if self.formname!=None:
> > > > > > >             
> > > > > > > components.append(INPUT(_type='hidden',_name='_formname',\
> > > > > > >                            _value=self.formname))
> > > > > > >         if self.attributes.has_key('hidden'):
> > > > > > >             hidden=self['hidden']
> > > > > > >             for key,value in hidden.items():
>
> > > > > > > components.append(INPUT(_type='hidden',_name=key,_value=value))
> > > > > > >     # create the Storage to hold value and component for each
> > > > > > > fieldname + one for 'hidden' INPUTs
> > > > > > >     def _latestdata(self):
> > > > > > >         self.latest=Storage()
> > > > > > >         components=[]
> > > > > > >         self._hiddendata(components)
>
> > > > > > > self.latest['hidden']={'value':'hidden','component':components}
> > > > > > >         for component in self.components:
> > > > > > >             component._latestdata(self.latest)
>
> > > > > > > a) add the following to DIV to find the required component and 
> > > > > > > store
> > > > > > > in latest Storage
> > > > > > >     def _latestdata(self, latest):
> > > > > > >         # the following code checks whether the component can have
> > > > > > > user input and
> > > > > > >         # if true stores the value and component using the 
> > > > > > > latestitem
> > > > > > > helper
> > > > > > >         # if false iterates through child components
> > > > > > >         if self.attributes.has_key('_value') and\
> > > > > > >            self.attributes.has_key('_name'):
>
> > > > > > > latest[self.attributes['_name']]=self.latestitem(self.attributes['_value'],self)
> > > > > > >         elif isinstance(self,SELECT) and\
> > > > > > >            self.attributes.has_key('_name'):
>
> > > > > > > latest[self.attributes['_name']]=self.latestitem(None,self)
> > > > > > >         elif isinstance(self,TEXTAREA) and\
> > > > > > >            self.attributes.has_key('value') and\
> > > > > > >            self.attributes.has_key('_name'):
> > > > > > >             value=self.attributes['value']
> > > > > > >             if value==None: value=''
>
> > > > > > > latest[self.attributes['_name']]=self.latestitem(value,self)
> > > > > > >         elif self.components:
> > > > > > >             for c in self.components:
> > > > > > >                 if hasattr(c,'_latestdata'): c._latestdata(latest)
> > > > > > >     # store value and component ensuring any errors are ignored
> > > > > > >     def latestitem(self, value, component):
> > > > > > >         component.errors=None
> > > > > > >         return {'value':value,'component':component}
>
> > > > > > > That's it - it all seems to work a
>
> ...
>
> read more ยป
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"web2py Web Framework" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/web2py?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to