• This repository has been archived on 27/Feb/2018
  • Stars
    star
    232
  • Rank 172,847 (Top 4 %)
  • Language
    PHP
  • License
    MIT License
  • Created over 11 years ago
  • Updated almost 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Super basic form HTML builder, only really exists so I can pull it in for some other more useful projects.

Important: This package is not actively maintained. For bug fixes and new features, please fork.

Form

This Project Has Been Deprecated. Code Climate Coverage Status

Boring name for a boring package. Builds form HTML with a fluent-ish, hopefully intuitive syntax.

Installation

You can install this package via Composer by running this command in your terminal in the root of your project:

composer require adamwathan/form

Laravel

This package works great as a replacement Form Builder that was removed in Laravel 5. The API is different but all of the features are there.

If you are using Laravel 4 or 5, you can register the FormServiceProvider to automatically gain access to the Old Input and Error Message functionality.

To do so, just update the providers array in your config/app.php:

'providers' => [
        //...
        'AdamWathan\Form\FormServiceProvider'
    ],

You can also choose to use the Facade by adding an alias in config/app.php:

'aliases' => [
        //...
        'Form' => 'AdamWathan\Form\Facades\Form',
    ],

Note that in Laravel 4, there is already a Form facade for the built-in Form Builder. If you want to use both, use a different alias. If you'd just like to use this one, remove the Form alias that points to the Illuminate component.

Basic Usage

Getting Started

First, instantiate a FormBuilder...

$builder = new AdamWathan\Form\FormBuilder;

Next, use the FormBuilder to build an element. For example:

// <input type="text" name="email" value="[email protected]" required="required">
<?= $builder->text('email')->value('[email protected]')->required(); ?>
  • All elements support method chaining, so you can add as many options to an element as you need.
  • All elements implement __toString() so there is no need to manually render.

Opening a Form

// <form method="POST">
<?= $builder->open(); ?>

// <form method="GET">
<?= $builder->open()->get(); ?>

// <form method="POST">
// <input type="hidden" name="_method" value="PUT">
<?= $builder->open()->put(); ?>

// <form method="POST">
// <input type="hidden" name="_method" value="DELETE">
<?= $builder->open()->delete(); ?>

// <form method="POST" action="/test">
<?= $builder->open()->action('/test'); ?>

// <form method="POST" action="" enctype="multipart/form-data">
<?= $builder->open()->multipart() ?>

// <form method="POST" action="" enctype="custom">
<?= $builder->open()->encodingType("custom") ?>

Text and Password Fields

Text and password fields share the same interface.

// <input type="text" name="email">
<?= $builder->text('email'); ?>

// <input type="text" name="email" id="email_field">
<?= $builder->text('email')->id('email_field'); ?>

// <input type="password" name="password" class="required">
<?= $builder->password('password')->addClass('required'); ?>

// <input type="text" name="email" value="[email protected]" required="required">
<?= $builder->text('email')->value('[email protected]')->required(); ?>

Other available methods:

  • placeholder($string)
  • optional()
  • defaultValue($string)
  • disable()
  • enable()

Textareas

Textareas share the same interface as regular text fields, with a couple of extra useful methods.

// <textarea name="bio" rows="5" cols="50"></textarea>
<?= $builder->textarea('bio')->rows(5); ?>

// <textarea name="bio" rows="10" cols="20"></textarea>
<?= $builder->textarea('bio')->cols(20); ?>

// <textarea name="bio" rows="5" cols="20" class="important">My biography</textarea>
<?= $builder->textarea('bio')->rows(5)->cols(20)->addClass('important')->value('My biography'); ?>

Checkboxes and Radio Buttons

// <input type="checkbox" name="terms" value="1">
<?= $builder->checkbox('terms'); ?>

// <input type="checkbox" name="terms" value="1" checked="checked">
<?= $builder->checkbox('terms')->check(); ?>

// <input type="checkbox" name="terms" value="1">
<?= $builder->checkbox('terms')->uncheck(); ?>

// <input type="checkbox" name="terms" value="1" checked="checked">
<?= $builder->checkbox('terms')->defaultToChecked(); ?>

// <input type="checkbox" name="terms" value="agree">
<?= $builder->checkbox('terms')->value('agree'); ?>

// <input type="radio" name="color" value="red">
<?= $builder->radio('color', 'red'); ?>

Selects

// <select name="birth_year"></select>
<?= $builder->select('birth_year'); ?>

// <select name="birth_year">
//   <option value="0">1990</option>
//   <option value="1">1991</option>
//   <option value="2">1992</option>
// </select>
<?= $builder->select('birth_year', [1990, 1991, 1992]); ?>

// <select name="birth_year">
//   <option value="1990">1990</option>
//   <option value="1991">1991</option>
//   <option value="1992">1992</option>
// </select>
<?= $builder->select('birth_year', ['1990' => 1990, '1991' => 1991, '1992' => 1992]); ?>

// <select name="birth_year">
//   <optgroup label="Ontario">
//     <option value="toronto">Toronto</option>
//     <option value="ottawa">Ottawa</option>
//   </optgroup>
//   <optgroup label="Quebec">
//     <option value="montreal">Montreal</option>
//     <option value="quebec_city">Quebec City</option>
//   </optgroup>
// </select>
$options = [
	'Ontario' => [
		'toronto' => 'Toronto',
		'ottawa' => 'Ottawa',
	],
	'Quebec' => [
		'montreal' => 'Montreal',
		'quebec_city' => 'Quebec City',
	]
];

<?= $builder->select('birth_year', $options); ?>

// <select name="birth_year">
//   <option value="1">1990</option>
// </select>
<?= $builder->select('birth_year')->addOption('1', 1990); ?>

// <select name="birth_year">
//   <option value="1">1990</option>
//   <option value="2">1991</option>
//   <option value="3" selected>1992</option>
// </select>
<?= $builder->select('birth_year', ['1' => 1990, '2' => 1991, '3' => 1992])->select('3'); ?>

Buttons

// <button type="button">Click Me</button>
<?= $builder->button('Click Me'); ?>

// <button type="submit">Sign Up</button>
<?= $builder->submit('Sign Up'); ?>

// <button type="reset">Reset Form</button>
<?= $builder->reset('Reset Form'); ?>

// <button type="submit" class="js-submit">Sign Up</button>
<?= $builder->submit('Sign Up')->addClass('js-submit'); ?>

Hidden Inputs

// <input type="hidden" name="secret" value="my-secret-value">
<?= $builder->hidden('secret')->value('my-secret-value'); ?>

Labels

Basic Label

// <label>Email</label>
<?= $builder->label('Email'); ?>

// <label for="email">Email</label>
<?= $builder->label('Email')->forId('email'); ?>

Wrapping another element

// <label>Email<input type="text" name="email"></label>
<?= $builder->label('Email')->before($emailElement); ?>

// <label><input type="text" name="email">Email</label>
<?= $builder->label('Email')->after($emailElement); ?>

Setting Attributes

// Attributes can be set with attribute(...)
// <input type="text" name="foobar" min="4">
<?= $builder->text('foobar')->attribute('min', 4); ?>

// Or by calling the attribute name as a method
// <input type="text" name="foobar" min="4">
<?= $builder->text('foobar')->min(4); ?>

// Setting data-* attributes
// <input type="text" data-foo="bar" name="foobar">
<?= $builder->text('foobar')->data('foo', 'bar'); ?>

// Multiple data-* attributes can be set at once
// <input type="text" data-foo="bar" data-bar="foo" name="foobar">
<?= $builder->text('foobar')->data(['foo' => 'bar', 'bar' => 'foo']); ?>

Remembering Old Input

The FormBuilder can remember old input and prepopulate your form fields if you redirect back to the form because of a validation error.

To make this work, you must create a class that implements the OldInputInterface and pass it to the FormBuilder:

$builder->setOldInputProvider($myOldInputProvider);

Now, your form elements will automatically populate with the user's old input data if it is available.

This works well with the defaultValue() methods, allowing you to set a default value that will be overridden by old input if the user has already submitted the form.

This package ships with a Laravel implementation out of the box, called IlluminateOldInput.

Error Messages

FormBuilder also allows you to easily retrieve error messages for your form elements. To do so, just implement the ErrorStoreInterface and pass it to the FormBuilder:

$builder->setErrorStore($myErrorStore);

This package ships with a Laravel implementation out of the box, called IlluminateErrorStore.

// Check if the form has an error for an element
$builder->hasError('email');

// Retrieve the error message for an element
$builder->getError('email');

You can also supply a format parameter to getError() to cleanup your markup. Instead of doing this:

<?php if ($builder->hasError('email')): ?>
	<span class="error"><?= $builder->getError('email'); ?></span>
<?php endif; ?>

...you can simply do this, which will display the formatted message if it exists, or nothing otherwise.

<?= $builder->getError('email', '<span class="error">:message</span'); ?>

CSRF Protection

Assuming you set a CSRF token when instantiating the Formbuilder (or you are using Laravel), add a CSRF token to your form easily like so:

<?= $builder->token(); ?>

Data Binding

Sometimes you might have a form where all of the fields match properties on some sort of object or array in your system, and you want the user to be able to edit that data. Data binding makes this really easy by allowing you to bind an object or array to your form that will be used to automatically provide all of the default values for your fields.

$model->first_name = "John";
$model->last_name = "Doe";
$model->email = "[email protected]";
$model->date_of_birth = new DateTime('1985-05-06');

<?= $builder->open(); ?>
<?= $builder->bind($model); ?>
<?= $builder->text('first_name'); ?>
<?= $builder->text('last_name'); ?>
<?= $builder->email('email'); ?>
<?= $builder->date('date_of_birth'); ?>
<?= $builder->close(); ?>

This will work out of the box with Laravel's Eloquent models.

When using data binding, old input will still take priority over any of your bound values, so you can still easily redirect the user back to the form with any validation errors without losing any of the data they entered.

Note: Be sure to bind before creating any other form elements.

More Repositories

1

laracon2017

PHP
469
star
2

workcation

Vue
425
star
3

bootforms

Rapid form generation with Bootstrap 3 and Laravel.
PHP
419
star
4

vue-tailwind-examples

Vue
390
star
5

eloquent-oauth

Braindead simple social login with Laravel and Eloquent.
PHP
374
star
6

laravel-preset

PHP
277
star
7

sublime-phpunit

Run individual unit test files directly from Sublime
Python
276
star
8

theming-tailwind-demo

HTML
267
star
9

eloquent-oauth-l5

Eloquent OAuth service provider and assets for Laravel 5
PHP
214
star
10

tailwind-take-home-project

Vue
132
star
11

vue-shopify-sortable-demo

HTML
113
star
12

fullstackradio.com

JavaScript
90
star
13

test-driven-laravel-from-scratch

PHP
81
star
14

tailwind-css-variable-text-opacity-demo

JavaScript
77
star
15

entypo-optimized

61
star
16

tailwindcss-dark-mode-prototype

JavaScript
58
star
17

workcation-theme-ui

JavaScript
38
star
18

vueconfto-demo

Vue
38
star
19

rebuilding-netlify

JavaScript
32
star
20

sublime-themes

Personal mods for ST themes I use
31
star
21

tailwind-animation-playground

HTML
27
star
22

laracon-madrid

The source code for my "Advanced Vue Component Design" at Laracon EU Madrid.
Vue
27
star
23

cra-tailwind-3

HTML
27
star
24

tailwind-jit-vite-example

Vue
25
star
25

tailwind-starter

CSS
24
star
26

rebuilding-allbirds-with-tailwindcss

JavaScript
24
star
27

laracon-2020

Vue
24
star
28

faktory

An attempt to bring the wonders of FactoryGirl to PHP.
PHP
22
star
29

rebuilding-transistor

JavaScript
22
star
30

tailwindcss-jit-next

JavaScript
17
star
31

tailwind-ui-navbar-react

JavaScript
16
star
32

nuxt-storybook

Vue
16
star
33

workcation-splash-page

HTML
15
star
34

vue-sidebar-layout

Vue
15
star
35

next10-tailwind

JavaScript
14
star
36

cra-tailwind-demo

JavaScript
12
star
37

next-nested-routing

JavaScript
12
star
38

laracon-online-2019

PHP
10
star
39

jit-vite-preact

TypeScript
9
star
40

nuxt-nested-layouts

Vue
9
star
41

tweeter-eu

PHP
8
star
42

tailwind-jit-cra-example

JavaScript
7
star
43

tailwind-cra-next

JavaScript
7
star
44

jit-postcss-demo

HTML
7
star
45

vue-rename-tailwind-config

JavaScript
7
star
46

activerest

ActiveRecord wrapper for REST APIs
PHP
7
star
47

headbangstagram

JavaScript
6
star
48

postcss8-tailwind

JavaScript
6
star
49

dotfiles

JavaScript
6
star
50

solid-tailwind-setup-example

JavaScript
5
star
51

tailwind-browserslist-test

HTML
5
star
52

tailwind-color-name-test

JavaScript
5
star
53

facktory

An attempt to bring the wonders of FactoryGirl to PHP
PHP
5
star
54

phxtailwindui

Elixir
4
star
55

tw3-cra-typescript-example

HTML
4
star
56

tw-devtools-perf

Vue
4
star
57

tailwind-color-function-demo

JavaScript
4
star
58

socialnorm

PHP
4
star
59

eloquent-oauth-l4

Eloquent OAuth service provider and assets for Laravel 4
PHP
4
star
60

tailwind-2-aspect-ratio

CSS
4
star
61

upgrade-config

JavaScript
4
star
62

next-cssnano-issue

CSS
3
star
63

sveltekit-forms-esm-demo

Svelte
3
star
64

at-apply-stuck

JavaScript
3
star
65

game-of-life

HTML
3
star
66

tailwind-plugin-color-extend-example

JavaScript
3
star
67

vite-issue-repro

Vue
3
star
68

micheltazartes

JavaScript
3
star
69

lets-refactor-zendcon

PHP
3
star
70

tailwindcss-i2369

JavaScript
2
star
71

tailwind-repro-8597

HTML
2
star
72

base-comment-delete-test

CSS
2
star
73

focus-visible-test

CSS
2
star
74

socialnorm-google

Google provider for SocialNorm
PHP
2
star
75

eloquent-oauth-example

Basic example Laravel app with minimal setup required for Eloquent OAuth
PHP
2
star
76

issue-10419

JavaScript
2
star
77

tailwind-repro-8661

CSS
2
star
78

vue-tailwind-library

Vue
1
star
79

thready-site

HTML
1
star
80

next-color-import-test

JavaScript
1
star
81

next-tailwind-hot-reload-issue

JavaScript
1
star
82

tw-postcss7-purge-test

CSS
1
star
83

tailwind-issue-7685

HTML
1
star
84

simple-design-ssphp16

PHP
1
star
85

vite-vue2-jit-issue

HTML
1
star
86

gulp-postcss-dependency-bug

JavaScript
1
star
87

vagrant-php

Just a little provisioning script and Vagrantfile, I'm sure I'll refine it over time.
Shell
1
star
88

parcel-2-postcss-dependency-bug

JavaScript
1
star
89

tailwindcss-forms-class-strategy-test

CSS
1
star
90

tw-postcss8-issue

JavaScript
1
star
91

eloquent-oauth-l5-example

PHP
1
star
92

larawedding

PHP
1
star
93

socialnorm-linkedin

LinkedIn provider for SocialNorm
PHP
1
star
94

postcss-normalize-bug

CSS
1
star
95

postcss-use-bug

JavaScript
1
star
96

vite-jsx-build-fail

Vue
1
star
97

turbopack-test

CSS
1
star
98

metamarkdown

PHP
1
star