简体   繁体   中英

GWT FileUpload form.submit() doesn't work after calling the button.click() programmatically

I'm writing a simple solution for uploading files in GWT and recently encountered a tiny, but quite annoying problem. I'm using a standard GWT FileUpload widget inside a FormPanel. Everything works just fine (form is submitted and the file is being sent to the servlet) only if user clicks "physically" a button related to form, with an attached click handler (inside there is this form.submit() fired).

Unfortunately, I have to submit a form from the other place in a FormPanel's parent widget (another class). I tried to implement click simulation with this particular code and a button with Visible attribute set to "false":

public void buttonClick() 
{
    NativeEvent event = Document.get().createClickEvent(0, 0, 0, 0, 0, false, false, false, false);
    DomEvent.fireNativeEvent(event, saveFileBtn);
}

saveFileBtn.addClickHandler(new ClickHandler()
{

    @Override
    public void onClick(ClickEvent event)
    {
        if(fileUpload.getFilename().isEmpty())
            return;
        else {
            form.submit();
        }           
    }
});

After calling the buttonClick() method the click event is fired, but the form doesn't submit (just nothing happens). Are there any differences between those two approaches to firing a click event?

If so, what would be the best alternative approach instead? I thought about making my own widget performing similar operations to the standard GWT FormPanel, but encode a file in a base64 format and send to server using the RequestBuilder mechanism. Does it make sense?

EDIT :

According to @Pedro Pedruzzi answer, I've implemented an event:

public interface FormToSubmitEventHandler extends EventHandler {
   void onFormToSubmit(FormToSubmitEvent event);
}

public class FormToSubmitEvent extends GwtEvent<FormToSubmitEventHandler> {

    public static final Type<FormToSubmitEventHandler> TYPE = new Type<FormToSubmitEventHandler>();

    public FormToSubmitEvent() {
        super();
    }

    @Override
    public Type<FormToSubmitEventHandler> getAssociatedType()
    {
        return TYPE;
    }

    @Override
    protected void dispatch(FormToSubmitEventHandler handler)
    {
        handler.onFormToSubmit(this);
    }

    public static HandlerRegistration register(EventBus eventBus, FormToSubmitEventHandler handler) 
    {
        return eventBus.addHandler(TYPE, handler);
    }  
}

In a widget class (implementing the interface above) added:

@Override
public void onFormToSubmit(FormToSubmitEvent event)
{
    if(fileUpload.getFilename().isEmpty())
        return;
    else {          
        form.submit();
    }   
}   

And then:

FormToSubmitEvent event = new FormToSubmitEvent();
Events.getTactinEventBus().fireEvent(event);

Unfortunately - it still doesn't work. I'm completely confused about what is going on.

EDIT 2

Whole class with registered handler:

public class FileLinkPropertyControl implements FormToSubmitEventHandler
{
    private FileUpload fileUpload;
    protected FormPanel form;;
    protected HorizontalPanel hPanel;   

    public FileLinkPropertyControl() {

    fileUpload = new FileUpload();

    FormToSubmitEvent.register(Events.getTactinEventBus(), this);

    fileUpload.setName("fileUploadFormElement");
    fileUpload.addChangeHandler(new ChangeHandler()
    {

        @Override
        public void onChange(ChangeEvent event)
        {
            setValue(fileUpload.getFilename(), true);                       
        }
    });

    form.setEncoding(FormPanel.ENCODING_MULTIPART);
    form.setMethod(FormPanel.METHOD_POST);
    form.setAction(GWT.getModuleBaseURL() + "fileUploadServlet");
    form.setWidget(hPanel);
    hPanel.add(fileUpload);
    }

    @Override
    public void onFormToSubmit(FormToSubmitEvent event)
    {
        if(fileUpload.getFilename().isEmpty())
            return;
        else {
            form.submit();
        }   
    }
}

Don't try to simulate the click or to make the request manually. You have to reach form.submit() some way. If the widget hierarchy is too complex to have a simple call chain aproach, you should use an event (see http://www.gwtproject.org/doc/latest/DevGuideUiHandlers.html ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM