包装/装饰 GWT FileUpload

发布于 2024-10-15 07:41:20 字数 1350 浏览 9 评论 0原文

GWT FileUpload 作为一个小部件来生成,以便人们可以在表单提交期间上传文件(至少这是我的理解:))我想做的是使其看起来更好并摆脱标准的“Browse.txt”。 ..“ 按钮。

由于我没有良好的 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);
    }
}

但这似乎不起作用:单击“我的浏览..”不会产生任何效果(以防万一我也尝试使用未注释的 container.add(upload) 行)。您能帮助我理解此代码示例中的错误/缺失吗?

先感谢您。

PS 我知道我必须将它放在 FormPanel 上,并且我知道其余的如何在 Servlet 中执行实际的提交/处理;我唯一想做的就是这样的装饰。

GWT FileUpload comes as a widget that produces so that one can upload a file during form submit (at least it's how I understand it :) ) What I want to do is to make it a better-looking and get rid of standard "Browse..." button.

Since I don't have good GWT experience (and no JavaScript), I looked for existing solutions and found quite a good project - gwtupload. It's good, but I realized I'd love to have my own miniature version (and also, I was curious about how it works). So I browsed through code and tried to extract the magic part. I realized that GWT FileInput is used, but it's not shown, and Button clicks are delegated to this FileInput. The code I tried to extract (only the part that delegates the click) after reviewing sources of gwtupload contains this tricky 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);
    }
}

But this seems not to work: clicking on 'My Browse..' results in no effect (just in case I also tried running with un-commented container.add(upload) line) . Could you please help me in understanding what's wrong/missing in this code sample?

Thank you in advance.

P.S. I know that I have to place it on the FormPanel, and I know the rest about how to perform the actual submit/handling in Servlet; the only thing I want to do is this kind of decoration.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

金兰素衣 2024-10-22 07:41:20

由于我没有收到任何答案,因此我必须对这个问题进行更多调查,因此我对 gwtupload 项目,以了解如何装饰 GWT FileUpload(转换为 )。

事实证明, element.click() 仅适用于支持 #click() 方法的浏览器(IE、Chrome、Safari)。事实上,项目作者 Manuel Carrasco Moñino 在评论中提到了这一点。还有第二种方法(对于 Firefox 和 Opera),当 FileInput 放置在透明面板上时使用 hack,但是将其放置在一些装饰按钮上(使用绝对定位);曼努埃尔评论:

当用户将鼠标放在按钮上并单击它时,真正发生的是用户单击显示选择文件对话框的透明文件输入。

之后的主要工作就是正确地将样式属性应用到元素上。

因此,自定义文件上传组件有两种实现,并且根据浏览器使用GWT延迟绑定来实例化它们。

例如,我在问题中提到,有一些修复(必须将“上传”添加到容器中,并且可以将其设置为 #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 中运行良好。

PS 感谢曼努埃尔提供的伟大的图书馆:)

Since I have not received any answers, I had to have more investigation of this issue, so I performed a deeper code analysis of gwtupload project in order to understand how GWT FileUpload (which gets transformed into ) can be decorated.

It turned out that element.click() will only work in browsers which support #click() method (IE, Chrome, Safari). Actually, Manuel Carrasco Moñino - project author - mentions it within comments. There's second approach (for Firefox & Opera) that uses hack when FileInput is placed on transparent panel, which however is placed over some decorated button (using absolute positioning); comment by Manuel:

When the user puts his mouse over the button and clicks on it, what really happens is that the user clicks on the transparent file input showing the choose file dialog.

After that, the main work is correctly applying style attributes to elements.

Thus, there are two implementations of custom file upload component, and GWT deferred binding is used to instantiate them depending on Browser.

As for example I mention in my question, there're few fixes ("upload" has to be added to to the container, and it can be set to #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);
    }
}

This example works fine in IE8.

P.S. Thanks to Manuel for his great library :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文