Giter Club home page Giter Club logo

html's Introduction

Forms & HTML

tests Total Downloads Latest Stable Version Latest Unstable Version License

Installation

To install through composer, run the following command from terminal:

composer require "laravie/html"

Next, add your new provider to the providers array of config/app.php:

'providers' => [

    // ...

    Collective\Html\HtmlServiceProvider::class,

],

Finally, add two class aliases to the aliases array of config/app.php:

'aliases' => [

    // ...

    'Form' => Collective\Html\FormFacade::class,
    'Html' => Collective\Html\HtmlFacade::class,

],

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.

Opening A Form

Opening A Form

{!! Form::open(['url' => 'foo/bar']) !!}
    //
{!! Form::close() !!}

By default, a POST method will be assumed; however, you are free to specify another method:

echo Form::open(['url' => 'foo/bar', 'method' => 'put'])

Note: Since HTML forms only support POST and GET, PUT and DELETE 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:

echo Form::open(['route' => 'route.name'])

echo Form::open(['action' => 'Controller@method'])

You may pass in route parameters as well:

echo Form::open(['route' => ['route.name', $user->id]])

echo Form::open(['action' => ['Controller@method', $user->id]])

If your form is going to accept file uploads, add a files option to your array:

echo Form::open(['url' => 'foo/bar', 'files' => true])

CSRF Protection

Adding The CSRF Token To A 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:

echo Form::token();

Attaching The CSRF Filter To A Route

Route::post('profile', ['before' => 'csrf', function() {
    //
}]);

Form Model Binding

Opening A Model Form

Often, you will want to populate a form based on the contents of a model. To do so, use the Form::model method:

echo 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:

  1. Session Flash Data (Old Input)
  2. Explicitly Passed Value
  3. 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 with Form::close!

Form Model Accessors

Laravel's Eloquent Accessor 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.

Labels

Generating A Label Element

echo Form::label('email', 'E-Mail Address');

Specifying Extra HTML Attributes

echo 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.

Text, Text Area, Password & Hidden Fields

Generating A Text Input

echo Form::text('username');

Specifying A Default Value

echo Form::text('email', '[email protected]');

Note: The hidden and textarea methods have the same signature as the text method.

Generating A Password Input

echo Form::password('password', ['class' => 'awesome']);

Generating Other Inputs

echo Form::email($name, $value = null, $attributes = []);
echo Form::file($name, $attributes = []);

Checkboxes and Radio Buttons

Generating A Checkbox Or Radio Input

echo Form::checkbox('name', 'value');

echo Form::radio('name', 'value');

Generating A Checkbox Or Radio Input That Is Checked

echo Form::checkbox('name', 'value', true);

echo Form::radio('name', 'value', true);

Number

Generating A Number Input

echo Form::number('name', 'value');

Date

Generating A Date Input

echo Form::date('name', \Carbon\Carbon::now());

File Input

Generating A File Input

echo Form::file('image');

Note: The form must have been opened with the files option set to true.

Drop-Down Lists

Generating A Drop-Down List

echo Form::select('size', ['L' => 'Large', 'S' => 'Small']);

Generating A Drop-Down List With Selected Default

echo Form::select('size', ['L' => 'Large', 'S' => 'Small'], 'S');

Generating a Drop-Down List With an Empty Placeholder

This will create an <option> element with no value as the very first option of your drop-down.

echo Form::select('size', ['L' => 'Large', 'S' => 'Small'], null, ['placeholder' => 'Pick a size...']);

Generating A Grouped List

echo Form::select('animal', [
    'Cats' => ['leopard' => 'Leopard'],
    'Dogs' => ['spaniel' => 'Spaniel'],
]);

Generating A Drop-Down List With A Range

echo Form::selectRange('number', 10, 20);

Generating A List With Month Names

echo Form::selectMonth('month');

Buttons

Generating A Submit Button

echo Form::submit('Click Me!');

Generating A Button

echo Form::button('Click Me!');

Note: Default value for third parameter is true. As default, any value that you pass will be escaped.

echo Form::button('<i class="fa fa-trash><i> Destroy"', ['class' => 'btn btn-danger'], false);

Custom Macros

Registering A Form Macro

It's easy to define your own custom Form class helpers called "macros". Here's how it works. First, simply register the macro with a given name and a Closure:

Form::macro('myField', function() {
    return '<input type="awesome">';
});

Now you can call your macro using its name:

Calling A Custom Form Macro

echo Form::myField();

##Custom Components

Registering A Custom Component

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 a Service Provider's boot method.

Form::component('bsText', 'components.form.text', ['name', 'value', 'attributes']);

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>

Custom Components can also be created on the Html facade in the same fashion as on the Form facade.

Providing Default Values

When defining your Custom Component's method signature, you can provide default values simply by giving your array items values, like so:

Form::component('bsText', 'components.form.text', ['name', 'value' => null, 'attributes' => []]);

Calling A Custom Form Component

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>

##Generating URLs

link_to

Generate a HTML link to the given URL.

echo link_to('foo/bar', $title = null, $attributes = [], $secure = null);

link_to_asset

Generate a HTML link to the given asset.

echo link_to_asset('foo/bar.zip', $title = null, $attributes = [], $secure = null);

link_to_route

Generate a HTML link to the given named route.

echo link_to_route('route.name', $title = null, $parameters = [], $attributes = []);

link_to_action

Generate a HTML link to the given controller action.

echo link_to_action('HomeController@getIndex', $title = null, $parameters = [], $attributes = []);

html's People

Contributors

adambant avatar adamgoose avatar alexandre-butynski avatar anahkiasen avatar andersonfriaca avatar barryvdh avatar crynobone avatar darthrevan13 avatar devinfd avatar franzliedke avatar grahamcampbell avatar greggilbert avatar jackmcdade avatar lanort avatar lucasmichot avatar mlantz avatar mul14 avatar nickurt avatar patrickbrouwers avatar pjona avatar ranabd36 avatar robinmalfait avatar taylorotwell avatar thujohn avatar tortuetorche avatar tshafer avatar vendin avatar vinceg avatar vlakoff avatar yajra avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

html's Issues

Form model binding not working in blade components

Form model binding not working in blade components

Form model binding is not working when you create a form component:

@component('components.form', ['model' => $product ?? null, 'route' => 'products'])
  @component('components.form-group', ['name' => 'name', 'label' => 'Product name:'])
    {!! Form::text('name', null, ['class' => 'form-control']) !!}
  @endcomponent
@endcomponent

And components/form.blade.php looks like this:

{!! Form::model($model, ['method' => 'PATCH', 'route' => [$route . '.update', $model->id]]) !!}
  {!! $slot !!}
{!! Form::close() !!}

In this case the field values are not populating (the attributes are exist in the $model object). When I use Form::model() just where I make the fields, it's working fine. If I @include the form opener part, it's also working fine.

Thank you.

Trait Componentable missing a use statement

When using renderComponent, it tries to return an instance that implements "Htmlable".
But since it is not aliased, an ErrorException is thrown:

Type error: Return value of Collective\Html\FormBuilder::renderComponent() must be an instance of Collective\Html\Htmlable, instance of Illuminate\Support\HtmlString returned

After adding

use Illuminate\Contracts\Support\Htmlable;

into src/Componentable.php, the problem disappears as expected.

Laravel 9 compatibility

  • Package Version: dev-master
  • Laravel Version: 9
  • PHP Version: 8.1

Description:

Hello,

I try to install the library on Laravel 9 but I have the following errors:

Problem 1
    - illuminate/view[v7.0.0, ..., v7.28.4] require php ^7.2.5 -> your php version (8.1.0) does not satisfy that requirement.
    - illuminate/view[v8.0.0, ..., v8.11.2] require php ^7.3 -> your php version (8.1.0) does not satisfy that requirement.
    - Root composer.json requires laravie/html dev-master -> satisfiable by laravie/html[dev-master].
    - Conclusion: don't install laravel/framework v9.3.0 (conflict analysis result)
    - Conclusion: don't install laravel/framework v9.3.1 (conflict analysis result)
    - Conclusion: don't install laravel/framework v9.2.0 (conflict analysis result)
    - laravie/html dev-master requires illuminate/view ^7.0 || ^8.0 -> satisfiable by illuminate/view[v7.0.0, ..., 7.x-dev, v8.0.0, ..., 8.x-dev].
    - Only one of these can be installed: illuminate/view[v7.0.0, ..., 7.x-dev, v8.0.0, ..., 8.x-dev], laravel/framework[v9.2.0, v9.3.0, v9.3.1, 9.x-dev]. laravel/framework replaces illuminate/view and thus cannot coexist with it.
    - Root composer.json requires laravel/framework ^9.2 -> satisfiable by laravel/framework[v9.2.0, v9.3.0, v9.3.1, 9.x-dev].

Can you update your library for Laravel 9?

Thank you!

Selection selected ignores Collection class

Hey,

Seems like there is a bug with the the following method:

https://github.com/laravie/html/blob/master/src/Concerns/Selection.php#L203

Assuming the following code as an example.

getSelectedValue(1, collect([1,2,3]))

the first lines in the method mentioned above will kick in for arrays as well as collections since Collection implements Arrayable.

the code

} elseif ($selected instanceof Collection) {
            return $selected->contains($value) ? 'selected' : null;
        }

never executes for Collections.

The following seems to work

/**
     * Determine if the value is selected.
     *
     * @param  string|null $value
     * @param  string|iterable|null  $selected
     *
     * @return string|null
     */
    protected function getSelectedValue(?string $value, $selected): ?string
    {
        if ($selected instanceof Collection) {
            return $selected->contains($value) ? 'selected' : null;
        } elseif ($selected instanceof Arrayable) {
            $selected = $selected->toArray();
        }

        if (is_array($selected)) {
            return in_array($value, $selected, true) || in_array((string) $value, $selected, true)
                        ? 'selected'
                        : null;
        }

        return ((string) $value === (string) $selected) ? 'selected' : null;
    }

trait FormAccessible bug ? (version 5.8.2)

Hi there,
This is probably just a misunderstanding of my part but there's something strange related to the FormAccessible trait when dealing with relations.

First of all, is this trait supposed to be dealing with relations ? Or is the developer expected to write form mutators for relations ? If so, just ignore this :)

So I've got this model that defines a relation :

class Content {

    use FormAccessible;

    public function content_type()
    {
        return $this->belongsTo(ContentType::class);
    }
}

if I call $content->getFormValue('content_type') it returns null, because :
1 - there is no form mutator for content_type in this model
2 -The FormAccessible trait sees 'content_type' as a nested key and forward the call like so :
return \data_get($relatedModel, empty($key) ? null : $key); with, in this case, $relatedModel being a ContentType object and $key being still 'content_type'.
Obviously there is no 'content_type' attribute on the ContentType object.

Moreover, if I call $content->getFormValue('content_type.id') it's searching for a form mutator in ContentType called formContentType.idAttribute on the ContentType object, which isn't a valid php method name.

Wouldn't it make more sense to return the ContentType object when there is no form mutator in that object, or even better the key of the relation if the key isn't a nested key ?

So it would do :

$content->getFormValue('content_type'); //returns the primary key of the ContentType object
$content->getFormValue('content_type.name'); //returns a string or the result of the method formNameAttribute of the ContentType object

What do you think ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.