Упаковка / декорирование GWT FileUpload - PullRequest
2 голосов
/ 02 февраля 2011

GWT FileUpload поставляется в виде виджета, который позволяет загружать файл во время отправки формы (по крайней мере, так, как я понимаю :)). Я хочу сделать его лучше и избавиться от стандартного. Кнопка «Обзор ...».

Поскольку у меня нет хорошего опыта работы с GWT (и нет JavaScript), я искал существующие решения и нашел довольно хороший проект - gwtupload . Это хорошо, но я понял, что хотел бы иметь свою собственную миниатюрную версию (а также мне было интересно, как она работает). Поэтому я просмотрел код и попытался извлечь волшебную часть. Я понял, что GWT FileInput используется, но он не показан, и нажатия кнопки делегируются этому FileInput. Код, который я пытался извлечь (только ту часть, которая делегирует щелчок) после просмотра источников gwtupload , содержит этот хитрый elem.click() JSNI:

class MyUpload extends Composite {
    private static native void clickOnInputFile(Element elem) /*-{
        elem.click();
    }-*/;

    public MyUpload() {
        final FileUpload upload = new FileUpload();
        AbsolutePanel container = new AbsolutePanel();
        // container.add(upload);
        Button btn = new Button("My Browse..");
        btn.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                clickOnInputFile(upload.getElement());
            }
        });
        container.add(btn);
        initWidget(container);
    }
}

Но, похоже, это не сработает: нажатие на «My Browse ..» не даст никакого эффекта (на тот случай, если я также попытался запустить безкомментированную строку container.add(upload)). Не могли бы вы помочь мне понять, что не так / отсутствует в этом примере кода?

Заранее спасибо.

P.S. Я знаю, что должен разместить его на FormPanel, а остальное я знаю о том, как выполнить фактическую отправку / обработку в Servlet; единственное, что я хочу сделать, - это украшение.

1 Ответ

9 голосов
/ 02 февраля 2011

Поскольку я не получил никаких ответов, мне нужно было больше изучить эту проблему, поэтому я провел более глубокий анализ кода проекта gwtupload , чтобы понять, как GWT FileUpload (который преобразуется в) может быть украшен.

Оказалось, что element.click() будет работать только в браузерах, которые поддерживают метод #click () (IE, Chrome, Safari). На самом деле, Мануэль Карраско Моньино, автор проекта, упоминает об этом в комментариях. Есть второй подход (для Firefox и Opera), который использует хак, когда FileInput помещается на прозрачную панель, которая, однако, размещается над какой-то украшенной кнопкой (с использованием абсолютного позиционирования); комментарий Мануэля:

Когда пользователь наводит указатель мыши на кнопку и нажимает на нее, на самом деле происходит то, что пользователь нажимает на прозрачный файл, отображающий диалоговое окно выбора файла.

После этого основная работа заключается в правильном применении атрибутов стиля к элементам.

Таким образом, существует две реализации пользовательского компонента загрузки файлов, и отложенное связывание GWT используется для их создания в зависимости от браузера.

Как, например, я упоминаю в своем вопросе, есть несколько исправлений (необходимо добавить «upload» в контейнер, и его можно установить в #setVisible (false)):

class MyUpload extends Composite {
    private static native void clickOnInputFile(Element elem) /*-{
        elem.click();
    }-*/;

    public MyUpload() {
        final FileUploadWithMouseEvents upload = new FileUploadWithMouseEvents();
        AbsolutePanel container = new AbsolutePanel();
        container.add(upload);
        upload.setVisible(false);
        Button btn = new Button("My Browse..");
        btn.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                clickOnInputFile(upload.getElement());
            }
        });
        container.add(btn);
        initWidget(container);
    }
}

Этот пример отлично работает в IE8.

P.S. Спасибо Мануэлю за его замечательную библиотеку:)

...