Package org.olat.core.gui.components.form.flexible.impl

Source Code of org.olat.core.gui.components.form.flexible.impl.FormBasicController

/**
* OLAT - Online Learning and Training<br>
* http://www.olat.org
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS,
* <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Copyright (c) 1999-2006 at Multimedia- & E-Learning Services (MELS),<br>
* University of Zurich, Switzerland.
* <p>
*/
package org.olat.core.gui.components.form.flexible.impl;

import java.util.Map;

import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.form.flexible.FormItem;
import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.FormUIFactory;
import org.olat.core.gui.components.form.flexible.elements.InlineElement;
import org.olat.core.gui.components.panel.Panel;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Disposable;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.controller.BasicController;
import org.olat.core.gui.translator.Translator;
import org.olat.core.logging.AssertException;
import org.olat.core.logging.activity.ThreadLocalUserActivityLoggerInstaller;

/**
* Description:<br>
* The form basic controller acts as a facade for <tt>Flexi.Form</tt>
* generation.
* <ul>
* <li>subclass it, and generate a constructor calling <tt>super(..)</tt></li>
* <li>add also <tt>initForm(this.flc, this, ureq)</tt> to your constructor
* as a last line</li>
* <li>if you want your form layout, provide the velocity page name in the
* <tt>super(..,name)</tt> call.</li>
* <li>add your desired form elements in the <tt>initForm(..)</tt> method
* implementaion</li>
* <li>add your complex business validation logic by overriding the method
* <tt>validateFormLogic(..)</tt></li>
* <li>add your code to read form values and process them further in the
* <tt>formOK(..)</tt> method implementation</li>
* <li>in complex forms with subworkflows the <tt>formInnerEvent(..)</tt>
* method can be overwritten and used the same way as known from
* <tt>event(..)</tt>.</li>
* </ul>
*
* <P>
* Initial Date: 01.02.2007 <br>
*
* @author patrickb
*/
public abstract class FormBasicController extends BasicController {

  public static final int LAYOUT_DEFAULT = 0;
  public static final int LAYOUT_HORIZONTAL = 1;
  public static final int LAYOUT_VERTICAL = 2;
  public static final int LAYOUT_CUSTOM = 3;

  protected FormLayoutContainer flc;

  protected Form mainForm;

  protected Panel initialPanel;

  protected FormUIFactory uifactory = FormUIFactory.getInstance();
 
  public FormBasicController(UserRequest ureq, WindowControl wControl) {
    this(ureq, wControl, null);
  }

  public FormBasicController(UserRequest ureq, WindowControl wControl, String pageName) {
    super(ureq, wControl);
    constructorInit(pageName);
  }

  public FormBasicController(UserRequest ureq, WindowControl wControl, String pageName, Translator fallbackTranslator) {
    super(ureq, wControl, fallbackTranslator);
    constructorInit(pageName);
  }

  protected FormBasicController(UserRequest ureq, WindowControl wControl, int layout){
    super(ureq, wControl);
    if (layout == LAYOUT_HORIZONTAL) {
      // init with horizontal layout
      flc = FormLayoutContainer.createHorizontalFormLayout("ffo_horizontal", getTranslator());   
      mainForm = Form.create("ffo_main_horizontal", flc, this);

    } else if (layout == LAYOUT_VERTICAL) {
      // init with vertical layout
      flc = FormLayoutContainer.createVerticalFormLayout("ffo_vertical", getTranslator());   
      mainForm = Form.create("ffo_main_vertical", flc, this);

    } else if (layout == LAYOUT_CUSTOM) {
      throw new AssertException("Use another constructor to work with a custom layout!");

    } else {
      // init with default layout
      flc = FormLayoutContainer.createDefaultFormLayout("ffo_default", getTranslator());
      mainForm = Form.create("ffo_main_default", flc, this);
    }
    initialPanel = putInitialPanel(mainForm.getInitialComponent());
  }

  protected FormBasicController(UserRequest ureq, WindowControl wControl, int layout, String customLayoutPageName, Form externalMainForm){
    super(ureq, wControl);
    if (layout == LAYOUT_HORIZONTAL) {
      // init with horizontal layout
      flc = FormLayoutContainer.createHorizontalFormLayout("ffo_horizontal", getTranslator());   

    } else if (layout == LAYOUT_VERTICAL) {
      // init with vertical layout
      flc = FormLayoutContainer.createVerticalFormLayout("ffo_vertical", getTranslator());   

    } else if (layout == LAYOUT_CUSTOM && customLayoutPageName != null) {
      // init with provided layout
      String vc_pageName = velocity_root + "/" + customLayoutPageName + ".html";
      flc = FormLayoutContainer.createCustomFormLayout("ffo_" + customLayoutPageName+this.hashCode(), getTranslator(), vc_pageName);

    } else {
      // init with default layout
      flc = FormLayoutContainer.createDefaultFormLayout("ffo_default", getTranslator());
    }
    //instead of the constructorInit's Form.create... use a supplied one
    mainForm = externalMainForm;
    flc.setRootForm(externalMainForm);
    mainForm.addSubFormListener(this);
    initialPanel = putInitialPanel(flc.getComponent());
  }
 
 
  /**
   * should be rarely overwritten, only if you provide infrastructure around flexi forms
   */
  protected void constructorInit(String pageName) {
    String ffo_pagename = null;
    if (pageName != null) {
      // init with provided layout
      String vc_pageName = velocity_root + "/" + pageName + ".html";
      ffo_pagename = "ffo_" + pageName;
      flc = FormLayoutContainer.createCustomFormLayout(ffo_pagename, getTranslator(), vc_pageName);
    } else {
      // init with default layout
      ffo_pagename="ffo_default";
      flc = FormLayoutContainer.createDefaultFormLayout(ffo_pagename, getTranslator());
    }
    //
    mainForm = Form.create("ffo_main_" + pageName, flc, this);
    /*
     * implementor must call initFormElements(...)
     */
    initialPanel = putInitialPanel(mainForm.getInitialComponent());
  }

  protected void initForm(UserRequest ureq) {
    initForm(this.flc, this, ureq);
  }

  /**
   * The creation initialisation and adding form elements to layout happens
   * here.<br>
   * The method is not called automatically, but it should be the last line in
   * your constructor.<br>
   *
   * @param formLayout
   * @param listener
   * @param ureq
   */
  abstract protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq);

  /**
   * The form first validates each element, then it calls the
   * <tt>boolean validateFormLogic(ureq)</tt> from the listening controller.
   * This gives the possibility to implement complex business logic checks.<br>
   * In the case of valid elements and a valid form logic this method is called.
   * Typically one will read and save/update values then.
   */
  abstract protected void formOK(UserRequest ureq);

  /**
   * called if form validation was not ok.<br>
   * default implementation does nothing. Each element is assumed to set
   * errormessages. Needed only if complex business logic is checked even
   */
  protected void formNOK(UserRequest ureq) {
  // by default nothing to do -> e.g. looping until form is ok
  }

  /**
   * Called when a form cancel button has been pressed. The form will
   * automatically be resetted.
   *
   * @param ureq
   */
  protected void formCancelled(UserRequest ureq) {
    // by default nothing to do
  }
 
  /**
   * called if an element was activated resetting the form elements to their
   * initial values. After all resetting took place this method is called.
   *
   * @param ureq
   */
  protected void formResetted(UserRequest ureq) {
  // by default no cleanup is needed outside of the form after resetting
  }

  /**
   * called if an element inside of the form triggered an event
   *
   * @param source
   * @param event
   */
  @SuppressWarnings("unused")
  protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
  // overwrite if you want to listen to inner form elements events
  }

  /**
   * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest,
   *      org.olat.core.gui.components.Component,
   *      org.olat.core.gui.control.Event)
   */
  @SuppressWarnings("unused")
  @Override
  public void event(UserRequest ureq, Component source, Event event) {
    if (source == mainForm.getInitialComponent()) {
      // general form events
      if (event == org.olat.core.gui.components.form.Form.EVNT_VALIDATION_OK) {
        // Set container dirty to remove potentially rendered error messages. Do
        // this before calling formOK() to let formOK override the dirtiness
        // flag
        this.flc.setDirty(true);
        formOK(ureq);
      } else if (event == org.olat.core.gui.components.form.Form.EVNT_VALIDATION_NOK) {
        // Set container dirty to rendered error messages. Do this before calling
        // formNOK() to let formNOK override the dirtiness flag
        this.flc.setDirty(true);
        formNOK(ureq);
      } else if (event == FormEvent.RESET) {
        // Set container dirty to render everything from scratch, remove error
        // messages. Do this before calling
        // formResetted() to let formResetted override the dirtiness flag
        this.flc.setDirty(true);
        formResetted(ureq);
      } else if (event instanceof FormEvent) {
        FormEvent fe = (FormEvent) event;
        // Special case: cancel events are wrapped as form inner events
        if (fe.getCommand().equals(org.olat.core.gui.components.form.Form.EVNT_FORM_CANCELLED.getCommand())) {
          // Set container dirty to clear error messages. Do this before calling
          // formCancelled() to let formCancelled override the dirtiness flag
          this.flc.setDirty(true);
          formResetted(ureq);
          formCancelled(ureq);
          return;
        }       
        /*
         * evaluate normal inner form events
         */
        FormItem fiSrc = fe.getFormItemSource();
        // check for InlineElments
        if(fiSrc instanceof InlineElement){
          this.flc.setDirty(true);
        }
        //
        formInnerEvent(ureq, fiSrc, fe);
        // no need to set container dirty, up to controller code if something is dirty
      }
    }
  }

  /**
   * Set an optional form title that is rendered as a fieldset legend. If you
   * use a custom template this will have no effect
   *
   * @param i18nKey
   */
  protected void setFormTitle(String i18nKey) {
    if (i18nKey == null) {
      this.flc.contextRemove("off_title");
    } else {
      this.flc.contextPut("off_title", getTranslator().translate(i18nKey));     
    }
  }
  /**
   * Set an optional form title that is rendered as a fieldset legend. If you
   * use a custom template this will have no effect
   *
   * @param i18nKey
   * @param args optional arguments
   */
  protected void setFormTitle(String i18nKey, String[] args) {
    if (i18nKey == null) {
      this.flc.contextRemove("off_title");
    } else {
      this.flc.contextPut("off_title", getTranslator().translate(i18nKey, args));
    }
  }

  /**
   * Set an optional description. This will appear above the form. If you use a
   * custom template this will have no effect
   *
   * @param i18nKey
   */
  protected void setFormDescription(String i18nKey) {
    if (i18nKey == null) {
      this.flc.contextRemove("off_desc");
    } else {
      this.flc.contextPut("off_desc", getTranslator().translate(i18nKey));
    }
  }

  /**
   * Set an optional description. This will appear above the form. If you use a
   * custom template this will have no effect
   *
   * @param i18nKey
   * @args args optional arguments
   */
  protected void setFormDescription(String i18nKey, String[] args) {
    if (i18nKey == null) {
      this.flc.contextRemove("off_desc");
    } else {
      this.flc.contextPut("off_desc", getTranslator().translate(i18nKey, args));
    }
  }

  /**
   * Set an optional context help link for this form. If you use a custom
   * template this will have no effect
   *
   * @param packageName The bundle name, e.g. org.olat.core
   * @param pageName The page name, e.g. my-helppage.html
   * @param hoverTextKey The hover text to indicate what this help is about
   *          (i18nkey)
   */
  protected void setFormContextHelp(String packageName, String pageName, String hoverTextKey) {
    if (packageName == null) {
      this.flc.contextRemove("off_chelp_package");
    } else {
      this.flc.contextPut("off_chelp_package", packageName);
      this.flc.contextPut("off_chelp_page", pageName);
      this.flc.contextPut("off_chelp_hover", hoverTextKey);
    }
  }
 
  /**
   * Set an optional css class to use for this form. May help to achieve custom formatting without
   * a separate velocity container.
   *
   * @param cssClassName the css class name to wrap around form
   */
  protected void setFormStyle(String cssClassName){
    if (cssClassName == null){
      this.flc.contextRemove("off_css_class");
    } else {
      this.flc.contextPut("off_css_class", cssClassName);
    }
  }
 
 
  protected void setTranslator(Translator translator) {
    super.setTranslator(translator);
    flc.setTranslator(translator);
  }

  /**
   * @param ureq
   * @return
   */
  protected boolean validateFormLogic(UserRequest ureq) {
    // TODO Auto-generated method stub
    return true;
  }

  /**
   * Adding disposing of form items that implement the disposable interface.
   * Some Form items might generate temporary data that needs to be cleaned
   * up.
   * <p>
   * First, super.dispose() is called.
   *
   * @see org.olat.core.gui.control.DefaultController#dispose()
   */
  @Override
  public void dispose() {
    super.dispose();
    ThreadLocalUserActivityLoggerInstaller.runWithUserActivityLogger(new Runnable() {
      public void run() {
        // Dispose also disposable form items (such as file uploads that needs to
        // cleanup temporary files)
        Map<String, FormItem> formItems = FormBasicController.this.flc.getFormComponents();
        for (FormItem formItem : formItems.values()) {
          if (formItem instanceof Disposable) {
            Disposable disposableFormItem = (Disposable) formItem;
            disposableFormItem.dispose();       
          }
        }
      }
    }, getUserActivityLogger());
  }
 

}
TOP

Related Classes of org.olat.core.gui.components.form.flexible.impl.FormBasicController

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.