SmartGWT с привязкой к данным ListGrid -> DateItem в заголовке столбца, перезагрузить столбец onChanged

Моя задача: ListGrid с привязкой к данным со столбцом. Заголовок этого столбца должен быть «Информация для {infoDate в формате ДД-ММ-ГГГГ}» + DateItem (только средство выбора значков), из которого пользователи могут изменять infoDate, который по умолчанию является текущей датой. Значения в столбце меняются в зависимости от выбранной даты.

Итак, я взял идею из этого вопроса Как добавить кнопку в HeaderSpan из SmartGWT, чтобы перейти к приведенному ниже коду. К сожалению, есть проблема: DateItem не выглядит интерактивным, он выглядит как изображение. Кроме того, я не могу удалить TextField, это либо текстовое поле, либо 3 выбираемых поля параметров.

Я предполагаю, что использование innerHTML не берет на себя функцию самого средства выбора, как я пробовал с Calendar, DateChooser и DatePicker, и это сработало, но проблема заключалась в представлении (мне нужен только значок календаря, который откроет DatePicker onClick ).

Заранее спасибо за любую помощь или идею!

Импорт:

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Node;
import com.google.gwt.dom.client.NodeList;
import com.smartgwt.client.widgets.events.DrawEvent;
import com.smartgwt.client.widgets.events.DrawHandler;
import com.smartgwt.client.widgets.grid.ListGrid;

Код:

ListGrid infoTable = new ListGrid();
infoTable.setShowRecordComponents(true);
infoTable.setShowRecordComponentsByCell(true);        
infoTable.setWidth100();
infoTable.setDataSource(dataSource);
infoTable.setCanEdit(false);
infoTable.setCanCollapseGroup(false);
infoTable.setCanFreezeFields(false);
infoTable.setCanGroupBy(false);
infoTable.setCanMultiSort(false);
infoTable.setCanSort(false);
infoTable.setCanResizeFields(false);
infoTable.setAutoFetchData(false);
infoTable.addDrawHandler(new DrawHandler() { 
    public void onDraw(final DrawEvent event) { 
        for (Element element : DOMUtils.getElementsByTagName("td")) { 

            if (element.getInnerHTML().startsWith("Information for")) { 
                DOMUtils.removeAllChildNodes(element); 

                final DynamicForm cal = new DynamicForm(); 

                final DateItem infoDate = new DateItem(); 
                infoDate.setDefaultValue(new Date());
                infoDate.setTitle(“Information for ”); 
                infoDate.setTitleAlign(Alignment.LEFT); 
                infoDate.setWrapTitle(false); 
                infoDate.setDisplayFormat(DateDisplayFormat.TOEUROPEANSHORTDATE); 
                infoDate.setUseTextField(true); 
                infoDate.setAlign(Alignment.RIGHT); 
                infoDate.addChangedHandler(new ChangedHandler() { 
                    public void onChanged(final ChangedEvent event) { 
                        //fetch new data, according to the date selected); 
                    } 
                }); 

                cal.setFields(infoDate); 

                element.setInnerHTML(cal.getInnerHTML()); 

            } 
        } 

        // fetch data from DataSource class
        infoTable.fetchData(); 
    } 
});

И класс DOMUtils:

class DOMUtils {
public static void removeAllChildNodes(Element element) {
    NodeList<Node> childList = element.getChildNodes();
    for(int childIndex = 0; childIndex < childList.getLength(); childIndex++) {
        element.removeChild(childList.getItem(childIndex));
    }
}

public static Element[] getElementsByTagName(String tagName)
{
    JavaScriptObject elements = getElementsByTagNameInternal(tagName);
    int length = getArrayLength(elements);
    Element[] result = new Element[length];
    for (int i=0; i<length; i++)
    {
        result[i] = getArrayElement(elements, i);
    }
    return result;
}

private static native JavaScriptObject getElementsByTagNameInternal(String tagName)/*-{
return $doc.getElementsByTagName(tagName);
  }-*/;

private static native int getArrayLength(JavaScriptObject array)/*-{
return array.length;
  }-*/;

private static native Element getArrayElement(JavaScriptObject array, int position)/*-{
return (position>=0 && position<array.length?array[position]:null);
  }-*/;
}

person Bubolina    schedule 24.08.2012    source источник


Ответы (2)


Вау, не надо ничего из этого. Вы можете использовать setShowFilterEditor(true), и интерфейс по умолчанию для поля типа «дата» будет выглядеть так, как вы хотите, за исключением того, что средство выбора, запускаемое из значка календаря, позволит пользователю ввести диапазон дат, что кажется более функциональным. чем то, что вы хотите.

Если вы не хотите поддерживать произвольные диапазоны дат, используйте setFilterEditorType(), чтобы заменить элемент управления по умолчанию своим собственным, более ограниченным элементом управления.

Если вам не нужны две строки заголовков (обычные заголовки плюс filterEditor), просто используйте setShowHeader(false).

person Bill Ellwood    schedule 24.08.2012
comment
Привет Билл, спасибо за ваш ответ. Дело в том, что только заголовок должен отображать дату, столбец содержит все виды данных (int, String, double и т. д.). Когда дата выбрана, я делаю перерасчеты по этой дате и перерисовываю столбец с новыми данными. - person Bubolina; 27.08.2012
comment
В этом случае ваш пользовательский FormItem действительно не имеет ничего общего с заголовком сетки или FilterEditor, и нет причин пытаться втиснуть его в эти компоненты. Вместо этого вы можете просто поместить его над ListGrid или, в версии 3.1, вы можете добавить его в макет ListGrid (см. ListGrid.gridComponents). - person Bill Ellwood; 28.08.2012
comment
Я использую 3.0 и да, я могу добавить его в форме над сеткой, но проблема в том, что клиент хочет это в шапку... :( Я могу сказать, что это невозможно, но я должен быть уверен, что это не. Вы действительно думаете, что нет никакого способа сделать это так? Еще раз спасибо за вашу помощь. - person Bubolina; 28.08.2012

Итак, я нашел способ сделать это: поскольку я не могу переопределить сам заголовок, я использую HeaderSpan с высотой заголовка, чтобы был виден только заголовок HeaderSpan. Однако ВНИМАНИЕ, на FF работает нормально, но вызывает ошибки в других частях приложения в IE. Вот код; класс DOMUtils можно найти в моем 1-м посте:

// class MyDataSource extends com.smartgwt.client.data.DataSource
MyDataSource dataSource = MyDataSource.getInstance(); 

final HeaderSpan headerSpanCol1 = new HeaderSpan(); 
headerSpanCol1.setTitle("column 1"); 
headerSpanCol1.setFields(MyDataSource.A); 
headerSpanCol1.setHeight(26); 

final HeaderSpan headerSpanCol2 = new HeaderSpan();
// make sure not to have the same element name
headerSpanCol2.setTitle(“Information for”); 
headerSpanCol2.setFields(MyDataSource.D); 
headerSpanCol2.setHeight(26); 

final HeaderSpan headerSpanCol3 = new HeaderSpan(); 
headerSpanCol3.setTitle("column 2"); 
headerSpanCol3.setFields(MyDataSource.B); 
headerSpanCol3.setHeight(26); 

infoTable = new ListGrid() { 

  @Override 
  protected Canvas createRecordComponent(final ListGridRecord record, final Integer colNum) { 

      final String fieldName = this.getFieldName(colNum); 

    // include some icons that I need in the ListGrid here

  } 
}; 
infoTable.setShowRecordComponents(true); 
infoTable.setShowRecordComponentsByCell(true); 

infoTable.setWidth100();
// make height equal to HeaderSpan’s in order to hide header titles and show only the HeaderSpan
infoTable.setHeaderHeight(26);
infoTable.setDataSource(dataSource); 
infoTable.setCanEdit(false); 
infoTable.setCanCollapseGroup(false); 
infoTable.setCanFreezeFields(false); 
infoTable.setCanGroupBy(false); 
infoTable.setCanMultiSort(false); 
infoTable.setCanSort(false); 
infoTable.setCanAutoFitFields(false); 
infoTable.setCanResizeFields(false); 
infoTable.setCanPickFields(false); 
infoTable.setAutoFetchData(false); 
infoTable.addDrawHandler(new DrawHandler() { 
public void onDraw(final DrawEvent event) { 

   for (Element element : DOMUtils.getElementsByTagName("td")) { 
       // iterate over the elements of the page to find the HeaderSpan to replace

       if (element.getInnerHTML().equals(“Information for”)) { 
          // replace the title of this HeaderSpan with a DateItem 
          DOMUtils.removeAllChildNodes(element); 

          final DynamicForm cal = new DynamicForm(); 

         final DateItem infoDate = new DateItem(); 
         infoDate.setDefaultValue(new Date()); 
         infoDate.setTitle(“Select date”); 
         infoDate.setWrapTitle(false); 
         infoDate.setDisplayFormat(DateDisplayFormat.TOEUROPEANSHORTDATE); 
         infoDate.setUseTextField(true); 
         infoDate.setAlign(Alignment.RIGHT); 
         infoDate.addChangedHandler(new ChangedHandler() { 
             public void onChanged(final ChangedEvent event) { 
                 // reload table with newly fetched results                       
             } 
         }); // ChangedHandler

         cal.setFields(infoDate);
         element.insertFirst(cal.getElement());

 break;
} // if
    } // for


    // fetch data from DataSource class
  infoTable.fetchData(); 
} // onDraw
}); // DrawHandler

infoTable.setHeaderSpans(headerSpanCol1, headerSpanCol2, headerSpanCol3); 
person Bubolina    schedule 31.08.2012