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

Reply via email to