Forms & HTML
Begin by installing this package through Composer. Edit your project's composer.json
file to require laravellux/html
.
$ composer require laravellux/html
Looking to install this package in Lumen? First of all, making this package compatible with Lumen will require some core changes to Lumen, which we believe would dampen the effectiveness of having Lumen in the first place. Secondly, it is our belief that if you need this package in your application, then you should be using Laravel anyway.
ImportantSince this package internally uses strict comparisons (
===
instead of==
) be careful when passing numeric values into your forms. Values in HTML are submitted as strings and Laravel old values stored in flash session are strings.In this example, this package will correctly insert
selected
HTML attribute into the radio input - because the passed value'1'
strictly equals to the old submitted value in the session'1'
:{!! Form::radio('category_id', '1') !!}
// '1' === '1' - comparing passed value and old session valueHowever, in this example, the passed integer value
1
is not strictly equal to the old submitted string value'1'
in the session and theselected
HTML attribute will not be inserted:{!! Form::radio('category_id', 1) !!}
// 1 === '1' - comparing passed value and old session value
{!! Form::open(['url' => 'foo/bar']) !!}
//
{!! Form::close() !!}
By default, a POST
method will be assumed; however, you are free to specify another method:
{!! Form::open(['url' => 'foo/bar', 'method' => 'put']) !!}
Note: Since HTML forms only support
POST
andGET
,PUT
andDELETE
methods will be spoofed by automatically adding a_method
hidden field to your form.
You may also open forms that point to named routes or controller actions:
{!! Form::open(['route' => 'route.name']) !!}
{!! Form::open(['action' => 'Controller@method']) !!}
You may pass in route parameters as well:
{!! Form::open(['route' => ['route.name', $user->id]]) !!}
{!! Form::open(['action' => ['Controller@method', $user->id]]) !!}
If your form is going to accept file uploads, add a files
option to your array:
{!! Form::open(['url' => 'foo/bar', 'files' => true]) !!}
If you need to give the "_method" input attributes:
{!! Form::open(['action' => ['Controller@method', $user->id], 'method_attributes' => ['id' => 'controller_method_form']]) !!}
Laravel provides an easy method of protecting your application from cross-site request forgeries. First, a random token is placed in your user's session. If you use the Form::open method with POST
, PUT
or DELETE
the CSRF token will be added to your forms as a hidden field automatically. Alternatively, if you wish to generate the HTML for the hidden CSRF field, you may use the token
method:
{!! Form::token() !!}
Often, you will want to populate a form based on the contents of a model. To do so, use the Form::model
method:
{!! Form::model($user, ['route' => ['user.update', $user->id]]) !!}
Now, when you generate a form element, like a text input, the model's value matching the field's name will automatically be set as the field value. So, for example, for a text input named email, the user model's email attribute would be set as the value. However, there's more! If there is an item in the Session flash data matching the input name, that will take precedence over the model's value. So, the priority looks like this:
- Session Flash Data (Old Input)
- Explicitly Passed Value
- Model Attribute Data
This allows you to quickly build forms that not only bind to model values, but easily re-populate if there is a validation error on the server!
Note: When using
Form::model
, be sure to close your form withForm::close
!
Laravel Eloquent Accessors allow you to manipulate a model attribute before returning it. This can be extremely useful for defining global date formats, for example. However, the date format used for display might not match the date format used for form elements. You can solve this by creating two separate accessors: a standard accessor, and/or a form accessor.
To define a form accessor, create a formFooAttribute
method on your model where Foo is the "camel" cased name of the column you wish to access. In this example, we'll define an accessor for the date_of_birth attribute
. The accessor will automatically be called by the HTML Form Builder when attempting to pre-fill a form field when Form::model()
is used.
You must include the FormAccessible trait in your model definition for this to work.
<?php
namespace App;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use LaravelLux\Html\Eloquent\FormAccessible;
class User extends Model
{
use FormAccessible;
/**
* Get the user's date of birth.
*
* @param string $value
* @return string
*/
public function getDateOfBirthAttribute($value)
{
return Carbon::parse($value)->format('m/d/Y');
}
/**
* Get the user's date of birth for forms.
*
* @param string $value
* @return string
*/
public function formDateOfBirthAttribute($value)
{
return Carbon::parse($value)->format('Y-m-d');
}
}
{!! Form::label('email', 'E-Mail Address') !!}
{!! Form::label('email', 'E-Mail Address', ['class' => 'awesome']) !!}
Note: After creating a label, any form element you create with a name matching the label name will automatically receive an ID matching the label name as well.
{!! Form::text('username') !!}
{!! Form::text('email', 'email@example.com') !!}
Note: The hidden and textarea methods have the same signature as the text method.
{!! Form::password('password', ['class' => 'awesome']) !!}
Note: As passwords are ALWAYS sensitive these will not auto-populate in form models. Although this is configurable in
config/html-forms.php
{!! Form::email($name, $value = null, $attributes = []) !!}
{!! Form::file($name, $attributes = []) !!}
{!! Form::checkbox($name, $value, $checked = false, $attributes = []) !!}
{!! Form::radio($name, $value, $checked = false, $attributes = []) !!}
{!! Form::number($name, $value, $attributes = []) !!}
{!! Form::date($name, $value, $attributes = []) !!}
Note: You can pass in a Carbon object such as
now()
orCarbon::now()->startOfWeek()
as the value and this will be parsed
{!! Form::file($name, $attributes = []) !!}
{!! Form::select($name, $values, $default, $attributes = []) !!}
Note:
$values
should be an associative array where the key is the value you want the Laravel backend to receive when the form is submitted.
E.g. The following will have "Pick a size...", "Large", "Small" with "Small" selected by default.{!! Form::select('size', ['L' => 'Large', 'S' => 'Small'], 'S', ['placeholder' => 'Pick a size...']) !!}
{!! Form::select($name,[
$group_name => [$key => $value],
$group_name => [$key => $value],
]) !!}
WARNING: Use of this function is deprecated. Please use
{!! Form::select($name, range(10, 20)) !!}
to achieve this functionality.{!! Form::select('size', ['L' => 'Large', 'S' => 'Small'], 'S', ['placeholder' => 'Pick a size...']) !!}
{!! Form::selectRange('number', 10, 20) !!}
{!! Form::selectMonth($name) !!}
{!! Form::submit($name, $attributes = []) !!}
{!! Form::button($name, $attributes = []) !!}
It's easy to define your own custom Form class helpers called "macros". Here's how it works.
Simply register the macro with a given name and a Closure inside a new service provider called FormServiceProvider
.
You can generate this file using the following command:
$ php artisan make:provider FormServiceProvider
Once you have run this go to app/Providers/FormServiceProvider
and add your macros there inside of boot:
Form::macro('myField', function($name)
{
return '<input name="' . $name . ' type="awesome">';
});
Note: You are not required to have any function arguments, but you may add as many as you want.
Once the macro is created you can call it in any blade template just like any other form element:
{!! Form::myField('name') !!}
Custom Components are similar to Custom Macros, however instead of using a closure to generate the resulting HTML, Components utilize Laravel Blade Templates. Components can be incredibly useful for developers who use Twitter Bootstrap, or any other front-end framework, which requires additional markup to properly render forms.
Let's build a Form Component for a simple Bootstrap text input. You might consider registering your Components inside the FormServiceProvider's boot method.
Form::component('bsText', 'components.form.text', ['name', 'value' => 'default value here', 'attributes' => 'value of attributes by default']);
Notice how we reference a view path of components.form.text. Also, the array we provided is a sort of method signature for your Component. This defines the names of the variables that will be passed to your view. Your view might look something like this:
// resources/views/components/form/text.blade.php<div class="form-group"> {{ Form::label($name, null, ['class' => 'control-label']) }} {{ Form::text($name, $value, array_merge(['class' => 'form-control'], $attributes)) }} </div>
Note: Custom Components can also be created on the
Html
facade in the same fashion as on theForm
facade.
Using our example from above (specifically, the one with default values provided), you can call your Custom Component like so:
{!! Form::bsText('first_name') !!}
This would result in something like the following HTML output:
<div class="form-group">
<label for="first_name">First Name</label>
<input type="text" name="first_name" value="" class="form-control">
</div>
This function generates HTML links to the given URL.
{!! link_to('foo/bar', $title = null, $attributes = [], $secure = null) !!}
This function generates HTML <link> tag to the asset
{!! link_to_asset('foo/bar', $title = null, $attributes = [], $secure = null) !!}
This function generates HTML links to the given route.
{!! link_to_route('route.name', $title = null, $parameters = [], $attributes = []) !!}
This function generates HTML links to the given controller action.
{!! link_to_action('HomeController@getIndex', $title = null, $parameters = [], $attributes = []) !!}