$r.render("sourceview")
public class GuiDemoFlexiForm extends FormBasicController {

  private TextElement firstName;
  private TextElement lastName;
  private TextElement institution;
  private Submit submit;
  private GuiDemoFlexiFormPersonData personData;
  private VelocityContainer confirm;
  private GuiDemoFlexiForm confirmController;

  public GuiDemoFlexiForm(UserRequest ureq, WindowControl wControl, GuiDemoFlexiFormPersonData data) {
    super(ureq, wControl);
    // first you may preprocess data to fit into the form items
    // if all preprocessing is done, create the form items
    //
    // example for simple preprocessing - check for NULL
    if(data != null){
      personData = data;
    }else{
      personData = new GuiDemoFlexiFormPersonData();
    }
    //
    // calls our initForm(formlayout,listener,ureq) with default values.
    initForm(ureq);
    //
    // after initialisation you may need to do some stuff
    // but typically initForm(..) is the last call in the constructor.
  }

  /**
   @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#doDispose(boolean)
   */
  @Override
  @SuppressWarnings("unused")
  protected void doDispose(boolean asynchronous) {
  // TODO Auto-generated method stub

  }

  /**
   @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#formOK(org.olat.core.gui.UserRequest)
   */
  @Override
  @SuppressWarnings("unused")
  protected void formOK(UserRequest ureq) {
    // this method is called if the form has validated
    // which means that all form items are filled without error
    // and all complex business rules validated also to true.
    //
    // typically the form values are now read out and persisted
    //
    // in our case, save value to data object and prepare a confirm page
    personData.setFirstName(firstName.getValue());
    personData.setLastName(lastName.getValue());
    personData.setInstitution(institution.getValue());
    personData.setReadOnly(true);
    //show the same form in readonly mode.
    confirmController = new GuiDemoFlexiForm(ureq, getWindowControl(), personData);
    confirm = createVelocityContainer("confirm");
    confirm.put("data", confirmController.getInitialComponent());
    initialPanel.pushContent(confirm);
  }

  @Override
  protected void formNOK(UserRequest ureq) {
    //in the error case, let the error messages be rerendered in AJAX mode
    //this will change
    this.flc.setDirty(true);
  }
  
  /**
   @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#initForm(org.olat.core.gui.components.form.flexible.FormItemContainer, org.olat.core.gui.control.Controller, org.olat.core.gui.UserRequest)
   */
  @Override
  @SuppressWarnings("unused")
  protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
    /*
     * create a form with a title and 4 input fields to enter some persons data
     */
    setFormTitle("guidemo_flexi_form_simpleform");
    final int defaultDisplaySize = 32;
    final boolean inputMode = !personData.isReadOnly();
    firstName = new TextElementImpl("firstname", personData.getFirstName()){
      {
        this.displaySize = defaultDisplaySize;
        setNotLongerThanCheck(256"notlongerthan");
        setLabel("guidemo.flexi.form.firstname"null);
        setNotEmptyCheck("guidemo.flexi.form.mustbefilled");
        setMandatory(true);
        setEnabled(inputMode);
      }
    };
    formLayout.add(firstName);
    
    lastName = new TextElementImpl("guidemo.flexi.form.lastname", personData.getLastName()){
      {
        this.displaySize = defaultDisplaySize;
        setNotLongerThanCheck(256"guidemo.flexi.form.notlongerthan");
        setLabel("guidemo.flexi.form.lastname"null);
        setNotEmptyCheck("guidemo.flexi.form.mustbefilled");
        setMandatory(true);
        setEnabled(inputMode);
      }
    };
    formLayout.add(lastName);
    
    institution = new TextElementImpl("institution", personData.getInstitution()){
      {
        this.displaySize = defaultDisplaySize;
        setNotLongerThanCheck(256"guidemo.flexi.form.notlongerthan");
        setLabel("guidemo.flexi.form.institution"null);
        setEnabled(inputMode);
      }
    };
    formLayout.add(institution);
    
    if(inputMode){
      //submit only if in input mode
      submit = new FormSubmit("submit","submit");
      formLayout.add(submit);
    }
  }
  
}