Well, having to do validation in model seems like a step backwards from what I have now. There are already validators that can be attached to objects, no to mention, that I would have issues with feedback, etc.

I still don't think layered model is a way to go. Currently, I have a solution, that works well form me. But it has two drawbacks.

1. It's really hacky.

2. It uses the invalidInput property of form components to store temporary values. When clicking on an ImmediateButton, all form components are marked invalid (so that they remember the values in invalidInput) and all feedbackMessages are supressed. So after clicking immediateButton, all feedback messages are hidden (even the valid one).

The advantages are that validation works as usual.

I'm attaching the source code in case anyone needs this. It seems that this behavior (not implementation) won't have enough support to get into wicket.

-Matej


Johan Compagner wrote:
first of all we are talking about 2 problems here!

Matej's and Laurent problems are completely different.

I still believe that Matej should use a temp model (in between model)
And the validations shouldn't be on the component level but between the between model and the real (strong typed) model. I really believe this is the best way. Any thing i can currently think of will result in something like that anyway.. The values Need to be stored somewhere!!
So having something like a model:

Model(Model realModel)
{
    Hashmap values;

    getObject(Component comp)  return values.get(comp);
    setObject(Component comp, Object value) values.put(comp, value);

   public void saveToReal()
   {

        Object realObject = realModel.getObject(null);

        while( Iterate over the values maps keys)
                Component key;
                String stringValue;
                Object value = converter.convertToType(stringValue);
                validator.validate(key,value)
String id = key.getId() // or get some kind of binding see BoundedCompoundPropertyModel
                Objects.setValue(id,realObject,value,null);
   }
}

this is just a rought idea how a in between model should or could work.


Laurents problem is completely different, He doesn't want to hold the data (and do nothing with it) over multiply pages. He just wants portions to be validated and portions to be kept for one request only but not validated. I think this is now already possible with the Button.defaultFormProcessing boolean Then the buttons must have a list of components which he must be validated before he does process everything. then he can call FormComponent.validate() and if that goes ok FormComponent.updateModel() (and so on on the complete List)

I think we are then where we are. You just need a special button that has a list of FormComponents to be validated...



On 11/16/05, *Johan Compagner* <[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>> wrote:

    i still think in youre case you have to use a inbetween model
    There is no other way. Even if we stored it inside the form itself
    then that is the inbetween model
    And i don't know if i want to support that.




    On 11/16/05, *Matej Knopp* <[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]> >
    wrote:

        Hi.

        The problem is, that I don't want to validate the form, unless user
        clicks 'OK'. The model is updated after validation only. But the
        'choose' button should NOT validate the form.

        I don't think it's a good thing storing the temporary values in
        model
        (at least in my case), because model is typed. The temporary values
        should only be strings (get from Http request).

        -Matej

        Johan Compagner wrote:
 Just one extra remark.
 Why can't use just use a model for this?
 And that model is an in between model for you real model object?

 Ok you have to do youre validation a bit different  (it can't
        be between
 Form->Model
 but it has to be between TmpModel->RealModel

 This looks to me like a much better way to have multiply page
        forms...

 johan


 On 11/13/05, *Matej Knopp* < [EMAIL PROTECTED]
        <mailto:[EMAIL PROTECTED]> <mailto: [EMAIL PROTECTED]
        <mailto:[EMAIL PROTECTED]>>> wrote:

    Hi.

    I know this has been discussed already, but still I'm
        opening it once
    more. I think there should be a way to preserve form state
        without
    validation and model updating.

    The use case is following.
    I have a (complex) form with some fields, that can not be
        entered
    directly, i.e. they have to be selected on other page. So I
        need to move
    between pages, but I don't want to lose any information
        entered on the
    previous page. If I use Button, the form gets processed,
        validated, etc
    and the action won't execute unless all entered data is
        valid. If I turn
    defaultProcessing off, the action executes, but the data
        (not written to
    model yet) is lost.

    What I'm using now is little hacky, but it works. I have my
        own class
    derived from Form, my own SubmitButton, ImmediateButton and
    FeedbackPanel. ImmediateButton acts like classic Button with
    defaultFormProcessing turned off, but unlike it,
        ImmediateButton stores
    the state in each component (in the string reserved for
        invalid data).
    So there's my own Feedback panel (Although filter would be
        probably
    enough) that detects that ImmediateButton was clicked and hides
    validation messages (there's a lot of them, because
        ImmediateButton
    marks every component as invalid).

    This approach works pretty well, but doesn't feel quite
        right. I think
    there definitely should be a way to preserve form state
        (without
    validation and updating model) directly supported by wicket.
    Not to mention that (if I recall correctly) the string field in
    FormComponent used for storing invalid data is transient.

    Btw. I've managed to persuade people from my company to use
        wicket for
    one of our projects. Since I do most of the current
        development, it's
    not a big deal, because I've personally been using wicket
        for some time
    now. But I can say they are really impressed with the
        productivity and
    simplicity of certain actions (like moving between complex
        pages forth
    and back ;) - that are sometimes quite difficult and
        cumbersome in
    struts.
    Not to mention excellent DataView and DatePicker
        components, markup
    inheritance and compoents in general.

    Kudos wicket team, you're doing excelent work!

    Sorry for really long mail,

    -Matej


    -------------------------------------------------------
    SF.Net email is sponsored by:
    Tame your development challenges with Apache's Geronimo App
        Server.
    Download
    it for free - -and be entered to win a 42" plasma tv or
        your very own
    Sony(tm)PSP.  Click here to play:
        http://sourceforge.net/geronimo.php
    _______________________________________________
    Wicket-user mailing list
    [email protected]
        <mailto:[email protected]>
    <mailto: [email protected]
        <mailto:[email protected]>>
    https://lists.sourceforge.net/lists/listinfo/wicket-user





        -------------------------------------------------------
        This SF.Net email is sponsored by the JBoss Inc.  Get Certified
        Today
        Register for a JBoss Training Course.  Free Certification Exam
        for All Training Attendees Through End of 2005. For more info visit:
        http://ads.osdn.com/?ad_id=7628&alloc_id=16845&op=click
        <http://ads.osdn.com/?ad_id=7628&alloc_id=16845&op=click>
        _______________________________________________
        Wicket-user mailing list
        [email protected]
        <mailto:[email protected]>
        https://lists.sourceforge.net/lists/listinfo/wicket-user




package framework.wicket.ext;

import wicket.feedback.FeedbackMessage;
import wicket.feedback.IFeedbackMessageFilter;
import wicket.markup.html.form.FormComponent;

public class FeedbackPanel extends wicket.markup.html.panel.FeedbackPanel {

    public FeedbackPanel(String id) {
        super(id);
    }

       
    public boolean isVisible() {        
        return 
!getPage().getFeedbackMessages().messages(getFeedbackMessageFilter()).isEmpty();
    }    
     
    protected boolean acceptFeedbackMessage(FeedbackMessage message) {
        return true;
    }
    
    final protected IFeedbackMessageFilter getFeedbackMessageFilter() {
        return new IFeedbackMessageFilter() {
            public boolean accept(FeedbackMessage message) {

                if (acceptFeedbackMessage(message) == false)
                        return false;
                
                if (message.getReporter() instanceof FormComponent) {
                    FormComponent component = (FormComponent) 
message.getReporter();
                    if (component.getForm() instanceof Form) {
                        return ((Form)component.getForm()).isEnableFeedback();
                    }
                }
                return true;
            }    
        };
    }
}
package framework.wicket.ext;

import wicket.markup.html.form.Button;

public class ImmediateButton extends Button {

    public ImmediateButton(String id) {
        super(id);
        setDefaultFormProcessing(false);
    }
    
    public ImmediateButton(String id, boolean preserveState) {
        super(id);
        setDefaultFormProcessing(false);
        setPreserveFormState(preserveState);
    }

    protected final void onSubmit() {
        if (getPreserveFormState() && getForm() instanceof Form) {
            Form form = (Form) getForm();
            form.saveState();
            form.setEnableFeedback(false);
        }
        onClick();
    }
    
    protected void onClick() {        
    }
    
    public void setPreserveFormState(boolean saveFormState) {
        this.preserveFormState = saveFormState;
    }
    
    public boolean getPreserveFormState() {
        return preserveFormState;
    }
    
    protected boolean preserveFormState = false;
}
package framework.wicket.ext;

import wicket.model.IModel;

public class Form extends wicket.markup.html.form.Form {
      
    public Form(String id) {
        super(id);
    }

    public Form(String id, IModel model) {
        super(id, model);
    }
        
    protected boolean process() {
        setEnableFeedback(true);
        return super.process();
    }
    
    public void setEnableFeedback(boolean enableFeedback) {
        this.enableFeedback = enableFeedback;
    }
    
    public boolean isEnableFeedback() {
        return enableFeedback;
    }
    
    public void saveState() {
        validate();
        markFormComponentsInvalid();
    }
    
    private boolean enableFeedback = true;
        
}
package framework.wicket.ext;

import wicket.markup.html.form.Button;

public class SubmitButton extends Button {

    public SubmitButton(String id) {
        super(id);
    }
        
    final protected void onSubmit() {
        onClick();
    }
    
    protected void onClick() {
        
    }
}

Reply via email to