Integrating form page with Kuroco and Nuxt.js

In this tutorial, we will learn how to use forms for a Nuxt.js project that is implemented with Kuroco.

Note)
This tutorial assumes that a project has already been implemented with Kuroco and Nuxt.js. If that is not done yet, please refer to this tutorial.

What is a form in Kuroco?

A form in Kuroco is a function that allows the user to define data to support the creation of HTML forms, set automatic replies, and view form data sent by users.

Form settings can be managed / set from [Campaign] -> [Form] management screen.
Image (fetched from Gyazo)

Please refer to the following for more details: -Form list -Form basic settings -Form items settings

A form will not work in the initial state, various settings and coding on the front-end side will be required. In this exercise, we will go through the required steps to enable the form in Kuroco and Nuxt.js project.

Creating the form definition

First, create a form definition. From the Form List page, click [Create new inquiry form].
Image (fetched from Gyazo)

The create new inquiry form page will be displayed, please refer to Form basic settings for more detail. In this exercise, we will set the following fields:

Image (fetched from Gyazo)

ParameterValue
TitleTest form
ExplanationExplanation here.
Explanation here.
Explanation here.
Gratitude wordsGratitude words here.
Gratitude words here.
Gratitude words here.

Click [Add] at the bottom.
Image (fetched from Gyazo)

You will be redirected to the Form list page. The newly created form can be verified here.

Image (fetched from Gyazo)

Please take note that the displayed 'ID' is the form's unique identifier.

Note) The ID value is automatically generated, so the value varies depending on the environment. Although the ID value is 12 in the above example, please use the actual ID displayed on your screen.

This concludes the form definition creation.

Verifying the form settings

Next, verify the settings and data of the form created earlier.

Verifying the "Items settings"

From the form list screen, click the created [Test form].
Image (fetched from Gyazo)

On the basic form settings screen page, click the [Item Settings] tab. Image (fetched from Gyazo)

The Form items settings screen will be displayed.
Image (fetched from Gyazo)

This screen defines the items in the HTML form.

"name", "email" and "message" are preset because they are required items in Kuroco. To add an item, you will need to add the item definition yourself. There are blank items under [message], customized item(s) can be added there if required. Image (fetched from Gyazo)

In this exercise, we will create the form with only the default items, so leave the item settings as they are.

Verifying the "Answers"

Click the [Answers] tab to see a list of user-submitted answers for the form.
Image (fetched from Gyazo)

The list of submitted answers via HTML form will be shown here.
(Currently, the HTML form has not been created yet and no data has been submitted, hence the list is displaying records)
Details such as the contents of the answer can be verified from this screen or the [Report] tab adjacent to the right.

Creating an endpoint for the form

Next, create an endpoint for the created form definition and configure it so that the form function can be used from the front end.

Select the target API from [API] and click [Configure Endpoint] from the API management screen. Image (fetched from Gyazo)

Let's create an endpoint with the following settings.
Note) To keep it simple, specify None for authentication here. Image (fetched from Gyazo)

Item settingsSettings
Pathform
Enabled/DisabledEnabled
ModelCategoriesInquiries
ModelInquiryForm
Operationdetails
AuthorizationNone

Verify with Swagger UI

Verify if it is possible to get the form definition with SwaggerUI. From the API screen, click [Swagger UI]. Image (fetched from Gyazo)

The Swagger UI screen will be displayed. Click the endpoint that was created earlier. Image (fetched from Gyazo)

Click [Try it out] Image (fetched from Gyazo)

In the [inquiry_id] field, enter the ID of the form created earlier ('12' is entered here), and click [Execute]. Image (fetched from Gyazo)

The created form definition will be converted to JSON and result will be displayed.
Image (fetched from Gyazo)

This concludes the endpoint setup for the form.

Create an endpoint for sending data

Next, create an endpoint to submit data from HTML to the target form.

Select the target API from [API] and click [Configure Endpoint] from the API management screen. Image (fetched from Gyazo)

In this exercise, let's create an endpoint with the following settings.
Note) To keep it simple, specify None for authentication.
Image (fetched from Gyazo)

Item settingsSettings
Pathform
Enabled/DisabledEnabled
ModelCategoriesInquiries
ModelInquiryMessage
Operationsend
AuthorizationNone

Click [+Add] to create the endpoint. This concludes the setting for the endpoint for sending data.

So far, we have created two types of endpoints.

  • Endpoint to get form definition: '(GET) form'
  • Endpoint to submit form: '(POST) form'

Now, let's actually use these endpoints to create and submit forms from HTML.

Creating an HTML form with additional modifications to the front end

Create additional files with the following structure in the Nuxt installation directory.
In this exercise, create a form directory in the pages directory and create "index.vue" in the form directory.

pages
 - form
   - index.vue 

Include the following in the added file 'pages/form/index.vue'.

index.vue
<template>
  <div>
    <h1>Form page</h1>

    <form v-if="!submitted" ref="form">
      <div v-if="error" class="error">
        <p v-for="(err, idx) in error" :key="idx">
          {{ err }}
        </p>
      </div>

      <div class="row--status">
        <h2>Form name</h2>
        <div>{{ name }}</div>
      </div>

      <div class="row--status">
        <h2>Description</h2>
        <div>
          <p v-for="(line, idx) in textLines2texts(info)" :key="idx">
            {{ line }}
          </p>
        </div>
      </div>

      <div class="row--status">
        <h2>Thank you message</h2>
        <div>
          <p v-for="(line, idx) in textLines2texts(thanksText)" :key="idx">
            {{ line }}
          </p>
        </div>
      </div>

      <div class="row--status">
        <h2>Form parameters</h2>
        <div class="row--internal">
          <div v-for="col in cols" :key="col.key">
            <p>[{{ col.title }}]</p>
            <pre>{{ col }}</pre>
          </div>
        </div>
      </div>

      <div v-for="col in cols" :key="col.objKey" class="row--form">
        <h2>[{{ col.title }}]</h2>
        <input :name="col.objKey" type="text" />
      </div>

      <div class="row--bottom-next">
        <button @click="handleOnSubmit">submit</button>
      </div>
    </form>

    <form v-else>
      <div class="row--status">
        <h2>Inquiry ID</h2>
        <div>
          {{ submittedId }}
        </div>
      </div>

      <div class="row--status">
        <h2>Thank you message</h2>
        <div>
          <p v-for="(line, idx) in textLines2texts(thanksText)" :key="idx">
            {{ line }}
          </p>
        </div>
      </div>

      <div class="row--bottom-back">
        <button @click="handleOnBack">back</button>
      </div>
    </form>
  </div>
</template>

<script>
const FORM_ID = 12 // ID of the form

export default {
  async asyncData({ $axios }) {
    const response = await $axios.$get(
      process.env.BASE_URL + `/rcms-api/2/form/${FORM_ID}`
    )
    return {
      name: response.details.inquiry_name,
      info: response.details.inquiry_info,
      thanksText: response.details.thanks_text,
      cols: Object.entries(response.details.cols).map(([k, v]) => ({
        objKey: k,
        ...v,
      })),
    }
  },
  data: () => {
    return {
      submitted: false,
      submittedId: null,
      error: null,
    }
  },
  methods: {
    textLines2texts(textLines = '') {
      return textLines.split('\r\n')
    },
    async handleOnSubmit(e) {
      e.preventDefault()

      // collect input elements
      const formInputElements = Array.from(this.$refs.form.elements).filter(
        (elm) => elm.tagName.toLowerCase() === 'input'
      )

      // transform key:value inputs to an object
      const body = formInputElements
        .map((elm) => ({ [elm.name]: elm.value }))
        .reduce((prev, cur) => ({ ...prev, ...cur }), {})

      try {
        // post data
        const { id } = await this.$axios.$post(
          process.env.BASE_URL + `/rcms-api/2/form?id=${FORM_ID}`,
          body
        )
        this.error = null
        this.submittedId = id
        this.submitted = true
      } catch (e) {
        this.error = [`${e}`, ...e.response.data.errors]
      }
    },
    handleOnBack(e) {
      e.preventDefault()
      this.submitted = false
    },
  },
}
</script>

<style scoped>
input {
  width: 100%;
  border: none;
}

.error {
  color: red;
}
.error > *:first-child {
  font-weight: bold;
}

.row--status {
  display: flex;
  border-top: 1px solid black;
}
.row--status > *:first-child {
  background-color: yellow;
  min-width: 15rem;
  max-width: 15rem;
  border-right: 1px solid black;
}

.row--form {
  display: flex;
  border-top: 1px solid black;
}
.row--form > *:first-child {
  background-color: aquamarine;
  min-width: 15rem;
  max-width: 15rem;
  border-right: 1px solid black;
}

.row--bottom-next {
  padding: 8px 16px;
  display: flex;
  justify-content: flex-end;
}
.row--bottom-back {
  padding: 8px 16px;
  display: flex;
  justify-content: flex-start;
}

.row--internal {
  display: flex;
}

form > *:nth-last-child(2) {
  border-bottom: 1px solid black;
}
</style>

Note) For 'const FORM_ID = 10', enter the ID of the form definition that you have created.
Note) For /rcms-api/2/form/${FORM_ID} and /rcms-api/2/form?id=${FORM_ID}, please enter the path described on the Kuroco management screen.
Image (fetched from Gyazo)

Verifying with a browser

Next, we will verify the file created earlier in a browser. If your local server is down, run 'npm run dev' to access 'http://localhost:3000/form'. Then, the following screen will be displayed. Image (fetched from Gyazo)

In the table displayed below, the yellow row shows the data extracted from the retrieved form definition.

Data contentAccess method
Form name(response).details.inquiry_name
Description(response).details.inquiry_info
Thank you message(response).details.thanks_text
Form items(response).details.cols

As shown in "asyncData()" source code, you can confirm that the form definition can be retrieved according to the above correspondence table.

For form items, default items other than [Category] are returned in object format.

Reference)
For more detailed information, use the [Network] tab from the Chrome developer console to verify the network information to and sent from Kuroco.

Sending data

Next, we will send the data from the HTML form based on the retrieved data definition. The green row of the table displayed on the screen is the input item (HTML form). Enter the values for each item as shown below. Image (fetched from Gyazo)

Input nameValue
[name]Test name
[email]test@example.com
[message]Test message

After clicking the [submit] button, the data will be sent and you will be redirected to the next screen.

Image (fetched from Gyazo)

Based on the "handleOnSubmit" source code, this operation will send the [Form item] data to Kuroco.

Next, we will check the sent data using Kuroco. From the form list page, click the created [Test form]. Image (fetched from Gyazo)

Clicking the [Answers] tab will display the list of answers, we can verify that one data entry exists.

Image (fetched from Gyazo)

Details of the answer can be checked by clicking [No.] ('109' in this case).
Image (fetched from Gyazo)

Answer details include the value submitted from the HTML form.

Verifying form validation

Lastly, check the validation of the form.

Access the page that was created earlier again, enter an invalid email address in the [email] field, and confirm that an error is returned.

Enter the following in each green row of the table.
(The value of [email] is an invalid email address, to trigger an error)

Image (fetched from Gyazo)

Item nameValue
[name]Error validation name
[email]mail
[message]Error validation message

After clicking [submit], an error message will be displayed at the top of the screen.
Image (fetched from Gyazo)

As shown above, we can verify that Kuroco has server-side validation. When an error occured, the error content is returned in the response body together with HTTP status code. As seen in the source code, error handling will need to be implemented on the front-end.

Note)
For dynamic validation, custom implementation based on the value obtained from Kuroco will be required .

Adding a custom item

In addition to the default form items, custom item(s) can be freely defined/created. Let's review the steps required to create a custom field.

From the form list page, click on the created [Test Form].
Image (fetched from Gyazo)

Click the [Items Settings] tab to display the Form items settings screen. Image (fetched from Gyazo)

In this exercise, the following input items will be added.

Image (fetched from Gyazo)

Item nameValue
Titleitem
Required attributeOptional
Answer type/Input value limitationShort text(InputBox)
Input settings(Blank)

As shown in the table above, it is also possible to set the attributes for validation in [Required attribute] and [Input settings] to return the content of the input restriction based on the attribute of the form item.

Once the settings are done, click [Update] at the bottom of the screen. Image (fetched from Gyazo)

Access the page created earlier and confirm that the form definition obtained from Kuroco has been partially changed. You can see that [item] has been added to [Form items].
Image (fetched from Gyazo)

Now let's actually submit the form data and verify that the new [item] item is submitted to Kuroco. Enter the following in each green row of the front screen table:
Image (fetched from Gyazo)

Item nameValue
[item]Additional item
[name]Additional item name
[email]test@example.com
[message]Additional item message

Click [submit] to submit the data.

Click the [Answers] tab from the [Form] management screen to display a list of answers.
Verify that 1 more data entry has been added.
Image (fetched from Gyazo)

Clicking on [No.] (110 in this case) will display the details. We can verify the newly added item [item] and the value entered for that item are applied.
Image (fetched from Gyazo)

This concludes the explanation on how to create a form page.