перейти к части...
Вот пример одного из полей формы из стандартного view login.blade.php
:
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
<label for="email" class="col-md-4 control-label">E-Mail Address</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required autofocus>
@if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
@endif
</div>
</div>
Оно огромно, не правда ли? А представьте, если у вас 5-10 таких полей в одном файле view? Такой код не только выглядит ужасно, его к тому же трудно читать. Чтобы добавить новое поле, вам придется скопировать весь этот блок и изменить имя поля (например, email
на username
) во всех местах, где оно встречается. При этом очень легко допустить ошибку.
Мы не можем что-либо убрать отсюда, так как весь этот код важен для внешнего вида и правильной работы поля. Что мы можем сделать, так это сделать универсальный компонент Blade на его основе этого кода.
Этим и займемся. Давайте создадим папку для компонентов, например resources/views/components/form
. Дальше создадим файл с названием input.blade.php
в этой папке. Скопируйте код выше и вставьте в файл.
Начнем с того, что заменим все вхождения строки email
на $name
. Вот результат:
<div class="form-group{{ $errors->has($name) ? ' has-error' : '' }}">
<label for="{{ $name }}" class="col-md-4 control-label">E-Mail Address</label>
<div class="col-md-6">
<input id="{{ $name }}" type="email" class="form-control" name="{{ $name }}" value="{{ old($name) }}" required autofocus>
@if ($errors->has($name))
<span class="help-block">
<strong>{{ $errors->first($name) }}</strong>
</span>
@endif
</div>
</div>
Далее сделаем заголовок поля label настраиваемым и необязательным:
@if (isset($label))
<label for="{{ $name }}" class="col-md-4 control-label">{{ $label }}</label>
@endif
Тип поля type
для input должен быть изменяемым со значением по-умолчанию равным text
. Атрибут placeholder
не должен быть обязательным. После указанных изменений наш input будет выглядеть так:
<input id="{{ $name }}"
type="{{ $type ?? 'text' }}"
class="form-control"
name="{{ $name }}"
placeholder="{{ $placeholder ?? '' }}"
value="{{ old($name) }}" required autofocus>
Атрибут required autofocus
стоит так же убрать, чтобы поле было еще более универсальным. Вместо этого мы добавим переменную $attributes
, чтобы у пользователя была возможность добавить любые дополнительные атрибуты, какие он захочет.
<input id="{{ $name }}"
type="{{ $type ?? 'text' }}"
class="form-control"
name="{{ $name }}"
placeholder="{{ $placeholder ?? '' }}"
value="{{ old($name) }}"
{{ isset($attributes) ? $attributes : '' }}>
Уже неплохо, но нужно еще поработать над атрибутом value
. Оно будет вытаскивать значение из объекта модели, если он был предоставлен. Это позволит использовать данный Blade компонент (а в конечном итоге и весь view) не только для форм создания сущностей, но и для форм редактирования.
<input id="{{ $name }}"
type="{{ $type ?? 'text' }}"
class="form-control"
name="{{ $name }}"
placeholder="{{ $placeholder ?? '' }}"
value="{{
old($name) ?: (isset($object) ? $object->{$name} : '')
}}"
{{ isset($attributes) ? $attributes : '' }}>
Что мы здесь делаем, так это проверяем если у поля есть old()
значение. Если есть - используем его, если нет - вытаскиваем значение из объекта $object
если он был предоставлен. Если объекта нет, задаем пустую строку.
А вот и конечный результат компонента целиком:
<div class="form-group{{ $errors->has($name) ? ' has-error' : '' }}">
@if (isset($label))
<label for="{{ $name }}" class="col-md-4 control-label">{{ $label }}</label>
@endif
<div class="col-md-6">
<input id="{{ $name }}"
type="{{ $type ?? 'text' }}"
class="form-control"
name="{{ $name }}"
placeholder="{{ $placeholder ?? '' }}"
value="{{
old($name) ?: (isset($object) ? $object->{$name} : '')
}}"
{{ isset($attributes) ? $attributes : '' }}>
@if ($errors->has($name))
<span class="help-block">
<strong>{{ $errors->first($name) }}</strong>
</span>
@endif
</div>
</div>
Вернемся во view login.blade.php
. Теперь мы можем заменить старый блок кода поля email
на это:
@component('components.form.input', [
'name' => 'email',
'label' => 'E-Mail адрес',
])@endcomponent
Код намного меньше, более читаемый, и просто выглядит приятнее, согласитесь?
Еще один пример. Допустим, у нас есть один единственный view edit.blade.php
, который используется и для создания, и для редактирования постов блога. Вам нужно будет передавать объект поста нашему компоненту учитывая то, что на момент создания поста этого объекта у нас не будет и нам нужно будет просто предавать null. Вот как выглядел бы наш компонент во view для поля title
(заголовок поста):
@component('components.form.input', [
'name' => 'title',
'label' => 'Заголовок',
'placeholder' => 'Введите заголовок поста',
'object' => $post ?? null,
])@endcomponent
Заключение
Надеюсь, теперь у вас есть понимание того, как работают компоненты Blade и как их создавать. Вы можете изменить компонент из урока под свои нужды. Также, основываясь на этом компоненте вы запросто сможете создать компоненты для других типов полей, например для textarea
или checkbox
- я оставляю эту задачу вам.
Все материалы на сайте voerro абсолютно бесплатны и написаны автором в свободное от основной работы время. Если уроки сайта оказались для вас полезными, пожалуйста, помогите проекту. Спасибо!