Is okay for your form to receive an IModel and is also okay not to receive any models and use a LodableDetachableModel warpped in a CompoundPropertyModel internally as per my precious e-mail.
Okay, let's stick with the form constructor having an IModel argument. What's this model? DetachableCnavUrlModel? Why not just a simple LoadableDetachableModel<T>? LoadableDetachableModel<CnavUrl> cnavUrlLDM = new LoadableDetachableModel<CnavUrl>() { private static final long serialVersionUID = 1L; @Override protected CnavUrl load() { return myDao.getCnavUrl(some id here); } }; Now wrap that in a CompoundPropertyModel like so: Form form = new CnavForm("cnavForm", new CompoundPropertyModel<CnavUrl>(cnavUrlLDM)); Your CnavForm would then use the property names of CnavUrl for its component IDs. Hope that makes more sense for you now, but you should really re-read chapter 9 "Wicket models and forms" of the Wicket Free Guide at (it will save you lots of time!): http://wicket.apache.org/learn/books/freeguide.html ~ Thank you, Paul Bors -----Original Message----- From: Daniel Watrous [mailto:dwmaill...@gmail.com] Sent: Tuesday, July 23, 2013 4:39 PM To: users@wicket.apache.org Subject: Re: Form questions I've had a difficult time following your recommendations. However I think I'm getting closer. Part of the disconnect is that right now, as I show above, the model object I create is in the Form, not the Page. In my Page I create an instance of my Form like this: Form form = new CnavForm("cnavForm"); add(form); So, the first step I've taken is to implement a constructor for my Form that receives an IModel and, rather than create my CnavUrl, I get it from the IModel: CnavUrl cnavUrl = (CnavUrl) model.getObject(); setModel(new Model((Serializable) cnavUrl)); Now I create my Form object like this: DetachableCnavUrlModel cnavUrlModel = new DetachableCnavUrlModel(new MorphiaCnavUrl()); Form form = new CnavForm("cnavForm", cnavUrlModel); add(form); I'm now at the page level when I create my Model and I have a DetachableCnavUrlModel, which I also use when displaying them. if (cnavid != null) { cnavUrlModel = new DetachableCnavUrlModel(cnavUrlDAO.getCnavById(cnavid)); } else { cnavUrlModel = new DetachableCnavUrlModel(new MorphiaCnavUrl()); } Form form = new CnavForm("cnavForm", cnavUrlModel); add(form); This way on edit I have a prepopulated form. To answer my other question about the link, I created a PageParameters object and used setResponsePage like this item.add(new Link("editlink") { @Override public void onClick() { PageParameters editParameters = new PageParameters(); editParameters.add("cnavid", ((MorphiaCnavUrl)cnavUrl).getId()); setResponsePage(CnavModify.class, editParameters); } }); I can then use the value in the parameters to set cnavid if (parameters.get("cnavid").toString() != null) { cnavid = new ObjectId(parameters.get("cnavid").toString()); } Thanks for all the help. Daniel On Fri, Jul 19, 2013 at 9:38 AM, Paul Bors <p...@bors.ws> wrote: > For stateless pages it would create a new one each time (add the > DebugBar to your pages and see if your page is stateless or not and > also see what the model is per component). > > For when Wicket serializes your page, you don't want a PropertyModel > alone, you want a detachable model (see section 9.6 of the Wicket Free > Guide or go over chapter 9 again "Wicket models and forms"). You need > to wrap a Detachable model inside a Property model like so: > > add(new TextField("url", new PropertyModel<MorphiaCnavUrl>(new > LoadableDetachableModel<MorphiaCnavUrl>(cnavUrl), "URL")) > .setRequired(true) > .add(new UrlValidator())); > > Is best to use a CompoundPropertyModel for the entire form and get to > your POJO that feeds the entire form (or panel) via a detachable model. > > The LoadableDetachableModel is desined to only serialize the record ID > for which you can later retrieve the entire object from your persistence layer. > > ~ Thank you, > Paul Bors > > -----Original Message----- > From: Daniel Watrous [mailto:dwmaill...@gmail.com] > Sent: Friday, July 19, 2013 11:24 AM > To: users@wicket.apache.org > Subject: Re: Form questions > > Paul, > > Thanks. I get that and understand how the Model happens. As you can > see, the instance of the model object is created in the constructor. > So the first question I had is whether a new instance is created for > every request or if there's one instance that's serialized. I suspect > it's the second, knowing how Wicket treats sessions. In that case, I > need some way on a per request basis to load the model from the > database. > > The other question I had is how to create a link that sends the ID to > the page that renders the form. I need to create a link to that page, > include an ID value with the request and then access that ID within > the form for my query to load that object from the DB. > > Daniel > > > On Thu, Jul 18, 2013 at 5:14 PM, Paul Bors <p...@bors.ws> wrote: > > > Okay let's pre-populate this field: > > > > add(new TextField("url", new PropertyModel(cnavUrl, "URL")) > > .setRequired(true) > > .add(new UrlValidator())); > > > > Its mode is a new PropertyModel(cnavUrl, "URL"), which is the > > "CnavUrl cnavUrl = new MorphiaCnavUrl();". > > So it's the cnavUrl.getUrl() value. > > > > What do you get when you call new MorphiaCnavUrl().getUrl()? > > That's what should appear in the TextField when you first load the > > page (normally read form the DB). > > > > ~ Thank you, > > Paul Bors > > > > -----Original Message----- > > From: Daniel Watrous [mailto:dwmaill...@gmail.com] > > Sent: Thursday, July 18, 2013 6:03 PM > > To: users@wicket.apache.org > > Subject: Re: Form questions > > > > I've made a lot of progress and been through chapters 9 and 10 of > > Wicket Free Guide, but I'm still stumped on point #2, pre-populating > > the > form. > > Here's what I have right now: > > > > public class CnavForm extends Form { > > > > @Inject private CnavUrlDAO cnavUrlDAO; > > > > public CnavForm(String id) { > > super(id); > > CnavUrl cnavUrl = new MorphiaCnavUrl(); > > setModel(new Model((Serializable) cnavUrl)); > > > > add(new TextField("url", new PropertyModel(cnavUrl, "URL")) > > .setRequired(true) > > .add(new UrlValidator())); > > add(new HiddenField("objectid", new PropertyModel(cnavUrl, > > "id"))); > > > > add(new Button("publish") { > > @Override > > public void onSubmit() { > > CnavUrl cnavUrl = (CnavUrl) > CnavForm.this.getModelObject(); > > // check for existing record to know if this is a > > create or update > > if (((MorphiaCnavUrlModel)cnavUrl).getId() == null) { > > // create > > cnavUrlDAO.save(cnavUrl); > > } else { > > // update > > cnavUrlDAO.save(cnavUrl); > > } > > } > > }); > > } > > } > > > > I need to know how to do two things. > > 1) how to link to the page that displays the form, and pass it the > > ID for the record I want to edit > > 2) load the object from the database and have it replace the model I > > create in the constructor > > > > Obviously I can make a database call and get the object. Is the > > constructor called every time the page is requested, so that I could > > check for an ID and either create the model or load it from the > > database? If so, then I just need help with #1. > > > > Thanks, > > Daniel > > > > > > On Wed, Jul 17, 2013 at 10:19 AM, Daniel Watrous > > <dwmaill...@gmail.com>wrote: > > > > > I think I'm getting it now. The Form needs to be embedded in a > > > panel for the type of inclusion that I'm interested in. > > > > > > I created a CnavFormPanel.java and changed CnavForm.html to > > > CnavFormPanel.html. I left CnavForm.java alone. > > > > > > In CnavModify.java I removed this > > > > > > Form form = new CnavForm("cnavFormArea"); > > > add(form); > > > > > > And added this > > > > > > add(new CnavFormPanel("cnavFormArea")); > > > > > > That works. Thanks for your help. > > > > > > Daniel > > > > > > > > > On Wed, Jul 17, 2013 at 10:07 AM, Daniel Watrous > > <dwmaill...@gmail.com>wrote: > > > > > >> I can make it work if I put the markup from CnavForm.html > > >> directly into CnavModify, but the form is not as reusable then. I > > >> would have to duplicate the markup for other pages that use the same form... > > >> > > >> Dnaiel > > >> > > >> > > >> On Wed, Jul 17, 2013 at 9:55 AM, Daniel Watrous > > <dwmaill...@gmail.com>wrote: > > >> > > >>> That's what I tried to do. I created CnavForm.java and > > >>> CnavForm.html. In the latter file I have this > > >>> <wicket:panel> > > >>> <form wicket:id="cnavForm"...> > > >>> // form details > > >>> </form> > > >>> </wicket:panel> > > >>> > > >>> Then I have CnavModify.java and CnavModify.html. You already see > > >>> what I have in CnavModify.java from my last email. My > > >>> CnavModify.html > > has this. > > >>> <wicket:extend> > > >>> <span wicket:id="cnavFormArea">Here's the form</span> > > >>> </wicket:extend> > > >>> > > >>> Rather than render I'm getting this error: > > >>> Last cause: Component [cnavFormArea] (path = [0:cnavFormArea]) > > >>> must be applied to a tag of type [form], not: '<span > > wicket:id="cnavFormArea" > > >>> id="cnavFormArea3">' (line 0, column 0) > > >>> > > >>> I'll keep trying and report back when I figure it out. > > >>> > > >>> Daniel > > >>> > > >>> > > >>> On Tue, Jul 16, 2013 at 10:50 PM, Paul Bors <p...@bors.ws> wrote: > > >>> > > >>>> Wicket is a MVC component driven framework similar to Swing. > > >>>> In short, what you want to do is create your own Panel with > > >>>> that form file of yours and add it to another Panel as a child. > > >>>> > > >>>> See chapter 4 "Keeping control over HTML" of the Wicket Free > > >>>> Guide > at: > > >>>> http://code.google.com/p/wicket-guide/ > > >>>> > > >>>> Also available from under the Learn section as the Books link > > >>>> on the right side navigation section on Wicket's home page at: > > >>>> http://wicket.apache.org/learn/books/ > > >>>> > > >>>> ~ Thank you, > > >>>> Paul Bors > > >>>> > > >>>> -----Original Message----- > > >>>> From: Daniel Watrous [mailto:dwmaill...@gmail.com] > > >>>> Sent: Tuesday, July 16, 2013 7:13 PM > > >>>> To: users@wicket.apache.org > > >>>> Subject: Re: Form questions > > >>>> > > >>>> Thanks Paul and Sven. I got the form to work and available in > > >>>> the onSubmit handler. > > >>>> > > >>>> Now I'm interested in splitting the form out into it's one file. > > >>>> So I created a class that has nothing more than the form, but > > >>>> I'm not sure how to include this into a page. > > >>>> > > >>>> In my class I do this: > > >>>> > > >>>> public class CnavModify extends ConsoleBasePage { > > >>>> > > >>>> public CnavModify(PageParameters parameters) { > > >>>> super(parameters); > > >>>> > > >>>> Form form = new CnavForm("cnavFormArea"); > > >>>> add(form); > > >>>> } > > >>>> } > > >>>> > > >>>> My CnavModify obviously extends a base page. What do I put > > >>>> inside the <wicket:extend> tag to have the form render? > > >>>> > > >>>> Daniel > > >>>> > > >>>> > > >>>> On Tue, Jul 16, 2013 at 12:00 AM, Sven Meier <s...@meiers.net> > wrote: > > >>>> > > >>>> > Hi, > > >>>> > > > >>>> > > > >>>> > Some problems I can't figure out. The code to create the > > >>>> > button complains > > >>>> >> that it requires a CnavUrl but gets back a String. > > >>>> >> > > >>>> >> add(new Button("publish", model) { > > >>>> >> @Override > > >>>> >> public void onSubmit() { > > >>>> >> CnavUrl cnavUrl = (CnavUrl) getModelObject(); > > >>>> >> System.out.println("publish"); > > >>>> >> } > > >>>> >> }); > > >>>> >> > > >>>> > > > >>>> > a Button always has a IModel<String> to fill the value attribute. > > >>>> > Note that in #onSubmit() you're getting the model object of > > >>>> > the button, not of your form. > > >>>> > You can write: > > >>>> > > > >>>> > add(new Button("publish", model) { > > >>>> >> @Override > > >>>> >> public void onSubmit() { > > >>>> >> CnavUrl cnavUrl = (CnavUrl) > > >>>> MyForm.this.getModelObject(); > > >>>> >> System.out.println("publish"); > > >>>> >> } > > >>>> >> }); > > >>>> >> > > >>>> > > > >>>> > Using generic types in your code should help you. > > >>>> > > > >>>> > Sven > > >>>> > > > >>>> > > > >>>> > > > >>>> > On 07/15/2013 11:41 PM, Daniel Watrous wrote: > > >>>> > > > >>>> >> Hello, > > >>>> >> > > >>>> >> I'm interested in creating a single Form that will > > >>>> >> accommodate the following use cases > > >>>> >> 1) display blank for creating new records > > >>>> >> 2) pre-populate for editing existing records > > >>>> >> 3) map submitted values on to an existing domain object > > >>>> >> 4) accommodate two actions, Save Draft -or- Publish > > >>>> >> > > >>>> >> I'm following Wicket in Action and within my Form > > >>>> >> constructor I create my model, like this > > >>>> >> > > >>>> >> CnavUrl cnavUrl = new BasicCnavUrl(); > > >>>> >> IModel model = new Model((Serializable) cnavUrl); > > >>>> >> setModel(model); > > >>>> >> > > >>>> >> I then use PropertyModel > > >>>> >> > > >>>> >> add(new TextField("url", new PropertyModel(cnavUrl, > > >>>> >> "url"))); > > >>>> >> > > >>>> >> For the two actions, I'm creating the Button objects like > > >>>> >> this > > >>>> >> > > >>>> >> add(new Button("publish", model) { > > >>>> >> @Override > > >>>> >> public void onSubmit() { > > >>>> >> CnavUrl cnavUrl = (CnavUrl) getModelObject(); > > >>>> >> System.out.println("publish"); > > >>>> >> } > > >>>> >> }); > > >>>> >> > > >>>> >> Some problems I can't figure out. The code to create the > > >>>> >> button complains that it requires a CnavUrl but gets back a > String. > > >>>> >> > > >>>> >> It seems that a new BasicCnavUrl is created once with the Form. > > >>>> >> What happens on subsequent calls? Can I always expect my > > >>>> >> model to have the data from the current form submission? > > >>>> >> > > >>>> >> Is there a best way to incorporate the idea of an edit, > > >>>> >> where the model is pre-populated from a data source and > > >>>> >> pre-fills the Form > > >>>> fields? > > >>>> >> > > >>>> >> Thanks, > > >>>> >> Daniel > > >>>> >> > > >>>> >> > > >>>> > > > >>>> > ------------------------------**----------------------------- > > >>>> > -* > > >>>> > *- > > >>>> > ----- > > >>>> > --- To unsubscribe, e-mail: > > >>>> > users-unsubscribe@wicket.**apache.org > > >>>> <users-unsubscribe@wicket.apache. > > >>>> > org> For additional commands, e-mail: > > >>>> > org> users-h...@wicket.apache.org > > >>>> > > > >>>> > > > >>>> > > >>>> > > >>>> --------------------------------------------------------------- > > >>>> -- > > >>>> -- > > >>>> -- To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org > > >>>> For additional commands, e-mail: users-h...@wicket.apache.org > > >>>> > > >>>> > > >>> > > >> > > > > > > > > > -------------------------------------------------------------------- > > - To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org > > For additional commands, e-mail: users-h...@wicket.apache.org > > > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org > For additional commands, e-mail: users-h...@wicket.apache.org > > --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org For additional commands, e-mail: users-h...@wicket.apache.org