Forms with Fillform

This document describes how to implement forms in your app through the fillform api.

Setup#

note

First be sure to have setup correctly the following two variables in your .env file:

FILLFORM_API_URL=https://api.fillform.io/
FILLFORM_TOKEN=xyz123xyz123xyz123xyz123xyz123xy

Create a form#

Everytime you need a form start by creating a component with npx acanto component MyForm. It will act as a wrapper of the actual form, allowing scoped props, styles and scripts modifications. You will be able to use it wherever you like in your templates with <x-MyForm />.

Now you have two ways of implementing your form through fillform.

Standard implementation#

This implementation requires very little code and typically manages contact forms and newsletter subscriptions. To have a standard form submitted in ajax, with client side validation and feedback messages you will neeed:

  1. In your template /src/components/MyForm/index.blade.php:
<div class="MyForm:>
<x-fillform-feedback
:success="$trans['myform.success']"
:failure="$trans['myform.fail']"
/>
<x-fillform-base
:forms="[ 'en' => '195', 'it' => '196' ]"
/>
</div>

Note that here we pass to x-fillform-base a forms prop with an array of the localised version ids of the form we want. This array will be used internally to construct the $form data.

  1. In your javascript /src/components/MyForm/index.js:
import Fillform from "@acanto/core-fillform/feedback";
export default function FormContact() {
Fillform(".MyForm:");
}

Custom implementation#

There are scenarios in which you want to customize the form data coming from fillform.

note

Note that the data form fillform can come either directly or indirectly, as in the authentication forms where the data is "forwarded" from Fillform by the CMS to the Frontend.

To accomplish this you will need to use your form component class in /src/components/MyForm/index.php and build the $form data with the Fillform service (namespace LaravelFrontend\Forms\Fillform):

$form = Fillform::get(["en" => "206"]);
// or if there is just one language and/or you do not rely on fillform for translations:
$form = Fillform::get("206");
$this->form = $form;

the get method takes the same array of forms as you would pass to <x-fillform-base forms="..." /> and a second bool argument indicates if the form includes a newsletter subscription management (default false).

In your template /src/components/MyForm/index.blade.php you use the $form data as such:

<div class="MyForm:">
<x-fillform-base :form="$form"></x-fillform-form>
</div>

Note that here we pass to x-fillform-base a form prop with an already constructed $form data array.

note

The JavaScript side is not affected by this approach!

In your controller you can customize the $form data as you like, here some exmples of common use cases.

Prefilling values with data source#

In your component class in /src/components/MyForm/index.php:

<?php
namespace resources\components;
use Illuminate\View\Component;
use LaravelFrontend\Forms\Fillform;
class MyContact extends Component
{
public $form = [];
/**
* Create a new component instance.
*
* @return void
*/
public function __construct()
{
$myDataSource = [
"company" => "Acanto",
];
$form = Fillform::get(["en" => "206"]);
$form = Fillform::prefill($form, $myDataSource);
$this->form = $form;
}
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\View\View|string
*/
public function render()
{
return view("components.MyContact");
}
}

Populate select options with other source#

In your component class in /src/components/MyForm/index.php :

<?php
namespace resources\components;
use Illuminate\View\Component;
use LaravelFrontend\Forms\Fillform;
use LaravelFrontend\Cms\CmsApi;
class MyForm extends Component
{
public $form = [];
/**
* Create a new component instance.
*
* @return void
*/
public function __construct()
{
$form = Fillform::get([ 'en' => '195', 'it' => '196' ]);
$i = 0;
foreach ($form['fields'] as $field) {
if ($field['name'] === 'myname') {
$form['fields'][$i]['options'] = CmsApi::getData('myform/options/endpoint');
}
$i++;
}
$this->form = $form;
}
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\View\View|string
*/
public function render()
{
return view('components.MyForm');
}
}

Sending fillform to custom frontend endpoint#

src/components/MyForm/index.blade.php:

@php $form = Fillform::get([ 'en' => 192 ]); @endphp
<form class="MyForm:">
<x-fillform-fields :fields="$form['fields']"></x-fillform-fields>
</form>

src/components/MyForm/index.js:

import { globalConf } from "@acanto/core-data";
import FormsBase from "@acanto/core-forms/base";
export default function MyForm($root) {
FormsBase($root, ".MyForm:", {
endpoint: "my-custom-endpoint",
succeded: handleSucceded,
failed: handleFailed,
});
/**
* Handle succeeded
*
* @param {object} formData The data sent to the server
* @param {object} instance The form instance
* @param {object} response The server response
*/
function handleSucceded(formData, instance, response) {
console.log(response);
}
/**
* Handle failed
*
* @param {object} formData The data sent to the server
* @param {object} instance The form instance
* @param {object} response The server response
*/
function handleFailed(formData, instance, response) {
console.error(response);
}
}
// init
MyForm();

Sending fillform to custom CMS endpoint#

src/components/MyForm/index.blade.php:

@php $form = Fillform::get([ 'en' => 192 ]); @endphp
<form class="MyForm:">
<x-fillform-fields :fields="$form['fields']"></x-fillform-fields>
</form>

src/components/MyForm/index.js:

import { globalConf } from "@acanto/core-data";
import FormsBase from "@acanto/core-forms/base";
export default function MyForm($root) {
FormsBase($root, ".MyForm:", {
url: globalConf.cmsApiUrl + "/my-custom-endpoint",
succeded: handleSucceded,
failed: handleFailed,
});
/**
* Handle succeeded
*
* @param {object} formData The data sent to the server
* @param {object} instance The form instance
* @param {object} response The server response
*/
function handleSucceded(formData, instance, response) {
console.log(response);
}
/**
* Handle failed
*
* @param {object} formData The data sent to the server
* @param {object} instance The form instance
* @param {object} response The server response
*/
function handleFailed(formData, instance, response) {
console.error(response);
}
}
// init
MyForm();