Thanks for your responses guys. @Peter you are correct, I should have been a bit clearer there. The User object is indeed stored in session and yes I am worried that potentially "invalid" data could be displayed on other pages (as the session.User data has been updated from the original form submission).
>If so I'd consider instead of editing (what I call) the SiteUser, just load >and edit a User object >and then you can session.SiteUser = UserService.getByID( >session.SiteUser.getID() ); to reload any changes >to the site user in session scope once the new User object has been >successfully validated and saved. That could work, but I wonder if it could get too complicated with other potential "instance" data the User object might have (site layout, current shopping cart composed objects etc). @Mark >In that case, why not duplicate() (or write your own clone() method), >on the user, and populate THAT with data? :D Could you explain this a bit further? Ideally the following would happen: - Form loads with current session.User data loaded into the form controls - User edits form and submits - Validation fails -> View reloads with the data the user edited in the form - BUT the session.User still retains the original data It's almost as if I shouldn't use: <input type="text" name="email" id="email" value="#oUser.getEmail()#" / > but instead use: <input type="text" name="email" id="email" value="#request.input.email#" /> Then at the top of the "view" I can have something like: <cfif structKeyExists(form, "submitted")> <cfset session.User.save(form) /> <cfset request.input = form /> <cfelse> <cfset request.input = structNew() /> <cfset request.input.email = session.User.getEmail() /> etc </cfif> @Kevan - wow, long post :) Most of that sounds like what I've use a User object for. Think I'll need to re-read in the morning to digest properly. Good food for thought though! On Sep 24, 11:11 pm, "Kevan Stannard" <[EMAIL PROTECTED]> wrote: > Validation discussions frequently bring up the concept of populating beans > with potentially invalid data then calling a bean.validate() function, but > something doesn't quite feel right about it for me. > > If I have a date field in my bean, then I would like it to be a real date > value (or an empty string meaning null), or if I have a numeric field in my > bean then I want it to be a real numeric value. Allowing them to be anything > entered by a user just doesn't feel right - but that is just where my head > is at right now. > > I have been handling general add/edit forms as follows (it's a bit of a long > story ...) > > I create a "FormHelper" object that is aware of all fields on the form > (including hidden, visible and dynamic fields). It knows how to transform > database data or objects into form field values and visa versa. > > For a User add/edit form I would have a UserFormHelper with some functions > as follows: > > * setField(name,value) > * getField(name) > Functions to set/get form field values. > > * initialiseFields() > This initialises an internal struct with all of the fields in the form. It > sets each of the fields to their initial value. These values would be for > "add/new" forms. This function essentially defines the fields that are > permitted in the form. The field names exactly match the actual form field > names. This is called from the init() function and has code that looks like: > > <cfset setField("userId",0)> > <cfset setField("firstName","")> > <cfset setField("lastName","")> > > * loadByUsedId(userId) > This initialises the helper fields from the database. But this could also be > something like loadByUserBean(user). This calls the setField() function for > each field, but with the value from the database/bean. This is used for an > "edit" form. > > * loadByEvent(event) > This initialises the helper fields from an "event", which is just the > combined form and url scopes. This is used when attempting to save a form. > The submitted form values are passed into the helper via this function. > > * validate() > This validates the form data. This may also populate beans and call their > validate() functions, but this helper validation is aware of the entire form > which may span multiple bean types. This function sets errors inside the > helper. > > * save() > Calls validate() and if no errors, performs the save (via > services/gateways). If errors during the save occur, then additional errors > may be set. > > I would generally use the helper as follows: > > * newUser event: > > <cfset helper = createObject("component","UserFormHelper").init()> > > In the form, use code such as: > > <cfset userId = helper.getField("userId")> > <input type="hidden" name="userId" value="#userId#"> > > <cfset firstName = helper.getField("firstName")> > <input type="hidden" name="firstName" value="#userId#"> > > * editUser event: > > <cfset userId = event.get("userId")> > <cfset helper = createObject("component","UserFormHelper").init()> > <cfset helper.loadByUserId(userId)> > > Then the form display code is the same as above. > > * saveUser event: > > <cfset helper = createObject("component","UserFormHelper").init()> > <cfset helper.loadByEvent(event)> > <cfset helper.save()> > <cfif not helper.hasErrors()> > <cfset userId = helper.getField("userId")> > <cflocation > url="/some/dir/index.cfm?event=editUser&userId=#userId#"> > </cfif> > <!--- > Then display the same form again, but with error messages. The helper has a > function getErrors() which returns a collection of formfield error messages. > ---> > > The helper manages the data with the form display in mind. It holds any > submitted invalid data which is redisplayed exactly as entered back onto the > form when errors occur, it also prepares data for display - such as > converting datetime fields from the database into the correct display values > for the form. Essentially it is a representation of the form as the server > sees it - without the UI - just a bunch of name/value pairs. > > I have a base FormHelper that all other form helpers extend, so there is not > much work in setting up new forms. > > Overall this has been working out quite nicely for me, but would love to > hear others ideas. > > Kevan > > -----Original Message----- > From: cfcdev@googlegroups.com [mailto:[EMAIL PROTECTED] On Behalf Of > > Michael Sharman > Sent: Wednesday, 24 September 2008 3:28 PM > To: CFCDev > Subject: [CFCDEV] Using object "getters" after form validation fails > > Hi guys, > > I'm after some suggestions for a quite common scenario. I have a site > where users are registered (i.e. they have a profile) and have the > option of updating their details after logging in. > > I load the "update" form's controls from a User.cfc > > e.g. <input type="text" name="email" id="email" > value="#oUser.getEmail()#" /> > > Now when the form gets submitted validation takes place and if that > validation fails the update form is reloaded with an error message. > The problem is that I want to display the new information that the > user has entered even though it hasn't yet been updated in the > database. > > I feel I can't update the User objects "state" if the validation fails > as the user may navigate away from the update form and as the rest of > the site depends on the User object's information this would be > potentially incorrect. > > Would I be looking at some kind of memento pattern here? Some kind of > a global #request.input# struct? How do people get around this, > hopefully without complicating/messing up views with a cfparam for > each User property etc > > Thanks --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "CFCDev" group. To post to this group, send email to cfcdev@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/cfcdev?hl=en -~----------~----~----~----~------~----~------~--~---