воскресенье, 1 декабря 2013 г.

24й - практикум. Dynamic Declarative Forms Builder

Dynamic Declarative Forms Builder (DDFB) - это динамическое построение формы ввода данных на основе описания (метаданных), используя декларативный подход.

 Т.е. откуда то из вне (XML, База данных, и др.) имеем описание формы/интерфейса, далее по этому описанию строим форму, ввод сохраняется в универсальном мапинге, который был рассмотрен ранее в п 23  





Начну с момента в котором уже имеется описание интерфейса и далее. Декларативный построитель  формы основан на комбинации forEach  и switcher.   forEach получает на вход коллекцию и проходя по ней switcher определяет тип данных (тип компоненты) и рисует соответствующий бок (facet). Facet -ы в switcher заранее настроены под соответствующий тип данных. В своем примере я показал четыре типа facet, тип Number, String, Date, LOV (список).
Вот как они выглядят
 Настроенный facet могут быть самыми разными, иметь уже пред настроенные блоки, оформление и пр.

Реализация в java
Имеется интерфейс который должен имплементировать базовый класс. Базовый класс реализует базовые типы данных String, Number, Date.

public interface BaseComponent
{
  public String getDataType();
  public Object getValue();
  public String getName();
  public String getLabel();
  public List<LovItem> getLovs();  
}

 Базовый класс
public class BaseComponentImpl implements BaseComponent
{
  
  // Тип данных
  private String dataType;
  // Значение
  private Object value;
  // Имя
  private String name;
  // Название
  private String label;

  public BaseComponentImpl(String dataType, Object value, String name, String label)
  {
    super();
    this.dataType = dataType;
    this.value = value;
    this.name = name;
    this.label = label;
  }

  public String getDataType()
  {
    return dataType;
  }
  . . . . 

Для получения других сложных типов, добавляем в интерфейс BaseComponent нужные методы и расширяем базовый класс BaseComponentImpl


Пример для получения списка LOV

public class LovComponentImpl extends BaseComponentImpl
{
  
  public LovComponentImpl(List<LovItem> lovs, String dataType, Object value, String name, String label)
  {
    super(dataType,  value,  name,  label);
    this.lovs = lovs;
  }
  
  private List<LovItem> lovs;
  
  @Override
  public List<LovItem> getLovs()
  {
   return lovs;  
  }


Обработка в DDFB

        <af:forEach items="#{pageFlowScope.pageBean.items}" var="var">
          <af:switcher id="s1" facetName="#{var.dataType}">
            <f:facet name="NUMBER">
              <af:inputText label="#{var.label}" id="it1" value="#{pageFlowScope.uiMappingBean.map[var.name]}"
                            columns="15">
                <af:convertNumber/>
              </af:inputText>
            </f:facet>
            <f:facet name="STRING">
              <af:inputText label="#{var.label}" id="it2" value="#{pageFlowScope.uiMappingBean.map[var.name]}"/>
            </f:facet>
            <f:facet name="DATE">
              <af:inputDate label="#{var.label}" id="id1" value="#{pageFlowScope.uiMappingBean.map[var.name]}"/>
            </f:facet>
            <f:facet name="LOV">
              <af:selectOneChoice label="#{var.label}" id="soc1" value="#{pageFlowScope.uiMappingBean.map[var.name]}">
                <af:forEach items="#{var.lovs}" var="lv">
                  <af:selectItem label="#{lv.label}" id="si1" value="#{lv.value}"/>
                </af:forEach>
              </af:selectOneChoice>
            </f:facet> 
          </af:switcher>
        </af:forEach>

 Подготовка данных

public class PageBean
{
  public PageBean()
  {
    super();
    // Edit 
    items.add(new BaseComponentImpl("STRING", null, "Name", "Имя"));
    items.add(new BaseComponentImpl("STRING", null, "LastName", "Фамилия"));
    items.add(new BaseComponentImpl("NUMBER", null, "Age", "Возраст"));
    items.add(new BaseComponentImpl("DATE", null, "BirthDay", "День рождения"));    
    // LOV    
    List<LovItem> lovs = new ArrayList<LovItem>();
    lovs.add(new LovItem("Январь", 1 ));
    lovs.add(new LovItem("Февраль", 2 ));
    lovs.add(new LovItem("Март", 3 ));
    lovs.add(new LovItem("Апрель", 4 ));
    lovs.add(new LovItem("Март", 5 ));
    items.add(new LovComponentImpl(lovs, "LOV", null, "Month", "Месяц"));    
  }
    
  List<BaseComponent> items = new ArrayList<BaseComponent>();
  
  public List<BaseComponent> getItems()
  {
    return items;
  }

Mapping полей ввода на been выполнен как в п 23
 
Вот так достаточно просто можно получать достаточно сложные формы на лету.

Форма



   




 Исходник


Комментариев нет:

Отправить комментарий