Former

A powerful form builder for the Laravel framework

View project onGitHub

Former

A Laravelish way to create and format forms

Build Status Latest Stable Version Total Downloads Scrutinizer Quality Score Code Coverage

Former is the name of a little project I'd like to present you — it's a PHP package that allows you to do all kinds of powerful stuff with forms while remaining pretty simple to use. It's also a really nice guy too once you get to know him.

Former chews a lot of the work for you, it handles repopulation, validation, grouped fields, automatic markup for your favorite CSS framework (Bootstrap, Foundation). I invite you to take a look at the features page to get more informations.

Introduction

Former aims to rethink elegantly form creation by transforming each field into its own model, with its own methods and attributes. This means that you can do this sort of stuff :

Former::horizontal_open()
  ->id('MyForm')
  ->secure()
  ->rules(['name' => 'required'])
  ->method('GET')

  Former::xlarge_text('name')
    ->class('myclass')
    ->value('Joseph')
    ->required();

  Former::textarea('comments')
    ->rows(10)->columns(20)
    ->autofocus();

  Former::actions()
    ->large_primary_submit('Submit')
    ->large_inverse_reset('Reset')

Former::close()

Every time you call a method that doesn't actually exist, Former assumes you're trying to set an attribute and creates it magically. That's why you can do in the above example ->rows(10) ; in case you want to set attributes that contain dashes, just replace them by underscores : ->data_foo('bar') equals data-foo="bar". Now of course in case you want to set an attribute that actually contains an underscore (jeez aren't you the little smartass) you can always use the fallback method setAttribute('data_foo', 'bar'). You're welcome.

This is the core of it, but Former offers a lot more. I invite you to consult the wiki to see the extend of what Former does.


Getting started

Core concept

Former is to be used as a View helper – meaning it provides for you a class that you can use directly in your views to output HTML code.

<?= Former::open()->method('GET') ?>
    <?= Former::text('name')->required() ?>
<?= Former::close() ?>

If you're using Twig or other more closed view templating systems, you can still use Former's classes outside :

$form = Former::open()->method('GET');
    $form .= Former::text('name')->required();
$form .= Former::close();

Installation

Under Laravel 3

Clone the laravel3 branch of the repo in your bundles folder and add 'former' => array('auto' => true) to your bundles file. Then add as an alias 'Former' => 'Former\Facades\Former' in your application file and you're good to go !

Under Laravel 4

Installing Former is easy as hell. Add the following to your composer.json :

"anahkiasen/former": "dev-master"

Add Former's service provider to your Laravel application in app/config/app.php. In the providers array add :

'Former\FormerServiceProvider',

Add then alias Former's main class by adding its facade to the aliases array in the same file :

'Former' => 'Former\Facades\Former',

With Package installer

Simply do artisan package:install anahkiasen/former:dev-master

Outside of a framework

Same as for Laravel 4, add Former to your Composer file. Then do this :

use Former\Facades\Former;

And you're done.

Features

Out-of-the-box integration to Bootstrap and Foundation

So that's pretty nice, but so far that just looks like a modification of Laravel's Form class I mean, what's so fancy about all that ? That's where the magic underneath lies : Former recognizes when you create an horizontal or vertical form, and goes the extra mile of wrapping each field in a control group, all behind the scenes. That means that when you type this :

Former::select('clients')->options($clients, 2)
  ->help('Pick some dude')
  ->state('warning')

What you actually get is the following output (with Bootstrap) :

<div class="control-group warning">
  <label for="clients" class="control-label">Clients</label>
  <div class="controls">
    <select id="clients" name="clients">
      <option value="0">Mickael</option>
      <option value="1">Joseph</option>
      <option value="2" selected="selected">Patrick</option>
    </select>
    <span class="help-inline">Pick some dude</span>
  </div>
</div>

By default Former will use Twitter Bootstrap for its syntax but you can select which framework to use with the method Former::framework(). For the moment Former supports 'TwitterBootstrap', 'ZurbFoundation' and 'Nude' (for no framework).

// Turn off Bootstrap syntax
Former::framework('Nude');

// Turn it on again (MAKE UP YOUR MIND JEEZ)
Former::framework('TwitterBootstrap');

Here is an example of code for Foundation :

Former::framework('ZurbFoundation');

Former::four_text('foo')->state('error')->help('bar')

Outputs :

<div class="error">
  <label for="foo">Foo</label>
  <input class="four" type="text" name="foo" id="foo">
  <small>Bar</small>
</div>

Ties-in with Laravel's Validator

So ok, that's already a lot of clutter removed by not having to call the lenghty Form::control_group() function. Now I hear you coming : "but you know I still have to manually validate my form and su"— Well no you don't. Enters Former's magic helper withErrors; what it does is pretty simple. Since it's already wrapping your nice fields into control groups, it goes the distance, and gently check the Message object for any errors that field might have, and set that error as an .help-inline. Now we're talking !

Now you use it differently according to how your code reacts after a failed validation :

If your render a view on failed validation (no redirection)

if($validation->fails()) {
  Former::withErrors($validation);
  return View::make('myview');
}

If your redirect on failed validation

if($validation->fails()) {
  return Redirect::to('login')
    ->with_errors($validation);
}

Now on the last example you never actually call Former, be it in your controller or in your view. Why is that ? That's because when Former opens a form on a page, it will automatically check in Session if there's not an object called errors and if there is, it will try to use it without requiring you to call anything. You can disable Former's automatic errors fetching with the following option : Former::config('fetch_errors', false).

Form populating

You can populate a form with value quite easily with the Former::populate function. There is two ways to do that. The first way is the usual passing of an array of values, like this :

// Will populate the field 'name' with the value 'value'
Former::populate( array('name' => 'value') )

You can also populate a form by passing an Eloquent model to it, say you have a Client model, you can do that. This allows for a lot of goodies, I'll get back to it.

Former::populate( Client::find(2) )

Former will recognize the model and populate the field with the model's attribute. If here per example our client has a name set to 'Foo' and a firstname set to 'Bar', Former will look for fields named 'name' and 'firstname' and fill them respectively with 'Foo' and 'Bar'.

Alternatively you can also populate a specific field after you've populated the whole form (for a relationship per example) by doing this :

Former::populate($project)

Former::populateField('client', $project->client->name)

For the rest of the form, filling fields is basically as easy as doing ->value('something'). To generate a list of options for a <select> you call Former::select('foo')->options([array], [facultative: selected value]). You can also use the results from an Eloquent/Fluent query as options for a select, like this :

Former::select('foo')->fromQuery(Client::all(), 'name', 'id')

Where the second argument is which attribute will be used for the option's text, and the third facultative argument is which attribute will be used for the option's value (defaults to the id attribute). Former also does some magic if none of those two arguments are specified. Say you pass Eloquent models to Former and don't specify what is to be used as key or value. Former will obtain the key by using Eloquent's get_key() method, and use any __toString() method binded to the model as raw value. Take this example :

class Client extends Eloquent
{
  public static $key = 'code';

  public function __toString()
  {
    return $this->name;
  }
}

Former::select('clients')->fromQuery(Client::all());

Is the same as doing this but you know, in less painful and DRYer. This will use each Client's default key, and output the Client's name as the option's label.

<div class="control-group">
  <label for="foo" class="control-label">Foo</label>
  <div class="controls">
    <select id="foo" name="foo">
      @foreach(Client::all() as $client)
        @if(Input::get('foo', Input::old('foo')) == $client->code)
          <option selected="selected" value="{{ $client->code }}">{{ $client->name }}</option>
        @else
          <option value="{{ $client->code }}">{{ $client->name }}</option>
        @endif
      @endforeach
    </select>
  </div>
</div>

Former is also able to populate fields with relationships. Now an example is worth a thousand words (excepted if, you know, your example is a thousand words long) :

Former::populate(Client::find(2))

// Will populate with $client->name
Former::text('name')

// Will populate with $client->store->name
Former::text('store.name')

// You can go as deep as you need to
Former::text('customer.name.adress')

// Will populate with the date from all of the client's reservations
Former::select('reservations.date')

// Which is the same as this ^
Former::select('reservations')->fromQuery($client->reservations, 'date')

// If you're using a text and not a select, instead of listing the
// relationship's models as options, it wil concatenate them
Former::text('customers.name') // Will display "name, name, name"

// You can rename a field afterwards for easier Input handling
Former::text('comment.title')->name('title')

Kudos to cviebrock for the original idea.

Datalists

But what else does it do ? Datalists, it can do datalists. You don't know what they are ? Ok; you know how sometimes you would like to make people chose between something in a select but also being able to type what they want if it's not in it ? That's a datalist. In Former you can simply create one like that :

Former::text('clients')->useDatalist($clients)

// Or use a Query object, same syntax than fromQuery()
Former::text('projects')->useDatalist(Project::all(), 'name')

You can also (if you need to) set a custom id on the created datalist by doing Former::text('foo')->list('myId')->useDatalist(). From there it will automatically generate the corresponding <datalist> and link it by id to that field. Which means your text input will get populated by the values in your array, while still letting people type whatever they want if they don't find happiness and/or are little pains in the ass.

Live validation

MORE. Ok, instant validation, we all like that don't we ? Now as some of you may know, all modern browsers support instant validation via HTML attributes — no Javascript needed nor script nor polyfill. There are a few attributes that can do that kind of job for you, pattern, required, max/min to name a few. Now you know when you validate your POST data with that little $rules array stuff ? Wouldn't it be awesome to just be able to pass that array to your form and let it transcribe your rules into real-live validation ? Yes ? Because you totally can with Former, just sayin'. Take the following (far-fetched) rules array :

Former::open()->rules(array(
  'name'     => 'required|max:20|alpha',
  'age'      => 'between:18,24',
  'email'    => 'email',
  'show'     => 'in:batman,spiderman',
  'random'   => 'match:/[a-zA-Z]+/',
  'birthday' => 'before:1968-12-03',
  'avatar'   => 'image',
));

What Former will do is look for fields that match the keys and apply the best it can those rules. There's not a lot of supported rules for now but I plan on adding more.

<input name="name"      type="text"   required maxlength="20" pattern="[a-zA-Z]+" />
<input name="age"       type="number" min="18" max="24" />
<input name="email"     type="email" />
<input name="show"      type="text"   pattern="^(batman|spiderman)$" />
<input name="random"    type="text"   pattern="[a-zA-Z]+" />
<input name="birthday"  type="date"   max="1968-12-03" />
<input name="avatar"    type="file"   accept="image/jpeg,image/png,image/gif,image/bmp" />

Note that you can always add custom rules the way you'd add any attributes, since the pattern attribute uses a Regex (and if you don't speak Regex you totally should because it will guide you through life or something).

Former::number('age')->min(18)

Former::text('client_code')->pattern('[a-z]{4}[0-9]{2}')

And that's it ! And the best news : since Bootstrap recognizes live validation, if say you try to type something that doesn't match the alpha pattern in your name field, it will automatically turn red just like when your control group is set to error. Just like that, fingers snappin' and all, nothing to do but sit back, relax, and watch Chrome/Firefox/whatever pop up a sweet little box saying "You have to fill that field dude" or "That is not email, what are you trying to do, fool me or something ?".

You can also, mid-course, manually set the state of a control group — that's a feature of course available only if you're using either Bootstrap or Foundation. You can use any of the control group states which include success, warning, error and info.

Former::text('name')->state('error')

Files handling

In Former like in Laravel you can create a simple file field with Former::file. What's new, is you can also create a multiple files field by calling Former::files which which will generate <input type="file" name="foo[]" multiple />.

One of the special method is the ->accept() with which you can do the following :

// Use a shortcut (image, video or audio)
Former::files('avatar')->accept('image')

// Use an extension which will be converted to MIME by Laravel
Former::files('avatar')->accept('gif', 'jpg')

// Or directly use a MIME
Former::files('avatar')->accept('image/jpeg', 'image/png')

You can also set a maximum size easily by using either bits or bytes

Former::file('foo')->max(2, 'MB')
Former::file('foo')->max(400, 'Ko')
Former::file('foo')->max(1, 'TB')

This will create an hidden MAX_FILE_SIZE field with the correct value in bytes.

Checkboxes and Radios

Checkboxes and radios, man, aren't those annoying ? Even more when you have to create several of them, and you think in your head "WHY CAN'T I VALIDATE ALL THESE LIMES ?". With Former it's all a little easier :

// Create a one-off checkbox
Former::checkbox('checkme')

// Create a one-off checkbox with a text, and check it
Former::checkbox('checkme')
  ->text('YO CHECK THIS OUT')
  ->check()

// Create four related checkboxes
Former::checkboxes('checkme')
  ->checkboxes('first', 'second', 'third', 'fourth')

// Create related checkboxes, and inline them
Former::checkboxes('checkme')
  ->checkboxes($checkboxes)->inline()

// Everything that works on a checkbox also works on a radio element
Former::radios('radio')
  ->radios(array('label' => 'name', 'label' => 'name'))
  ->stacked()

// Stacked and inline can also be called as magic methods
Former::inline_checkboxes('foo')->checkboxes('foo', 'bar')
Former::stacked_radios('foo')->radios('foo', 'bar')

// Set which checkables are checked or not in one move
Former::checkboxes('level')
  ->checkboxes(0, 1, 2)
  ->check(array('level_0' => true, 'level_1' => false, 'level_2' => true))

// Fine tune checkable elements
Former::radios('radio')
  ->radios(array(
    'label' => array('name' => 'foo', 'value' => 'bar', 'data-foo' => 'bar'),
    'label' => array('name' => 'foo', 'value' => 'bar', 'data-foo' => 'bar'),
  ))

Important point : Former gives you an option to force the pushing of checkboxes. What is that you mean ? That's when your checkboxes still pop up in your POST data even when they're unchecked. That sounds pretty normal but is actually the opposite of the weird-ass default behavior of forms. "IT'S UNCHECKED ? I HAVE NO RECOLLECTION WHATSOEVER OF THAT FIELD HAVING EVER EXISTED". You can change what value an unchecked checkbox possesses in the POST array via the unchecked_value option.

When creating checkables via the checkboxes/radios() method, by default for each checkable name attribute it will use the original name you specified and append it a number (here in our exemple it would be <input type="checkbox" name="checkme_2">). It also repopulates it, meaning a checked input will stay checked on submit.

Localization helpers

For those of you that work on multilingual projects, Former is also here to help. By default, when creating a field, if no label is specified Former will use the field name by default. But more importantly it will try and translate it automatically. Same goes for checkboxes labels, help texts and form legends. Which means the following :

// This
Former::label(__('validation.attributes.name'))
Former::text('name', __('validation.attributes.name'))
Former::text('name')->inlineHelp(__('help.name'))
Former::checkbox('rules')->text(__('my.translation'))
<legend>{{ __('validation.attributes.mylegend') }}</legend>

// Is the same as this
Former::label('name')
Former::text('name')
Former::text('name')->inlineHelp('help.name')
Former::checkbox('rules')->text('my.translation')
Former::legend('mylegend')

Which you know, is kind of cool. Former will first try to translate the string in itself, ie my.text will return __('my.text') and if that fails, it will look for it in a fallback place. You can set where Former look for translations by changing the following variable : Former::config('translate_from', [boolean]) (defaults to validation.attributes). Note that it must be an array.

Notes on setting field values

All form classes encounter a problem at one point : what kind of data takes precedence over what kind ? To populate your field, Former set the following priorities to found values :

  • POST data takes precedence over everything – if a user just typed something in a field, chances are this is what they want to see in it next time
  • Then comes data set via the ->forceValue() method – it's a special branch of ->value() created to force a value in a field no matter what happens
  • Then any values set via Former::populate() – that means that if you're editing something or are repopulating with some value, it can be overwritten with forceValue
  • Finally the classic ->value() gets the least priority – it is created for minimum and default field values and thus gets overwritten by population and POST data

Anatomy of Former

Bare with me, there are a lot of classes but it all makes sense once you read what they do :

  • Former : The main class, mostly handles configuration and interactions between the form parts
  • FormerServiceProvider : The Service Provider for Laravel 4
  • Helpers : A set of static helpers used troughout the library
  • Dispatch : Catches the call you do the Former facade and dispatches them to the right classes
  • LiveValidation : Handles live validation of fields and translation of rules into attributes
  • Populator : A value container from which Former gets/sets the fields values
  • Traits
    • Checkable : Common methods and properties to radios and checkboxes
    • Field : Common methods and properties to all fields
    • FormerObject : A base object extended by the traits above, handles dynamic attributes and stuff
    • Framework : Common methods and properties to all frameworks
  • Interfaces : Required methods by all fields an frameworks
    • FieldInterface
    • FrameworkInterface
  • Framework : These classes generate the right markup according to the framework in use
    • Nude
    • TwitterBootstrap
    • ZurbFoundation
  • Form : All the classes underneath handle the actual markup and elements of a form
    • Actions : Handles the actions blocks where submit buttons and all are found
    • Elements : Various form elements that are neither fields nor actions (legends, etc)
    • Form : Handles the form opening and closing and the methods that go with it
    • Group : Wraps fields and provide field states, errors fetching and such
    • Fields : The field classes, each handle one kind of field. The names say it all
      • Button
      • Checkbox
      • File
      • Hidden
      • Input
      • Radio
      • Select
      • Textarea
      • Uneditable
  • Facades : Various entry points that smooth out the experience across environments
    • Agnostic : The base facade used by Former outside of any framework
    • FormerBuilder : Common methods and building blocks for all facades to use
    • Illuminate : The Laravel 4 facade, hooks up Former to the various components (localization etc)
    • LaravelThree : The Laravel 3 facade, hooks up Former to the various components (localization etc)
    • Legacy : A set of redirector classes that unify the interface between Laravel 3 and 4
      • Config
      • Redirector
      • Session
      • Translator

Description of each method

Former\Former

This class is the main class - it is your interface for everything in Former. Now of course, Former makes you interact with its subclasses which means you can not only use its methods but the methods of each class used by Former.

Options

This is a set of options that can be set to modify Former's behavior.

Former::config('translate_from', [string]) ('validation.attributes')

By default Former tries to translate most labels, legends and help texts. For that it first tries to translate the string passed as is, and then it tries to look in a special place that can be defined with this variable - defaulting to 'validation.attributes.mykey'.

Former::config('required_class', [string]) ('required')

A class to add to fields that are set as required.

Former::config('default_form_type', [horizontal|vertical|inline|search]) ('horizontal')

By default when you call Former::open a fallback form type gets assigned to the form – this is the option that says which one is that type. It can be any of those values, or null if you want don't want to use Bootstrap's form classes.

Former::config('fetch_errors', [boolean]) (true)

Whenever you call the open method, if this option is set to true, Former will look into the Session array for a Message objects that would have been created by the ->with_errors() method of Redirect. Which means that if on failed validation you do Redirect::to()->with_errors(), Former will automatically fetch said errors and display them on the corresponding fields without having to type anything.

Former::config('automatic_label', [boolean]) (true)

Allows the user to turn on or off the automatic labeling feature. When it's on, if you give per example foo as a field name and no label, Former will assume foo is also to be used as label. Former will then attempt to translate it, capitalize it, and use it as label. With this option turned off, if no label is specific, no label tag will be printed out.

Former::config('live_validation', [boolean]) (true)

Whether Former should try to apply Laravel's Validator rules as live validation attributes.

Former::config('push_checkboxes', [boolean]) (true)

Whether checkboxes should always be present in the POST data, no matter if you checked them or not

Helpers

Former::populate([array|Eloquent])

Populates the fields with an array of values or an Eloquent object.

Former::withErrors([Validator])

If you have an $errors variable from a failed validation, Former will automatically fetch it from Session and set the corresponding fields as incorrect and display the error message right next to them. This is if you're calling withErrors in your view. If you're in the controller, you can simply pass the $validator object to Former and it will work just the same.

Former::withRules([array])

Let you pass an array of Laravel rules to Former, to let it try and apply those rules live with HTML attributes such as pattern, maxlength, etc.

Former::framework([bootstrap|zurb|null])

Select which CSS framework Former should use for its syntax – each gives you more or less access to the available methods. Per example you can't use Bootstrap's ->blockHelp method while using Zurb, etc.

$error = Former::getErrors([string])

Equivalent to $error = isset($errors) ? $errors->first('field') : null.

Form builders

Former::legend([string])

Opens a Bootstrap <legend> tag in your form – the string passed to Former can be a translation index since Former will attempt to translate it.

Former::open()

The open method mirrors Laravel's, which means you can refer to the doc for it on Laravel's website. But it also support the magic methods introduced by Bootstrapper for backward compatibility :

Former::horizontal_open()
Former::secure_open()
Former::open_for_files()
Former::secure_vertical_open_for_files()

You can mix it up however you want as long as each block remain intact (ie. you can't do secure_files_open_for_vertical because that makes no fucking sense).

Former::close()

Pretty straightforward, simply prints out a </form> tag. No argument or nothing.

Former::actions([string, ...])

Creates a <div class='form-actions'> tag to wrap your submit/reset/back/etc buttons. To output multiple buttons simply use multiple arguments

// Button class from Bootstrapper
Former::actions( Button::submit('Submit'), Button::reset('Reset') )

Field builders

And the one class you'll be using the two thirds of the time :

Former::[classes]_[field]

This method analyze whatever unknown method you're trying to call and creates a field with it. It decomposes it as [classes]_[field] or [field]. As classes you can call all Bootstrap classes working on fields : span1 to span12 and mini to xxlarge.

Former\Field

This class is what you actually get when you create a field, which means the method listed underneath are only accessible as chained methods after a field was created. To put it simply :

// Here you're using Former
Former::populate($project)

// Here you're actually using the Field class wrapped in Former
Former::text('foo')

A Former class stops being a field the second that field is printed out. Which means that you can do this :

$textField = Former::text('foo');
$textField->class('myclass')

But can't do this :

echo Former::text('foo')
Former::class('myclass')

Because fields are like little birds and once they fly away you can't get take care of them anymore.

Interactions with the attributes

Former::text('foo')->addClass([string])

Adds a class to the current field without overwriting any existing one. This differs front ->class() will — just like any attribute setter — overwrite any existing value.

Former::text('foo')->forceValue([string])

Sets the field value to something. This will be overwritten by POST data, but will overwrite calls to Former::populate.

Former::text('foo')->value([string])

Sets a default value for a field — a text present in it but that will get overwritten by calls to Former::populate or POST data.

Former::text('foo')->[attribute]([value])

Sets the value of any attribute. Attributes containing dashes have to be replaced with an underscore, so that you'd call data_foo('bar') to set data-foo="bar".

Former::text('text')->setAttribute([string], [string])

Can be used as a fallback to magic methods if you really have to set an attribute that contains an underscore.

Former::text('foo')->setAttributes([associative array])

Allows you to mass-set a couple of attributes with an array. So the following examples do the exact same thing.

Former::text('foo')->class('foo')->foo('bar')

Former::text('foo')->setAttributes(array( 'class' => 'foo', 'foo' => 'bar' ))

The second way is not the cleanest per say but is still useful if you have to set the same attributes for a group of fields, you can then just create an array with the attributes you want and assign it to each field in order to stay DRY.

Former::text('foo')->label([string])

Sets the label of a field to a string. If you're using Bootstrap this has a specific meaning since the label that will be created will automatically have the class control-label.

Former::text('foo')->addGroupClass('bar')

Adds specified class attributes to the parent control-group.

Helpers

$textField = Former::text('foo')->require()
$textField = $textField->isRequired() // Returns "true"

Checks if a field has been set to required, be it by yourself or when transposing Laravel rules.

Former\Checkable

Checkable is a subset of Field, which means all methods available with Field are available with Checkable. The latter just offers a few more methods related to radios and checkboxes.

Former::radios('foo')->inline()
Former::checkboxes('foo')->stacked()

Set the current radios and checkboxes as inline, or stacked (vertical)

Former::checkbox('foo')->text('bar')

If you're printing only a single checkbox/radio, it's easier to use this method to set the text that will be appended to it.

Former::checkbox('foo')->check()
Former::radio('foo')->check()

Former::checkboxes('foo')->checkboxes('foo', 'bar')->check('foo_0')

Former::radios('foo')->checkboxes('foo', 'bar')->check(0)

The check method allows you to check a one-off checkable element, or to check one in a group of checkable elements. Now for single elements you just call check() without arguments – but when you're using a group you need to specify which element is going to be checked. This is done differently if you're creating radios or checkboxes. Why ? Because checkboxes can only be differentiated by their field name, while radio elements can only be differentiated by their value. So that's it, for checkboxes you specify the name of the one you want to see checked, and for radios you specify its value.

Former\ControlGroup

Helpers and methods related to Bootstrap's control groups. If you set the $useBootstrap option to false earlier, this class is not accessible, nor are any of its methods.

Former::text('foo')->state([error|warning|info|success])

Set the state of a control group to a particular Bootstrap class.

Former::text('foo')->inlineHelp([string])
Former::text('foo')->blockHelp([string])

Adds an inline/block help text to the current field. Both can be called (meaning you can have both an inline and a block text) but can only be called once (which means if you call inlineHelp twice the latter will overwrite whatever you typed in the first one).

Former::text('foo')->append([string, ...])
Former::text('foo')->prepend([string, ...])

Prepends one or more icons/text/buttons to the current field. Those functions use func_get_args() so you can per example do that :

Former::text('foo')->prepend('@', '$')

Former\Fields\Input

All classes related to Input-type fields.

Former::text('foo')->useDatalist([array])

Former::text('foo')->useDatalist([Query], [string], [string (id)])

Creates a <datalist> tag and links it to the field in order to create a select/text mix.

Former\Fields\Select

All classes related to Select-type fields (select, multiselect, etc)

Former::select('foo')->options([array], [selected])

Populates a <select> field with an array of options, where key will be the option's value and value will be its text. It sounds retarted explained like that but it means the following :

Former::select('clients')->options(array(
    1  => 'Max',
    3  => 'Clémence',
    12 => 'Jean Valjean'
));

<select name="foo">
    <option value="1">Max</option>
    <option value="3">Clémence</option>
    <option value="12">Jean Valjean</option>
</select>

Which looks really natural : you select a client's name and get it's ID in return. The second parameters allows to preselect one option, per example if in the above example we'd done ->options($clients, 3) then Clémence would have been selected.

Former::select('foo')->select(3)

Alias for ->value(), selects an option.

Former::select('foo')->fromQuery([array], [string], [string (id)])

Populates a <select> field with the results of a Fluent/Eloquent query. Second argument is the attribute used by Former for the options text, third argument is the attribute used by Former for the options value (defaults to the id attribute). Second argument defaults to the model's __toString() method, thirds defaults to the model's get_key() method.

Former::select('foo')->placeholder('Select one option...')

Create a ghost option set as disabled by default to serve as placeholder for the select.