суббота, 10 мая 2014 г.

28й - практикум. Filter column table on Range (between) of dates

Для таблиц есть встроенный фильтр на основе QBE, но он мало пригоден в случае если поле типа дата да еще со временем. В этом случае нужен фильтр по диапазону дат, оператор Between .
 Пример на Oracle XE схема  HR

И так возьмем таблицу, стандартный фильтр, и для поля даты (HireDate) в области facet-filter разместим два поля даты, и кнопку "applyFilter". Эта часть не принципиальна и может быть реализована по разному.



Сделаем бин для страницы и в нем выполним все операции по фильтрации. Поля фильтра для дат устанавливают свои значения в "requestScope.HireDate1 и requestScope.HireDate2".

 Основной метод в бине
/**
   * Применить фильтр для даты
   * @param actionEvent
   */
  public void applyFilter(ActionEvent actionEvent)
  {
    FilterableQueryDescriptor queryDescriptor = (FilterableQueryDescriptor) getTable().getFilterModel();
    ConjunctionCriterion cc = queryDescriptor.getConjunctionCriterion();
    List<Criterion> cl = cc.getCriterionList();
    // получить критерий для атрибута
    AttributeCriterion ac = getAttrCriterionByName(cl, "HireDate");
    // получить оператор сравнения для атрибута
    AttributeDescriptor.Operator op = getOperatorByName(ac, "BETWEEN");
    // дата с: 
    Date hd1 = (Date) JSFUtils.getRequestAttribute("HireDate1");
    // дата по:
    Date hd2 = (Date) JSFUtils.getRequestAttribute("HireDate2");
    ac.setOperator(op);
    List list = ac.getValues();     
    list.set(0, new Timestamp(hd1.getTime()));
    list.set(1, new Timestamp(hd2.getTime()));
    // послать событие фильтра 
    getTable().queueEvent(new QueryEvent(getTable(), queryDescriptor));
    // обновить таблицу
    AdfFacesContext.getCurrentInstance().addPartialTarget(getTable());
  }

Вспомогательные методы

/**
   * Получить критерий для атрибута 
   * @param cl
   * @param name
   * @return
   */
  private AttributeCriterion getAttrCriterionByName(List<Criterion> cl, String name)
  {
    AttributeCriterion result = null;
    for (Criterion ac: cl)
    {
      if (name.equals(((AttributeCriterion)ac).getAttribute().getName()))
      {
        result = (AttributeCriterion) ac;
        break;
      }
    }
    return result;
  }
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  /**
   * Получить оператор сравнения по имени
   * @param ac
   * @param name
   * @return
   */
  private AttributeDescriptor.Operator getOperatorByName(AttributeCriterion ac, String name)
  {
    AttributeDescriptor.Operator result = null;
    Set<AttributeDescriptor.Operator> operators = ac.getAttribute().getSupportedOperators();
    for (AttributeDescriptor.Operator o: operators)
    {
      if (name.equals(o.getValue()))
      {
        result = o;
        break;
      }      
    }
    return result;
  }

Основная мысль такая, получаем у таблицы FilterableQueryDescripto, далее для атрибута получаем  AttributeCriterion, а затем из доступных операторов для атрибута получаем нужный (BETWEEN) оператор, но умолчанию для поля даты идет оператор "=", отсюда и проблемы с фильтром  в QBE, затем подменяем стандартный на - BETWEEN, и присваиваем ему две даты (с:, по:)

Внешний вид страницы
  

Источники
Apply Filter on af:table column programmatically ,Invoke 'FilterableQueryDescriptor' through managed bean

Исходник





1 комментарий: