Flick
Guide Validation Services API Pro Examples GitHub
Docs / Getting Started

Creating Forms

Creating forms with Flick is about as easy as it gets, and there are multiple ways in which you can do it. Let's take a look at each.

  1. The Quickest Way
  2. Using Strings
  3. Using Arrays
  4. Using Form Files
  5. Using Field Elements
  6. Using Raw HTML
  7. Creating Multistep Forms

The Quickest Way: createAndValidate

Tip

createAndValidate() is the fastest way to create a production-ready form. One line of code handles form creation, validation, success/error messages, and form hiding on success.

$form->createAndValidate('Name[required], Email[email, required]');

That's it! This single line:

  • Displays the form on initial page load
  • Validates the submission when the form is posted
  • Shows a success message when validation passes
  • Shows an error message when validation fails
  • Hides the form after successful submission

Processing the Data

Check the result and process the data:

$data = $form->createAndValidate('Name, Email');

if ($data && $form->ok()) {
    $form->sql->save('users', [
        'name' => $data['name'],
        'email' => $data['email'],
    ]);
}

Or use a callback for a more compact approach:

$form->createAndValidate('Name, Email',
    onSuccess: fn($data) => $form->sql->save('users', [
        'name' => $data['name'],
        'email' => $data['email'],
    ])
);

Custom Messages

Override the default messages:

$form->createAndValidate(
    'Name[required], Email[email]',
    successMessage: 'Thanks for signing up!',
    errorMessage: 'Oops! Please check your input.'
);

Keep Form Visible After Success

By default, the form disappears after a successful submission. To keep it visible:

$form->createAndValidate('Name, Email', hideOnSuccess: false);

With Form Attributes

Pass form attributes as the second parameter:

$form = new Flick\Flick(['id' => 'contact-form']);

$form->createAndValidate('Name, Email', [
    'action' => '/submit',
    'method' => 'POST',
]);

If you give the form a custom id, you can set it in the Flick config (as above) or pass it in the attributes array — both work with createAndValidate(). The one exception is a form file like /login, which declares its id inside the file: Flick only reads it while rendering the form, after the submission check has run. When you validate a form file, set its id in the config too (new Flick\Flick(['id' => 'form-login'])) — see the prebuilt forms warning for details.

Rendering in Blade (Laravel)

In Laravel, Flick's echo setting is false, so form methods return their HTML instead of printing it. That's a problem for createAndValidate() in a Blade view, because it returns the validated data — not something you can echo. Use renderValidated() instead. It does everything createAndValidate() does, but returns the form's HTML so you can echo it, and hands you the validated data through the onSuccess callback:

{!! $form->renderValidated('Name[required], Email[email, required]',
    onSuccess: fn($data) => User::create($data)
) !!}

It shows the form, validates on submit, displays the success or error message, and hides the form after a successful submission. Custom messages, hideOnSuccess, and form attributes all work the same as createAndValidate():

{!! $form->renderValidated('Name, Email',
    successMessage: 'Thanks for signing up!',
    hideOnSuccess: false
) !!}

Create Your Form with a String

Tip

By far, the easiest way to create a form is with a string. Add each field's label text to Flick's create() method, and Flick will build the entire form for you.

$form->create('Name, Email, Comments');

The default field element type is text. However, you can easily change that by adding a pipe character after the label text, then add your element's type.

$form->create('Name, Email, Comments|textarea');

You can add a default value by wrapping it in curly braces.

$form->create('Username{gern}, Password|password');

You can add any of Flick's validation rules by wrapping them in square brackets.

$form->create('Username{gern}[min:2, max:16], Password|password');

You can specify a field is required by typing required, or using the r shortcut.

$form->create('Username[required], Password|password[r]');

Tip

When you add validation rules to create(), Flick remembers them! Just call $form->request() without any arguments when the form is submitted, and those same rules are applied automatically. See Auto-Rules for details.

Dropdown/Select options go inside parentheses. You can add an array of options by placing them inside square brackets.

$form->create('Foo|select([key:Value, foo:Foo, bar:Bar])');

You can add a default option by adding two colons followed by the option's label text.

$form->create('Foo|select([one:One, two:Two]::Select an Item...)');

Flick has several prebuilt dropdowns that you can use just by typing the name of the dropdown. In this instance, a menu with all 50 U.S. states plus Washington D.C. will be generated.

$form->create('State|select(states)');

Tip

You can also add your own prebuilt dropdowns. Take a look at the Customize docs for more info.

Overriding Form Attributes

You can override the form's default attributes and button text by passing an array of values to the create method's second parameter.

$attributes = [
    'id' => 'form-search',
    'method' => 'GET',
    'action' => '/search',
    'button' => '<i class="far fa-magnifying-glass"></i> Search',
    'string' => ' novalidate',
];

$form->create('Search|search', $attributes);

You can also pass a string of attributes to the second parameter.

$form->create('Search|search', ' novalidate onsubmit="submitForm()"');

Tip

Passing the string 'GET' to the second parameter will change the form action from POST to GET.

Labels Are Your HTML

Flick renders labels and button text exactly as you write them, so markup works:

$form->create('Search|search', [
    'button' => '<i class="far fa-magnifying-glass"></i> Search',
]);

$form->checkbox('agree', 'I agree to the <a href="/terms">Terms</a>', 'yes');

Field values are a different story. Flick escapes those for you, because a value can come straight back from the request when a form redisplays after a failed validation.

Warning

Because labels are rendered as-is, escape them yourself if you ever build one out of user-submitted data or content from a CMS:

$form->text('nickname', htmlspecialchars($userSuppliedLabel, ENT_QUOTES, 'UTF-8'));

Create Your Form with an Array

Create an array and pass it to the create() method; your form is ready.

$formArray = [
    'fields' => [
        'name' => [
            'type' => 'text',
            'name' => 'full_name',
            'label' => 'Your Name',
            'value' => 'Gern Blanston'
        ],
        'email' => [
            'type' => 'email',
            'name' => 'email',
            'label' => 'Your Email',
            'value' => 'email@learnwithgern.com'
        ]
    ]
];

$form->create($formArray);

Tip

You can save yourself a step and omit the name attribute from the field array. Doing this tells Flick to use the array's key as the field name. Plus, the default field element type is text, so you can leave off the type attribute as well if you're creating a text field.

// speed it up by omitting attributes

$form->create([
    'fields' => [
        'full_name' => [
            'label' => 'Your Name',
            'value' => 'Gern Blanston'
        ],
        'email' => [
            'type' => 'email',
            'label' => 'Your Email',
            'value' => 'email@learnwithgern.com'
        ]
    ]
]);

Only the fields array is required. The form action, method, etc. will be taken care of by Flick. Of course, you can override them...

$formArray = [
    'action' => '/search',
    'method' => 'GET',
    'attributes' => [
        'id' => 'form-search'
    ],
    'button' => [
        'text' => 'Search'
    ],
    'fields' => [
        'keyword' => [
            'type' => 'search',
            'name' => 'keyword',
            'label' => 'Search',
        ]
    ]
];

$form->create($formArray);

Load a Form from a File

You can save your form arrays as files and add them by passing the name of the file, preceded by a forward slash. The forward slash tells Flick to look for a file named login.php and load its contents.

$form->create('/login');

There are several forms which ship with Flick, and it's really easy to add your own. Take a look at the Configuration document for more details.

Tip

Flick will automatically append '.php' to the filename when loading a file.

Create Your Form with Field Elements

Creating your form using individual field elements allows for greater control, as you can add additional attributes, like custom classes, JavaScript, etc. Learn more about using Flick's field element methods.

$form->open();
$form->text('name', 'Name');
$form->email('email', 'Email');
$form->textarea('comments', 'Comments');
$form->submit();
$form->close();

Create Your Form with Raw HTML

Flick's value() method will display a default value (if provided), plus retain the value of the element after the form is submitted.

A hand-written form needs two hidden fields that open() and create() normally add for you: the CSRF token (from $form->csrf()) and the form's _id. Flick uses _id to recognize which form was submitted — leave it out and submitted() stays false, so values are never retained and request() returns null.

<form action="/" method="post">
    <?= $form->csrf() ?>
    <input type="hidden" name="_id" value="myForm">
    <input type="text" name="name" value="<?php $form->value('name', 'John Doe') ?>">
    <input type="email" name="email" value="<?php $form->value('email') ?>">
    <textarea name="comments"><?php $form->value('comments') ?></textarea>
    <button type="submit">Submit</button>
</form>

The _id value must match the form's id config, which defaults to 'myForm'.

Tip

value() prints on its own because echo is on by default. If you've set 'echo' => false, it returns the string instead — use <?= $form->value('name') ?>.


Multistep Forms

Flick makes multistep forms ridiculously easy. One array, automatic breadcrumbs, built-in review step, session handling - all handled for you.

$steps = [
    'Contact' => [
        'text' => 'How can we reach you?',
        'fields' => [
            'name'  => ['label' => 'Name', 'rules' => ['required']],
            'email' => ['type' => 'email', 'label' => 'Email'],
        ],
    ],
    'Preferences' => [
        'text' => 'What would you like to hear about?',
        'fields' => [
            'newsletter' => ['type' => 'checkbox', 'label' => 'Subscribe'],
        ],
    ],
];

$form->createMultistep($steps);

See the complete Multistep Forms Guide for customization options, helper methods, and practical examples.


Frequently Asked Questions

What's the fastest way to create a form in Flick?

Use createAndValidate() for the fastest approach. One line of code handles form creation, validation, success/error messages, and form hiding on success:

$form->createAndValidate('Name[required], Email[email, required]');

How do I add validation to a Flick form?

Add validation rules in square brackets after field names:

$form->create('Email[required, email], Password|password[required, min:8]');

Flick includes 40+ built-in validation rules including required, email, min, max, regex, creditCard, and strongPassword.

Can I use my own HTML with Flick?

Yes, Flick supports raw HTML forms. Use the value() method to retain field values:

<input type="text" name="name" value="<?php $form->value('name') ?>">

Include the hidden _id and CSRF fields shown in Create Your Form with Raw HTML — without them the submission isn't recognized. You can also use field element methods like $form->text(), $form->email() for more control while keeping Flick's features.

How do I create a multistep form wizard?

Use createMultistep() with an array of steps. Flick handles breadcrumbs, navigation, session storage, and the review step automatically:

$form->createMultistep([
    'Contact' => [
        'text' => 'How can we reach you?',
        'fields' => [
            'name'  => ['label' => 'Name', 'rules' => ['required']],
            'email' => ['type' => 'email', 'label' => 'Email'],
        ],
    ],
    'Preferences' => [
        'text' => 'What would you like to hear about?',
        'fields' => [
            'newsletter' => ['type' => 'checkbox', 'label' => 'Subscribe'],
        ],
    ],
]);