Frontend UI Contact Form

Hi:

I am trying to figure out how to create a simple Contact form so the user can send an email to us. This is in the Anonymous section of our web site - there is no login. I think this means I can’t use a transient entity?

I want to embed the form on my home page - it’s just three simple fields: name, email and message with a “Send” button.

In plain old HTML, that would just have a mailto link on the submit button for the form and it would be done.

Do I need to use a transient entity and a service to send the email via Cuba email sender? I know how to do that with the Generic UI but I just can’t wrap my head around React.

Can anybody point me to an example I can follow?

Hi @eraskin,

You don’t need a transient entity as you can use serializable POJOs as arguments to service methods.

What you’ll need to do is:

  • Expose a service method with REST API
  • Sync up your frontend project model by running npm run update-model from the root of your frontend project. Your new method will appear in the restServices object located in <frontend-project-root>/src/cuba/services.ts.
  • In your form import restServices and call the corresponding method, providing form values as arguments.

Thanks. I created a simple service, ran npm run update-model, then tried to put the call into my form. I have based it on the PetClinic React test data generator example. I’m getting the following error:

TS2349: This expression is not callable.

I don’t know how to specify the arguments to the service call. See WHAT GOES HERE??? below:

Service interface:

public interface ContactEmailService {
    String NAME = "pasweb_ContactEmailService";

    public Boolean sendEmail(String name, String email, String message);
}

rest-services.xml:

<?xml version="1.0" encoding="UTF-8"?>
<services xmlns="http://schemas.haulmont.com/cuba/rest-services-v2.xsd">
    <service name="pasweb_ContactEmailService">
        <method name="sendEmail">
            <param name="name"/>
            <param name="email"/>
            <param name="message"/>
        </method>
    </service>
</services>

services.ts:

import { CubaApp, FetchOptions } from "@cuba-platform/rest";

export type pasweb_ContactEmailService_sendEmail_params = {
  name: any;
  email: any;
  message: any;
};

export var restServices = {
  pasweb_ContactEmailService: {
    sendEmail: (cubaApp: CubaApp, fetchOpts?: FetchOptions) => (
      params: pasweb_ContactEmailService_sendEmail_params
    ) => {
      return cubaApp.invokeService(
        "pasweb_ContactEmailService",
        "sendEmail",
        params,
        fetchOpts
      );
    }
  }
};

ContactForm.tsx:

import {restServices, pasweb_ContactEmailService_sendEmail_params} from "../../cuba/services";
.
.
.
  handleSubmit = (e: any) => {
    e.preventDefault();
    this.props.form.validateFieldsAndScroll((err, values) => {
      if (!err) {

        restServices.pasweb_ContactEmailService(cubaREST)( WHAT GOES HERE??? )
          .then((result:Boolean) => {
             if (result) {
               //TODO: notify sent
             } else {
               //TODO: notify send failed
             }
          });
      }
    });
  };

Well, I think I got it. Is this correct?

  handleSubmit = (e: any) => {
    e.preventDefault();
    this.props.form.validateFieldsAndScroll((err, values) => {
      if (!err) {
        restServices.pasweb_ContactEmailService.sendEmail(cubaREST)( { name: values.name, email: values.email, message: values.message } )
          .then((result:Boolean) => {
             if (result) {
               //TODO: notify sent
             } else {
               //TODO: notify send failed
             }
          });
      }
    });
  };

It now works! The final piece of the puzzle was a change to rest-services.xml:

<?xml version="1.0" encoding="UTF-8"?>
<services xmlns="http://schemas.haulmont.com/cuba/rest-services-v2.xsd">
    <service name="pasweb_ContactEmailService">
        <method name="sendEmail" anonymousAllowed="true">
            <param name="name"/>
            <param name="email"/>
            <param name="message"/>
        </method>
    </service>
</services>

Since the contact form is accessible to anyone, I needed to add anonymousAllowed=“true” to the method.

Thanks for your help.

You are welcome!