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 treat. All feedback gratefully
> > > received (this is where Massimo tells me it could all have been done
> > > with 2 lines of python and a regex) :-)
>
> > > Bill
--~--~---------~--~----~------------~-------~--~----~
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