FormSender with VaadinFlow

Hi all,

We have a requirement to send form data (the data itself is an xml) via a POST request, from a Vaadin flow webapp. This should redirect you to another application UI, with its form already prefilled with the sent data.

We have another Vaadin 8 application that does just this, using the extension FormSender (https://vaadin.com/directory/component/formsender-for-vaadin-8 ).

I don’t think there is an equivalent of this extension for Vaadin Flow (wishing I am wrong).

My question would be : is there any way of doing with Vaadin flow what FormSender does with Vaadin 8?

Any help much appreciated!

It seems to me there’s no such an addon for Vaadin Flow, but you can easily build the form on your own,
defining some component with in Java

@Tag("input")
public class Hidden extends HtmlComponent {
	private static final PropertyDescriptor<String, String> valueDescriptor = PropertyDescriptors
		.attributeWithDefault("value", "");

	public Hidden(String name, String value) {
		getElement().setAttribute("type", "hidden");
		getElement().setAttribute("name", name);
		setValue(value);
	}

	public void setValue(String value) {
		set(valueDescriptor, value);
	}

}

@Tag("form")
public class Form extends HtmlComponent implements HasComponents {

	private static final PropertyDescriptor<String, String> actionDescriptor = PropertyDescriptors
		.attributeWithDefault("action", "");
	private static final PropertyDescriptor<String, String> targetDescriptor = PropertyDescriptors
		.attributeWithDefault("target", "");
	private static final PropertyDescriptor<String, String> methodDescriptor = PropertyDescriptors
		.attributeWithDefault("method", "");

	public void setAction(String action) {
		set(actionDescriptor, action);
	}

	public void setMethod(String method) {
		set(methodDescriptor, method);
	}

	public void setTarget(String target) {
		set(targetDescriptor, target);
	}

	public void addValue(String name, String value) {
		add(new Hidden(name, value));
	}

	public void submit() {
		getElement().callJsFunction("submit");
	}

	/*
	public void submit() {
		getElement().executeJs("setTimeout(function(){$0.submit()},0)", getElement());
	}
	 */

}
@Route("testform")
public class TheForm extends Div {

    public TheForm() {
        add(new Button("SendForm", ev -> {
            Form form = createForm();
            add(form);
            form.submit();
        }));
    }

    private Form createForm() {
        Form form = new Form();
        form.setAction("/myform");
        form.setMethod("POST");
        form.setTarget("_blank");
        form.addValue("PARAM1", "value1");
        form.addValue("PARAM2", "abcds");
        return form;
    }

}

HTH
Marco

Awesome!! Tried it, working as expected.

Also, it really help me seeing the connection between Vaadin and Html when I see this example.

Big thanks!

Marco,

Thank you for this example it is very helpful.

I have a further question on this.

Is it possible to use the above method to send a JSON object as “Form Data” instead of a name value pair with Vaadin Flow?

So the content type gets set as application/json and the request body contains the JSON object.

Best Regards
John

Hi John,
I think this is not possible out of the box with html form.

There’s an enctype attribute but it seems it does not allow “application/json”.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-enctype

Maybe you can add some javascript to serialize form data and send it with an XmlHttpRequest.

HTH
Marco

Thanks, Marco.

Marco,

Do you know of any reason why the mechanism outlined above might not work on IE 11?
I don’t usually use IE11 but just tried it and it doesn’t work on IE 11 but works perfectly on Chrome, Safari and FF.
I have not investigated it much yet but just wanted to ask in case there is something fundamental preventing this mechanism from working with IE 11.

Thanks for any suggestions.

John.

Hi John,

I’m sorry but I have no idea why it doesn’t work in IE 11, and unfortunately I’m not able to test it.

Can you see any error message on the browser?

Marco,

There is no error at all anywhere. When I examine the DOM in the developer tools, the form element is added correctly and appears no different from the element in Chrome.

It just appeared that when I clicked my button to trigger the “Submit” it wasn’t doing anything on IE11.

So I discovered that if I replace the submit() method using the “callJsFuntion()” with the one that was commented out in the above example, using the “executeJs” function, it works on IE 11 !!

So …

public void submit() {
		getElement().callJsFunction("submit");
	}

	/*
	public void submit() {
		getElement().executeJs("setTimeout(function(){$0.submit()},0)", getElement());
	}
	 */

If I use the commented out submit - IE 11 works !! This also works for Chrome as well.

Do you know why that would be the case? I had a look on the vaadin page and both methods are described and appear to do the same thing.

Hi John,

I can only suppose that what makes it work on IE11 is that submit is scheduled by the setTimeout function

HTH

Marco