Simple form templates in PHP

A collection of simple HTML form templates.

View source code on Github

A collection of form templates for PHP with full support for alpinejs properties.

<div>
  <?= $form->label('Name')->asRequired() ?>
  <?= $form->input('name')->asModel() ?>
</div>
<div>
  <?= $form->label('Description')->asRequired() ?>
  <?= $form->input('detail')->asModel() ?>
</div>
<div>
  <?= $form->button('Update')->onClick('update(id)') ?>
</div>

Installation

Install the package using Composer:

$ composer require rougin/fortem

Basic usage

[!NOTE] All elements below use Bootstrap classes by default. Use the noStyling method to opt out, or see Restyling elements to apply a custom CSS framework.

The FormHelper class provides an interface for creating labels, inputs, buttons, select dropdowns, and error messages:

// index.php

use Rougin\Fortem\Helpers\FormHelper;

$form = new FormHelper;

echo $form->label('Name');
<label class="form-label">Name</label>

[!NOTE] See the next sections for the documentation of the abovementioned elements.

The LinkHelper class helps in generating and checking URLs to the template:

use Rougin\Fortem\Helpers\LinkHelper;

$server = array();
$server['HTTP_HOST'] = 'localhost';
$server['REQUEST_URI'] = '/';

$link = new LinkHelper($server);

echo $link; // http://localhost/

Use the isActive method to check if a given link is the current URL:

$current = $link->isActive('/'); // true

If HTTP_HOST is not available, the setBase method can be used:

use Rougin\Fortem\Helpers\LinkHelper;

$data = /** instaceof $_SERVER */;

$link = new LinkHelper($data);

$link->setBase('roug.in')

echo $link; // http://roug.in/

Labels

To create a <label> element, the label method is used:

echo $form->label('Name');
<label class="form-label">Name</label>

Additional CSS classes can be appended using withClass:

echo $form->label('Name')->withClass('text-uppercase');
<label class="form-label text-uppercase">Name</label>

To remove the default styling, use the noStyling method:

echo $form->label('Name')->noStyling();
<label>Name</label>

A label can also be marked as required, which adds a red asterisk:

echo $form->label('Name')->asRequired();
<label class="form-label">Name <span class="text-danger">*</span></label>

Inputs

To create an <input> element, the input method is used. By default, it creates a text input:

echo $form->input('name');
<input type="text" name="name" class="form-control">

Additional CSS classes can be appended using withClass:

echo $form->input('name')->withClass('is-invalid');
<input type="text" name="name" class="form-control is-invalid">

The input type can be changed using the withType method or the convenient asEmail and asNumber methods:

echo $form->input('email')->asEmail();
<input type="email" name="email" class="form-control">
echo $form->input('age')->asNumber();
<input type="number" name="age" class="form-control">

Buttons

To create a <button> element, the button method is used:

echo $form->button('Submit');
<button type="button" class="btn">Submit</button>

Additional CSS classes can be appended using withClass:

echo $form->button('Submit')->withClass('btn-primary');
<button type="button" class="btn btn-primary">Submit</button>

The button type can be changed using the withType method:

echo $form->button('Submit')->withType('submit');
<button type="submit" class="btn">Submit</button>

Select dropdowns

To create a <select> element, the select method is used:

$items = array('Male', 'Female');

echo $form->select('gender', $items);
<select name="gender" class="form-select">
  <option value="">Please select</option>
  <option value="0">Male</option>
  <option value="1">Female</option>
</select>

An associative array with id and name keys can also be provided:

$items = [ array('id' => 'm', 'name' => 'Male') ];
$items[] = array('id' => 'f', 'name' => 'Female');

echo $form->select('gender', $items);
<select name="gender">
  <option value="">Please select</option>
  <option value="m">Male</option>
  <option value="f">Female</option>
</select>

Error messages

The error method is used to create a placeholder for validation error messages:

echo $form->error('error.name');
<template x-if="error.name">
  <p class="text-danger small mb-0" x-text="error.name[0]"></p>
</template>

[!NOTE] This is only works when integrated in alpinejs.

Using alpinejs

Fortem provides methods for seamless integration with alpinejs.

For Input and Select classes, the asModel method adds an x-model attribute to the element, binding its value to its variable:

echo $form->input('name')->asModel();
<input type="text" name="name" x-model="name">
echo $form->select('gender', $items)->asModel();
<select name="gender" x-model="gender">...</select>

In all elements, the disablesOn method adds the :disabled attribute, allowing an element to be disabled based on its condition:

echo $form->input('name')->disablesOn('loading');
<input type="text" name="name" :disabled="loading">

For the Button class, the onClick method adds the @click attribute to a button, executing its function on click:

echo $form->button('Submit')->onClick('submitForm');
<button type="button" @click="submitForm">Submit</button>

Scripts

The script method helps create a JavaScript object from PHP which is useful for initializing data for alpinejs:

echo $form->script('data')
  ->with('name', 'John Doe')
  ->with('age', 30)
  ->withLoading()
  ->withError();
<script>
  let data = {"name":"John Doe","age":30,"loading":false,"error":{}};
</script>

Restyling elements

The default styling uses Bootstrap 5 classes. To use a different CSS framework, implement the StyleInterface and pass it to the form helper:

namespace Rougin\Test\Styles;

use Rougin\Fortem\StyleInterface;

class TailwindStyle implements StyleInterface
{
    public function button()
    {
        return 'rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500';
    }

    public function error()
    {
        return 'mt-1 text-sm text-red-600';
    }

    public function input()
    {
        return 'block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 sm:text-sm';
    }

    public function label()
    {
        return 'block text-sm font-medium leading-6 text-gray-900';
    }

    public function required()
    {
        return 'text-red-500';
    }

    public function select()
    {
        return 'block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 sm:text-sm';
    }
}
use Rougin\Fortem\Helpers\FormHelper;
use Rougin\Test\Styles\TailwindStyle;

$form = new FormHelper;

// Apply the custom style to all elements ---
$form->useStyling(new TailwindStyle);
// ------------------------------------------

// All elements now use the custom style ---
$form->label('Name')->asRequired();
$form->input('name');
$form->button('Submit')->withClass('btn-primary');
$form->select('gender', array('Male', 'Female'));
$form->error('error.name');
// -----------------------------------------

// Opt out the default styling per element ---
$form->input('name')->noStyling();
// -------------------------------------------