- Text
- Number
- Password
- Hidden
- Date
- Datetime
- Time
- File
- Image
- Images
- Textarea
- Select
- DependentSelect
- Multi Select
- Select Ajax
- Multi Select Ajax
- Wysiwyg
- Ckeditor
- Checkbox
- Radio
- Html
- Custom
- View
- Upload
- API
В качестве элемента формы может выступать любой класс, которые реализует интерфейс Illuminate\Contracts\Support\Renderable
.
Для полноцнной работы класс поля должен реализовать интерфейс SleepingOwl\Admin\Contracts\FormElementInterface
Обычное текстовое поле <input type="text" />
AdminFormElement::text(string $key, string $label = null): static
$key
- Ключ поля$label
- Заголовок
Числовое поле <input type="number" min max step />
AdminFormElement::number(string $key, string $label = null): static
$key
- Ключ поля$label
- Заголовок
Указание минимального допустимого значения
$field->setMin(10);
Указание максимального допустимого значения
$field->setMax(100);
Указание шага
$field->setStep(5);
Поле для ввода пароля <input type="password" />
AdminFormElement::password(string $key, string $label = null): static
$key
- Ключ поля$label
- Заголовок
Если пароль указан для текущего поля, то при валидации будет игнорироваться правило required
Перед сохранением применить к паролю функцию bcrypt
Перед сохранением применить к паролю функцию md5
Перед сохранением применить к паролю функцию sha1
Hidden
AdminFormElement::hidden(string $key): static
$key
- Ключ поля
Поле для ввода даты (использует javascript календарь http://eonasdan.github.io/bootstrap-datetimepicker/)
AdminFormElement::date(string $key, string $label = null): static
$key
- Ключ поля$label
- Заголовок
Указание формата хранения даты в БД (По умолчанию: Y-m-d
)
Указание формата отображения даты в поле (По умолчанию значение из конфига config('sleeping_owl.dateFormat')
)
Установка текущей даты, если значение не указано
Поле для ввода даты и времени (использует javascript календарь http://eonasdan.github.io/bootstrap-datetimepicker/)
AdminFormElement::datetime(string $key, string $label = null): static
$key
- Ключ поля$label
- Заголовок
Указание формата хранения даты в БД (По умолчанию: Y-m-d H:i:s
)
Указание формата отображения даты в поле (По умолчанию значение из конфига config('sleeping_owl.datetimeFormat')
)
Установка текущей даты, если значение не указано
Показывать секунды в поле
Поле для ввода времени (использует javascript календарь http://eonasdan.github.io/bootstrap-datetimepicker/)
AdminFormElement::time(string $key, string $label = null): static
$key
- Ключ поля$label
- Заголовок
Указание формата хранения даты в БД (По умолчанию: H:i:s
)
Указание формата отображения даты в поле (По умолчанию значение из конфига config('sleeping_owl.timeFormat')
)
Поле для загрузки файла. Загрузка файлов происходит через ajax и возвращает строку (относительный путь до файла).
AdminFormElement::file(string $key, string $label = null): static
$key
- Ключ поля$label
- Заголовок
Указание пути сохранения файла ** Путь должен начинаться относительно папки public и не должен содержать название файла!**
В анонимную функцию будет передан объект загружаемого файла \Illuminate\Http\UploadedFile $file
$field->setUploadPath(function(\Illuminate\Http\UploadedFile $file) {
return 'files'; // public/files
});
Имплемент своей логики сохранения и обработки файла
В анонимную функцию будет переданы все параметры обычного сохранения файла
[
\Illuminate\Http\UploadedFile $file
- объект загружаемого файла,
$path
-директория куда якобы должен быть сохранен файл,
$filename
- имя файла якобы сгенерированное самим элементом,
$settings
- опции заданные методом setUploadOptions
]
Все методы сохранения файлов сейчас должны возвращать json объект для двух данных json_encode(['value' => 'тут полная ссылка или относительный path на картинку', 'url' => 'тут только полная ссылка на файл'])
Пример использования
AdminFormElement::images('some_images', "Some Label")->setSaveCallback(function ($file, $path, $filename, $settings) use ($id) {
//Здесь ваша логика на сохранение картинки
$result = $youimage;
return ['path' => $result['url'], 'value' => $result['path|url']];
}),
Способ передачи модели не был найден - потому можно в примере найти use ($id) и использовать в колбеке нахождение модели через ID. Полезно когда нужно сохранить картинку после обработки в отношение с другой моделью. В этом моменте мы и открываем пользователям грань тонкого мышления и обработки фотографий таким образом, какой нужен именно вам. Колбек используется поверх всех сохранений, а значит вызвав его, вы прервете все сохранения на стороне админки. Позже это доработается до принятия некого интерфейса подачи на вход контроллера, класса и возможно целой экосистемы. Всем удачи
Указание имени файла
В анонимную функцию будет передан объект загружаемого файла \Illuminate\Http\UploadedFile $file
$field->setUploadPath(function(\Illuminate\Http\UploadedFile $file) {
return $file->getClientOriginalName().'.'.$file->getClientOriginalExtension();
});
Указание максимального размера загружаемого изображения (в байтах)
Указание минимального размера загружаемого изображения (в байтах)
Загрузка файлов происходит через ajax и возвращает строку (относительный путь до файла).
При загрузке изображений, файлы проходят валидацию image
AdminFormElement::image(string $key, string $label = null): static
$key
- Ключ поля$label
- Заголовок
Для данного поля доступны все методы поля File
Указание настроек для обработки загружаемого изображения.
Для возможности обработки изображений при сохранении вам необходимо подключить пакет intervention/image и добавить сервис провайдер Установить пакет можно помощью командной строки
$ composer require intervention/image
После установки пакета необходимо добавить сервис провайдер
Intervention\Image\ImageServiceProviderLaravel5::class
,
в соответсвующий раздел providers
файла config/app.php
:
После подключения пакета можно использовать фильтры пакета через метод setUploadSettings
.
Пример
$field->setUploadSettings([
'orientate' => [],
'resize' => [1280, null, function ($constraint) {
$constraint->upsize();
$constraint->aspectRatio();
}],
'fit' => [200, 300, function ($constraint) {
$constraint->upsize();
$constraint->aspectRatio();
}]
]);
Ключем массива выступает название фильтра, например resize
, в качестве значения массива передается массив аргументов, которые будут переданы в эту функцию. Т.е. после передачи настроек итератор пройдется по всем элементам массива и сделает вызов call_user_func_array($key, $value)
Наглядный пример
$image = \Intervention\Image\Facades\Image::make($file)
call_user_func_array([$image, 'resize'], [1280, null, function ($constraint) {
$constraint->upsize();
$constraint->aspectRatio();
}])
Загрузка файлов происходит через ajax и возвращает строку (относительный путь до файла).
При загрузке изображений, файлы проходят валидацию image
При сохранении поля в модель передается массив изображений.
AdminFormElement::images(string $key, string $label = null): static
$key
- Ключ поля$label
- Заголовок
Для данного поля доступны все методы поля Image
При сохранении преобразовать массив в json строку
При сохранении преобразовать массив в строку с разделителем ","
Поле для ввода текста <textarea></textarea>
AdminFormElement::textarea(string $key, string $label = null): static
$key
- Ключ поля$label
- Заголовок
Указание кол-ва видимых строк
Поле для выбора значения из выпадающего списка (использует javascript пакет https://select2.github.io/)
AdminFormElement::select(string $key, string $label = null, array|Model|string $options = []): static
$key
- Ключ поля$label
- Заголовок$options
- Данные- При передаче массива, он будет использован в качестве значений
- При передаче объекта модели, будут использованы ее значения
setModelForOptions(string|\Illuminate\Database\Eloquent\Model $model, string $titleKey = null): static
Указание модели в качестве элементов списка
$titleKey
- Смотри методsetDisplay
Указание поля модели, используемого в качестве заголовка
При использовании модели указание списка загружаемых полей в select
$field->setFetchColumns('title');
$field->setFetchColumns(['title']);
$field->setFetchColumns(['title', 'position']);
При использовании модели перед загрузкой списка возможность изменения запроса
В анонимную функцию будут переданы
$element
- текущий объект Select$query
- текущий запрос на получение спсика
$field->setLoadOptionsQueryPreparer(function($element, $query) {
return $query
->where('column', 'value')
->where('owner_id', $element->getModel()->author_id)
})
Указание элементов списка
Указание элементов списка не содержащего ключей (в качестве ключей будут использованы значения массива)
Установка атрибута для сортировки элементов списка по алфавиту (по умолчанию сортировка включена)
Возможность оставлять поле пустым
Исключение из списика элементов
Select Ajax (Отдельная благодарность https://github.com/hkd213)
Поле для выбора значения из выпадающего списка с помощью технологии ajax (использует javascript пакет https://select2.github.io/)
AdminFormElement::selectajax(string $key, string $label = null): static
$key
- Ключ поля$label
- Заголовок$options
- Данные- При передаче объекта модели, будут использованы ее значения
setModelForOptions(string|\Illuminate\Database\Eloquent\Model $model, string $titleKey = null): static
Указание модели в качестве элементов списка
$titleKey
- Смотри методsetDisplay
Указание поля модели, используемого в качестве заголовка.
Поле одновременно играет роль поля источника для запроса
->setDisplay('name')
будет искать в указанной модели по этому полю.
Указание своего собственного источника поиска данных При этом использованный setDisplay будет играть роль ключа в источнике
AdminFormElement::selectajax('name')
->setSearchUrl(
route('name.route')
)
- Если указан кастомный источник то поиск по модели производится не будет
- Если указана модель то поиск будет производиться внутри SleepingOwl
Исключение из списика элементов
MultiSelect Ajax (Отдельная благодарность https://github.com/hkd213)
Поле для выбора множества значений из выпадающего списка с помощью технологии ajax (использует javascript пакет https://select2.github.io/)
AdminFormElement::multiselectajax(string $key, string $label = null): static
$key
- Ключ поля$label
- Заголовок$options
- Данные- При передаче объекта модели, будут использованы ее значения
setModelForOptions(string|\Illuminate\Database\Eloquent\Model $model, string $titleKey = null): static
Указание модели в качестве элементов списка
$titleKey
- Смотри методsetDisplay
Указание поля модели, используемого в качестве заголовка.
Поле одновременно играет роль поля источника для запроса
->setDisplay('name')
будет искать в указанной модели по этому полю.
Указание своего собственного источника поиска данных При этом использованный setDisplay будет играть роль ключа в источнике
AdminFormElement::selectajax('name')
->setSearchUrl(
route('name.route')
)
- Если указан кастомный источник то поиск по модели производится не будет
- Если указана модель то поиск будет производиться внутри SleepingOwl
Исключение из списика элементов
Поле для ввода зависимых значений (использует javascript пакет http://plugins.krajee.com/dependent-dropdown)
AdminFormElement::dependentselect(string $key, string $label = null, array $depends = []): static
$key
- Ключ поля$label
- Заголовок$depends
- (Смотри метод setDataDepends)
Указание ключей полей, при изменении значения в которых производить обновление текущего поля
Указание модели, которая будет использована в качестве элементов списка.
Указание поля модели, используемого в качестве заголовка
Правила фильтрации списка
$field->setLoadOptionsQueryPreparer(function($element, $query) {
// метод getDependValue используется для получения значения связанного поля
// При загрузке формы метод вернет $model->getAttribute($key)
// При выполнении ajax запроса $request->input('depdrop_all_params.{$key}')
return $query->where('country_id', $element->getDependValue('country_id'));
})
AdminFormElement::select('country_id', 'Country')
->setModelForOptions(Country::class, 'title'),
AdminFormElement::dependentselect('city_id', 'City')
->setModelForOptions(\App\Model\City::class, 'title')
->setDataDepends(['country_id'])
->setLoadOptionsQueryPreparer(function($item, $query) {
return $query->where('country_id', $item->getDependValue('country_id'));
})
AdminFormElement::multiselect(string $key, string $label = null, array|Model|string $options = []): static
$key
- Ключ поля$label
- Заголовок$options
- Данные- При передаче массива, он будет использован в качестве значений
- При передаче объекта модели, будут использованы ее значения
Доступны все методы поля Select
Возможность указывать собственные варианты значений
Если значение было ранее выбрано и сейчас убирается из списика, удалить его из БД. (необходимо протестировать)
Добавление поля с визуальным текстовым редактором
AdminFormElement::wysiwyg(string $key, string $label = null, string $editor = null): static
$key
- Ключ поля$label
- Заголовок$editor
- Смотри метод setEditor
Указание поля, где будет храниться преобразованный текст в HTML (Используется для редакторов типа markdown)
Отключить фильтр (При использовании markdown редактора, перед сохранением значения, он его компилирует в HTML)
указание редактора текста (Доступны редакторы ckeditor
, tinymce
, simplemde
)
Указание высоты поля ввода в px
Передача дополнительных настроек в редактор (Будут преобразованы в json)
Алиас для поля Wysiwyg
с подключением редактора ckeditor
AdminFormElement::ckeditor(string $key, string $label = null): static
$key
- Ключ поля$label
- Заголовок
AdminFormElement::checkbox(string $key, string $label = null): static
$key
- Ключ поля$label
- Заголовок
Доступны все методы из поля Select
AdminFormElement::radio(string $key, string $label = null, array|Model|string $options = []): static
$key
- Ключ поля$label
- Заголовок
Поле для вывода обычного HTML кода.
AdminFormElement::custom(Closure $callback = null): static
$callback
- функция, которая будет вызвана при сохранении поля
Функция, которая будет вызвана при сохранении поля
setDisplay(string|Closure|\Illuminate\Contracts\Support\Htmlable|\Illuminate\Contracts\View\View $display)
HTML, который будет выведен в форме
- При передаче объекта
\Illuminate\Contracts\View\View
, в него будет передан объект модели$model
. - При передаче анонимной функции, в нее будет передат первым аргументов объект модели.
$field->setDisplay(function(Model $model) {
return (string);
});
$field->setDisplay(view('app.custom'));
Поле для вывода обычного HTML кода.
Данное поле алиас поля Custom, с передачей через конструктор html в поле setDisplay
AdminFormElement::html(
string|Closure|\Illuminate\Contracts\Support\Htmlable|\Illuminate\Contracts\View\View $html,
Closure $callback = null
): static
$html
- HTML, который будет выведен в форме$callback
- Функция, которая будет вызвана в момент сохранения формы
Поле для вывода view шаблона в качестве элемента формы
Во view шаблон будет передан объект модели $model
AdminFormElement::view(string $view, array $data = [], Closure $callback = null): static
$view
- путь до шаблона$data
- массив который будет передан в шаблон (также туда будет передана модель)$callback
- функция, которая будет вызвана при сохранении поля
Достны все методы поля Custom
Путь до шаблона
Массив который будет передан в шаблон
Поле используется для загрузки файлов на сервер посредством <input type="upload" />
.
При добавлении поля, форма должна автоматически получить html атрибут enctype="multipart/form-data"
.
Если этого не произошло, вы можете добавить атрибут вручную:
return AdminForm::panel()
....
->setHtmlAttribute('enctype', 'multipart/form-data');
Для работы с этим полем существует специальный трейт KodiComponents\Support\Upload
, который поможет с загрузкой прикрепленного файла и сохранением ссылки на него в БД. (При желании данный трейт можно использовать отдельно, используя composer пакет kodicomponents/support
)
Пример использования:
class User extends Model
{
use \KodiComponents\Support\Upload;
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'image' => 'image', // or file | upload
];
}
После добавления трейта в модель необходимо в $casts
указать поля, которые должны работать с файлами. Для файлов необходимо указать тип file
или upload
, для изображений image
. В качестве файла ожидается объект Illuminate\Http\UploadedFile
Если тип файла указан image
, то можно указать правила обработки изображения (Для работы с изображениями используется пакет http://image.intervention.io/)
/**
* @return array
*/
public function getUploadSettings()
{
return [
'image' => [ // Ключ поля
// Название функции, которую необходимо применить к изображению http://image.intervention.io/api/fit и параметры передаваемые в нее
'fit' => [300, 300, function ($constraint) {
$constraint->upsize();
$constraint->aspectRatio();
}],
'crop' => [300, 300], // http://image.intervention.io/api/crop
...
],
'image_small' => [
...
]
];
}
По умолчанию путь сохранения файла: public\storage\{table_name}\{field_name}\{file_name_hash:2chars}\{uniqid}.{ext}
.
При желании можно указать свой формат имени файла
/**
* @param UploadedFile $file
*
* @return string
*/
protected function getUploadFilename(\Illuminate\Http\UploadedFile $file)
{
return md5($this->id).'.'.$file->getClientOriginalExtension();
}
Путь хранения файла пока что изменить невозможно.
В случае если у вас несколько файлов изображений, например, миниатюра и большое изображение и вы хотите загружать их через одно поле, то можно сделать следующим образом:
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'image' => 'image',
'thumb' => 'image',
];
/**
* @return array
*/
public function getUploadSettings()
{
return [
'image' => [
'orientate' => [],
'resize' => [1280, null, function ($constraint) {
$constraint->upsize();
$constraint->aspectRatio();
}]
],
'thumb' => [
'orientate' => [],
'fit' => [200, 300, function ($constraint) {
$constraint->upsize();
$constraint->aspectRatio();
}]
]
];
}
/**
* @param \Illuminate\Http\UploadedFile $file
*/
public function setUploadImageAttribute(\Illuminate\Http\UploadedFile $file = null)
{
if (is_null($file)) {
return;
}
foreach ($this->getUploadFields() as $field) {
$this->{$field.'_file'} = $file;
}
}
И в форме указываем AdminFormElement::upload('upload_image', 'Image')
, т.е. прикрепленный файл через поле с ключем upload_image
будет передан в модель в созданный нами мутатор setUploadImageAttribute
, где файл будет передан в нужные нам поля и сохранен согласно их правилам.
Также для загруженного файла доступны ссылка на файл и абсолюьтный путь. Например рассмотрим поле с ключем image
:
$user->image
public\storage\users\image\23n4b23hj4b.jpg
$user->image_path
\var\www\site.com\public\storage\users\image\23n4b23hj4b.jpg
$user->image_url
http:\\site.com\storage\users\image\23n4b23hj4b.jpg
Данный тип поля поддерживает валидацию загружаемых файлов
- https://laravel.com/docs/5.4/validation#rule-image
- https://laravel.com/docs/5.4/validation#rule-mimetypes
- https://laravel.com/docs/5.4/validation#rule-mimes
AdminFormElement::upload('image', 'Image')->addValidationRule('image')
// or for file
AdminFormElement::upload('pdf', 'PDF')->addValidationRule('mimes:pdf'),
!!!Трейт переопределет методы getAttribute
, mutateAttribute
, setAttribute
, в случае, если они переопределены у вас в модели, могут возникнуть проблемы в работе!!!
Добавление правила валидации
Добавление правил валидации в виде массива
Поле обязательно для заполнения
Поле должно быть уникальным
Изменение сообщения для правила валидации
Указания шаблона для отображения. При передачи пути до шаблона, поиск будет производиться с учетом view namespace sleepingowl::
При передачи объекта \Illuminate\View\View
, в него будут перданы данные поля и произведен вывод
Указание ключа поля.
Указание заголовка поля.
Указание значения по умолчанию
Указание вспомогательного текста
Установка атрибута "только для чтения".
Если поле только для чтения, то оно будет игнорироваться при валидации и сохранении.
Пример
$field->setReadOnly(true);
$field->setReadOnly(function($model) {
return $model->author_id != auth()->id();
});
$field->setReadOnly(function($model) {
return !auth()->check();
});
Установка атрибута пропуска записи значения поля в модель. По умолчанию false
.
Если значение поля должно быть пропущено, то правила валидации будут применены, но в модель значение не установится.
Например, вы хотите чтобы при создании пользователя проверялись соответствия полей password
(пароль) и password_confirmation
(подтверждение), но вам не нужно чтобы поле password_confirmation
записывалось в модель:
AdminFormElement::text('password', 'Password')->required();
AdminFormElement::text('password_confirmation', 'Password confirmation')
->setValueSkipped(true)
->required()
->addValidationRule('same:password', 'Passwords must match!');
Указания условия видимости поля (LaravelRUS/SleepingOwlAdmin#377)
Если поле скрыто, то оно будет игнорироваться при валидации и сохранении.
Пример
$field->setVisibilityCondition(function($model) {
return auth()->user()->isAdmin();
});
$field->setVisibilityCondition(function($model) {
return $model->author_id == auth()->id();
});
Изменение значения поля перед передачей в модель
Пример
$field->mutateValue(function($value) {
return bcrypt($value);
})
Для каждого элемента формы AdminFormElement
можно указывать павила валидации.
Пример
AdminFormElement::text('title', 'Title')
->required()
->unique();
Если вы хотите переопределить стандартное сообщение для правила, вы можете воспользоваться одним из сопособов:
AdminFormElement::text('title', 'Title')
->required('Поле обязательно для заполнения')
->unique('Поле должно содержать уникальное значение')
// Или
AdminFormElement::text('title', 'Title')
->addValidationRule('required', 'Поле обязательно для заполнения')
->addValidationRule('number', 'Поле должно быть числом');
// Или
AdminFormElement::text('title', 'Title')
->required()
->addValidationMessage('required', 'Поле обязательно для заполнения');