updated for version 2.1.0

Forms#

Form Action Pojos#

Form action pojos are a special kind of action pojo designed to handle form submit and display.

The following is a typical example of a form action pojo:


/**
 The form pojo used to keep the user input
*/
public class SampleForm implements ZIForm 
{
   public final ZDateProperty dateFrom = new ZDateProperty();
   public final ZDateProperty dateTo = new ZDateProperty();
   public final ZOperation submit = new ZOperation("Submit");
}


@ZMatch("/sampleForm")
public class SampleAction implements ZIFormAction
{ 
  //the form pojo used to hold the values
  private SampleForm form;

  /**
   create a url to this action, 
   use in conjunction with the protected constructor
  */
  public static String createUrl() throws Exception
  {
    SampleAction action = new SampleAction ();
    return ZTemplates.getActionService().createUrl(action);
  }
   
  /** 
    no one else should instantiate the action, 
    urls are created by the static createUrl factory methods
  */
  protected SampleAction() {
 
  }

  /**
    this is called before the form is filled with request parameters, 
    do your initialisation here. Sets a operation listener on the submit operation,
    so "afterSubmit()" is called instead of "after()".
  */
  public void beforeForm() throws Exception
  {
    //instantiate and initialize the form
    form = new SampleForm();
    form.dateFrom.setRequired(true);
    form.dateTo.setRequired(true);
    
    /**
     This associates the afterSubmit method with the form submit 
     when the button associated with the ZOperation form.submit is pressed.
     Causes the OperationListener to be called instead of the default after callback.
     If no ZIOperationListener is added, the default after callback is called.
    */
    form.submit.setOperationListener(new ZIOperationListener()
    {
      @Override
      public void exec() throws Exception
      {
        afterSubmit();
      }
    });
  }

  /**
   returns the initialized Form so the framework can fill in the matching request parameters.
  */
  public SampleForm getForm() throws Exception
  {
    return form;
  }


  /**
   this is called after the submit button has been pressed. 
   See the beforeForm() method for the code that adds the ZIOperationListener
   to the form.submit operation.
  */
  private void afterSubmit() throws Exception
  {
    //first validate
    ZValidator validator = createValidator();

    ZMessages messages = validator.validate();
    // If there are validation errors redisplay the form
    if (messages.isErrors())
    {
      showView(messages);
      return;
    }


    //the user name if needed
    String userName = ZTemplates.getSecurityService().getSecurityProvider().getUserName();
    Date dateFrom = form.dateFrom.getValue();
    Date dateTo = form.dateTo.getValue();
    ...
 
    UpdateSampleFormReqDTO req = new UpdateSampleFromReqDTO(
        userName,
        dateFrom,
        dateTo,
        ...  );

    SampleService ps = ServiceLocator.getSampleService();
    UpdateSampleFormRespDTO resp = ps.updateSampleForm(req);

    if (resp.getReturnCode() != UpdateSampleFormReqDTO.ReturnCode.OK)
    {
      //some Error happened, you should provide some better error message than this example
      messages.addErrorMessage("Error happend: " + resp.getReturnCode());
    }
    else 
    {
      //show success message
      messages.addInfoMessage("Your submit has been successfully processed.");
    }
    showView(messages);
  }


  /**
   create the validator that validates this form.
   could also access backend systems to do validation here
  */
  private ZValidator createValidator()
  {
    ZValidator validator = new ZValidator();

    // validates all required fields.
    // also calls all validators attached to a ZProperty.
    validator.getValidators().add(new ZFormValidator(form, "This field is required."));
    
    // add a custom validator.
    validator.getValidators().add(new ZIValidator()
    {
      @Override
      public void validate(ZMessages messages) throws Exception
      {
        Date dateFrom = form.dateFrom.getValue();
        Date dateTo = form.dateTo.getValue();

        //dont validate empty values
        if (dateFrom == null || dateTo == null)
        {
          return;
        }
        if (!dateFrom .before(dateTo))
        {
          //adds a error message associated with the properties dateFrom and dateTo
          messages.addErrorPropertyMessage("Date from must be before date to.", form.dateFrom , form.dateTo );
        }

        Date today= new Date();
        if (dateFrom.before(today))
        {
          //adds a error message associated with the property dateFrom
          messages.addErrorPropertyMessage("Date from must be in the future.", form.dateFrom );
        }
      }
    });
    return validator;
  }

  /**
   called when the form is to be shown. 
   Because afterForm() adds a ZIOperationListener to the submit operation
   this method is not called when the submit button is pressed. 
   If a second operation named for example "createNew" without listener is added to the form 
   this callback would be called again if the second "createNew" button is pressed.
  */
  @Override
  public void after() throws Exception
  {
    ZMessages messages = new ZMessages();
    
    //user is logged in, get the name
    String userName = ZTemplates.getSecurityService().getSecurityProvider().getUserName();

    // load default data from service, write your own service locator, maybe using spring or EJB or whatever you like
    SampleService ps = ServiceLocator.getSampleService(); 
    DisplaySampleFormRespDTO resp = ps.displaySampleForm(userName);
    if (resp.getReturnCode() != DisplaySampleFormRespDTO.ReturnCode.OK)
    {
      //some Error happened, you should provide some better error message than this example
      messages.addErrorMessage("Error happend: " + resp.getReturnCode());
    }
    else 
    {
      //init the form data 
      fillForm(resp);
    }

    showView(messages);
  }

  /**
   fill the form with values from the backend
  */
  private void fillForm(DisplaySampleFormRespDTO resp)
  {
    form.dateFrom.setValue(resp.dateFrom);
    form.dateTo.setValue(resp.dateTo);
    ...
  }


  /**
   This renders the form and displays the messages
  */
  private void showView(ZMessages res) throws Exception
  {
    //you should write a view factory that assembles the views.
    MyViewFactory fact = new MyViewFactory();
    SampleView sampleView = fact.createSampleView(messages);
    ZTemplates.getServletService().render(sampleView);
  }



}

Form views#

ztemplates comes with support for most html form input elements. It is easy to write your own if the provided ones don't fit.

The form html support is in the package org.ztemplates.html

File SampleView.java#


@ZRenderer(ZVelocityRenderer.class)
public final class SampleView
{
  @ZExpose(render=true)
  final ZFormText dateFrom;

  @ZExpose(render=true)
  final ZFormText dateTo;
 
  @ZExpose(render=true)
  final ZFormSubmit submit;


  public SampleView(SampleForm form)
  {
    //html input tags for the form properties
    this.dateFrom = new ZFormText(form.dateFrom);
    this.dateTo = new ZFormText(form.dateTo);
    this.submitInput = new ZFormSubmit(form.submit);
  }
}

The sample template in file SampleView.vm#

As you can see, a property dateFromBean is exposed to the template too. It contains the unrendered value so you can access the id.


<html>
<body>
<form>
  <div>
    <label for="$dateFromBean.id">Date from</label> $dateFrom 
  </div>
  <div>
    <label for="$dateToBean.id">Date to</label> $dateTo 
  </div>
  <div>
    $submit
  </div>
</form>
</body>
</html>

Form pojos#

In ztemplates form values are kept in form pojos.

Properties in form pojos#

You use properties in forms to hold form values.

There are 2 patterns how to use properties in forms:

Declare a public final field#

This is preferred, as it is easier to read and provides the same functionality as the second pattern.


public class SampleForm implements ZIForm
{
  public final ZStringProperty title = new ZStringProperty();

  public final ZStringProperty homepageUrl = new ZStringProperty();

  public final ZStringProperty description = new ZStringProperty();

  public final ZOperation submit = new ZOperation("Submit");
}

Declare a private final field and provide a getter.#



public class SampleForm implements ZIForm
{
  private final ZStringProperty title = new ZStringProperty();

  private final ZStringProperty homepageUrl = new ZStringProperty();

  private final ZStringProperty description = new ZStringProperty();

  private final ZOperation submit = new ZOperation("Submit");

  public ZStringProperty getTitle() 
  {
    return title;
  }
  public ZStringProperty getHomepageUrl () 
  {
    return homepageUrl ;
  }
  public ZStringProperty getDescription () 
  {
    return description ;
  }
  public ZOperation getSubmit () 
  {
    return submit ;
  }
}

Form Pojos and Sessions#

Form pojos are per request objects and should not be stored in the session.

If you need to keep form state between requests, use the ZIFormService to transfer form state between the form pojo and the servlet session or into a ZFormValues object that is serializable and can be kept in the servet session.

Never keep a form pojo in the servlet session.

Neuen Anhang hinzuf�gen

Du bist nicht autorisiert, Anh�nge zu dieser Seite hochzuladen.
« Diese Seite (Version-) wurde zuletzt am 22-Dez-2013 13:18 von gerdziegler.de ge�ndert.