1348 lines
27 KiB
PHP
Executable File
1348 lines
27 KiB
PHP
Executable File
<?php
|
|
|
|
namespace Dcat\Admin\Form;
|
|
|
|
use Dcat\Admin\Admin;
|
|
use Dcat\Admin\Form;
|
|
use Dcat\Admin\Support\Helper;
|
|
use Dcat\Admin\Traits\HasBuilderEvents;
|
|
use Dcat\Admin\Traits\HasVariables;
|
|
use Dcat\Admin\Widgets\Form as WidgetForm;
|
|
use Illuminate\Contracts\Support\Arrayable;
|
|
use Illuminate\Contracts\Support\Renderable;
|
|
use Illuminate\Support\Arr;
|
|
use Illuminate\Support\Fluent;
|
|
use Illuminate\Support\Str;
|
|
use Illuminate\Support\Traits\Macroable;
|
|
|
|
/**
|
|
* Class Field.
|
|
*/
|
|
class Field implements Renderable
|
|
{
|
|
use Macroable;
|
|
use Form\Concerns\HasFieldValidator;
|
|
use HasBuilderEvents;
|
|
use HasVariables;
|
|
|
|
const FILE_DELETE_FLAG = '_file_del_';
|
|
|
|
const FIELD_CLASS_PREFIX = 'field_';
|
|
|
|
const BUILD_IGNORE = 'build-ignore';
|
|
|
|
const NORMAL_CLASS = '_normal_';
|
|
|
|
/**
|
|
* Element value.
|
|
*
|
|
* @var mixed
|
|
*/
|
|
protected $value;
|
|
|
|
/**
|
|
* Data of all original columns of value.
|
|
*
|
|
* @var mixed
|
|
*/
|
|
protected $data;
|
|
|
|
/**
|
|
* Field original value.
|
|
*
|
|
* @var mixed
|
|
*/
|
|
protected $original;
|
|
|
|
/**
|
|
* Field default value.
|
|
*
|
|
* @var mixed
|
|
*/
|
|
protected $default;
|
|
|
|
/**
|
|
* @var bool
|
|
*/
|
|
protected $allowDefaultValueInEditPage = false;
|
|
|
|
/**
|
|
* Element label.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $label = '';
|
|
|
|
/**
|
|
* Column name.
|
|
*
|
|
* @var string|array
|
|
*/
|
|
protected $column = '';
|
|
|
|
/**
|
|
* Form element name.
|
|
*
|
|
* @var string|array
|
|
*/
|
|
protected $elementName = [];
|
|
|
|
/**
|
|
* Form element classes.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $elementClass = [];
|
|
|
|
/**
|
|
* Options for specify elements.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $options = [];
|
|
|
|
/**
|
|
* Checked for specify elements.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $checked = [];
|
|
|
|
/**
|
|
* Css required by this field.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected static $css = [];
|
|
|
|
/**
|
|
* Js required by this field.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected static $js = [];
|
|
|
|
/**
|
|
* Script for field.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $script = '';
|
|
|
|
/**
|
|
* Element attributes.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $attributes = ['autocomplete' => 'off'];
|
|
|
|
/**
|
|
* Parent form.
|
|
*
|
|
* @var Form|WidgetForm
|
|
*/
|
|
protected $form;
|
|
|
|
/**
|
|
* @var WidgetForm
|
|
*/
|
|
protected $parent;
|
|
|
|
/**
|
|
* View for field to render.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $view = '';
|
|
|
|
/**
|
|
* Help block.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $help = [];
|
|
|
|
/**
|
|
* Key for errors.
|
|
*
|
|
* @var string|array
|
|
*/
|
|
protected $errorKey;
|
|
|
|
/**
|
|
* Placeholder for this field.
|
|
*
|
|
* @var string|array
|
|
*/
|
|
protected $placeholder;
|
|
|
|
/**
|
|
* Width for label and field.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $width = [
|
|
'label' => 2,
|
|
'field' => 8,
|
|
];
|
|
|
|
/**
|
|
* If the form horizontal layout.
|
|
*
|
|
* @var bool
|
|
*/
|
|
protected $horizontal = true;
|
|
|
|
/**
|
|
* column data format.
|
|
*
|
|
* @var \Closure
|
|
*/
|
|
protected $customFormat = null;
|
|
|
|
/**
|
|
* @var bool
|
|
*/
|
|
protected $display = true;
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $labelClass = ['text-capitalize'];
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $fieldClass = [];
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $formGroupClass = ['form-field'];
|
|
|
|
/**
|
|
* @var \Closure[]
|
|
*/
|
|
protected $savingCallbacks = [];
|
|
|
|
/**
|
|
* Field constructor.
|
|
*
|
|
* @param string|array $column
|
|
* @param array $arguments
|
|
*/
|
|
public function __construct($column, $arguments = [])
|
|
{
|
|
$this->column = $column;
|
|
$this->label = $this->formatLabel($arguments);
|
|
|
|
$this->callResolving();
|
|
}
|
|
|
|
/**
|
|
* @param array $options
|
|
* @return $this
|
|
*/
|
|
public function setRelation(array $options = [])
|
|
{
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Format the label value.
|
|
*
|
|
* @param array $arguments
|
|
* @return string
|
|
*/
|
|
protected function formatLabel($arguments = [])
|
|
{
|
|
if (isset($arguments[0])) {
|
|
return $arguments[0];
|
|
}
|
|
|
|
$column = is_array($this->column) ? current($this->column) : $this->column;
|
|
|
|
return str_replace('_', ' ', admin_trans_field($column));
|
|
}
|
|
|
|
/**
|
|
* Format the name of the field.
|
|
*
|
|
* @param string $column
|
|
* @return array|mixed|string
|
|
*/
|
|
protected function formatName($column)
|
|
{
|
|
return Helper::formatElementName($column);
|
|
}
|
|
|
|
/**
|
|
* Set form element name.
|
|
*
|
|
* @param string|array $name
|
|
* @return $this
|
|
*
|
|
* @author Edwin Hui
|
|
*/
|
|
public function setElementName($name)
|
|
{
|
|
$this->elementName = $name;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get form element name.
|
|
*
|
|
* @return array|mixed|string
|
|
*/
|
|
public function getElementName()
|
|
{
|
|
return $this->elementName ?: $this->formatName($this->column);
|
|
}
|
|
|
|
/**
|
|
* Fill data to the field.
|
|
*
|
|
* @param array $data
|
|
* @return void
|
|
*/
|
|
public function fill($data)
|
|
{
|
|
$data = Helper::array($data);
|
|
|
|
$this->data($data);
|
|
|
|
$this->value = $this->formatFieldData($data);
|
|
|
|
$this->callCustomFormatter();
|
|
}
|
|
|
|
/**
|
|
* Format field data.
|
|
*
|
|
* @param array $data
|
|
* @return mixed
|
|
*/
|
|
protected function formatFieldData($data)
|
|
{
|
|
if (is_array($this->column)) {
|
|
$value = [];
|
|
|
|
foreach ($this->column as $key => $column) {
|
|
$value[$key] = $this->getValueFromData($data, $this->normalizeColumn($column));
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
return $this->getValueFromData($data, null, $this->value);
|
|
}
|
|
|
|
/**
|
|
* @param array $data
|
|
* @param string $column
|
|
* @param mixed $default
|
|
* @return mixed
|
|
*/
|
|
protected function getValueFromData($data, $column = null, $default = null)
|
|
{
|
|
$column = $column ?: $this->normalizeColumn();
|
|
|
|
if (Arr::has($data, $column)) {
|
|
return Arr::get($data, $column, $default);
|
|
}
|
|
|
|
return Arr::get($data, Str::snake($column), $default);
|
|
}
|
|
|
|
protected function normalizeColumn(?string $column = null)
|
|
{
|
|
return str_replace('->', '.', $column ?: $this->column);
|
|
}
|
|
|
|
/**
|
|
* custom format form column data when edit.
|
|
*
|
|
* @param \Closure $call
|
|
* @return $this
|
|
*/
|
|
public function customFormat(\Closure $call)
|
|
{
|
|
$this->customFormat = $call;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set original value to the field.
|
|
*
|
|
* @param array $data
|
|
* @return void
|
|
*/
|
|
final public function setOriginal($data)
|
|
{
|
|
$data = Helper::array($data);
|
|
|
|
$this->original = $this->formatFieldData($data);
|
|
|
|
$this->callCustomFormatter('original', new Fluent($data));
|
|
}
|
|
|
|
/**
|
|
* @param string $key
|
|
* @param Fluent|null $dataremoveField
|
|
*/
|
|
protected function callCustomFormatter($key = 'value', Fluent $data = null)
|
|
{
|
|
if ($this->customFormat) {
|
|
$this->{$key} = $this->customFormat
|
|
->call(
|
|
$data ?: $this->data(),
|
|
$this->{$key},
|
|
$this->column,
|
|
$this
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param Form|WidgetForm $form
|
|
* @return $this
|
|
*/
|
|
public function setForm($form = null)
|
|
{
|
|
$this->form = $form;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param WidgetForm $form
|
|
* @return $this
|
|
*/
|
|
public function setParent($form = null)
|
|
{
|
|
$this->parent = $form;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return Fluent|\Illuminate\Database\Eloquent\Model
|
|
*/
|
|
public function values()
|
|
{
|
|
return $this->form ? $this->form->model() : new Fluent();
|
|
}
|
|
|
|
/**
|
|
* Set width for field and label.
|
|
*
|
|
* @param int $field
|
|
* @param int $label
|
|
* @return $this
|
|
*/
|
|
public function width($field = 8, $label = 2)
|
|
{
|
|
$this->width = [
|
|
'label' => $label,
|
|
'field' => $field,
|
|
];
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set the field options.
|
|
*
|
|
* @param array $options
|
|
* @return $this
|
|
*/
|
|
public function options($options = [])
|
|
{
|
|
if ($options instanceof \Closure) {
|
|
$options = $options->call($this->data(), $this->value());
|
|
}
|
|
|
|
$this->options = array_merge($this->options, Helper::array($options));
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param array $options
|
|
* @return $this
|
|
*/
|
|
public function replaceOptions($options)
|
|
{
|
|
if ($options instanceof \Closure) {
|
|
$options = $options->call($this->data(), $this->value());
|
|
}
|
|
|
|
$this->options = $options;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param array|Arrayable $options
|
|
* @return $this
|
|
*/
|
|
public function mergeOptions($options)
|
|
{
|
|
return $this->options($options);
|
|
}
|
|
|
|
/**
|
|
* Set the field option checked.
|
|
*
|
|
* @param array $checked
|
|
* @return $this
|
|
*/
|
|
public function checked($checked = [])
|
|
{
|
|
if ($checked instanceof Arrayable) {
|
|
$checked = $checked->toArray();
|
|
}
|
|
|
|
$this->checked = array_merge($this->checked, (array) $checked);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set key for error message.
|
|
*
|
|
* @param string|array $key
|
|
* @return $this
|
|
*/
|
|
public function setErrorKey($key)
|
|
{
|
|
$this->errorKey = $key;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get key for error message.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getErrorKey()
|
|
{
|
|
return $this->errorKey ?: $this->column;
|
|
}
|
|
|
|
/**
|
|
* Set or get value of the field.
|
|
*
|
|
* @param mixed|null $value
|
|
* @return mixed|$this
|
|
*/
|
|
public function value($value = null)
|
|
{
|
|
if (is_null($value)) {
|
|
if (
|
|
$this->value === null
|
|
|| (is_array($this->value) && empty($this->value))
|
|
) {
|
|
return $this->default();
|
|
}
|
|
|
|
return $this->value;
|
|
}
|
|
|
|
$this->value = value($value);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set or get data.
|
|
*
|
|
* @param array $data
|
|
* @return $this|Fluent
|
|
*/
|
|
public function data(array $data = null)
|
|
{
|
|
if (is_null($data)) {
|
|
if (! $this->data || is_array($this->data)) {
|
|
$this->data = new Fluent((array) $this->data);
|
|
}
|
|
|
|
return $this->data;
|
|
}
|
|
|
|
$this->data = new Fluent($data);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get or set default value for field.
|
|
*
|
|
* @param mixed $default
|
|
* @param bool $edit
|
|
* @return $this|mixed
|
|
*/
|
|
public function default($default = null, bool $edit = false)
|
|
{
|
|
if ($default === null) {
|
|
if (
|
|
$this->form
|
|
&& method_exists($this->form, 'isCreating')
|
|
&& ! $this->form->isCreating()
|
|
&& ! $this->allowDefaultValueInEditPage
|
|
) {
|
|
return;
|
|
}
|
|
|
|
if ($this->default instanceof \Closure) {
|
|
$this->default->bindTo($this->data());
|
|
|
|
return call_user_func($this->default, $this->form);
|
|
}
|
|
|
|
return $this->default;
|
|
}
|
|
|
|
$this->default = value($default);
|
|
$this->allowDefaultValueInEditPage = $edit;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set help block for current field.
|
|
*
|
|
* @param string $text
|
|
* @param string $icon
|
|
* @return $this
|
|
*/
|
|
public function help($text = '', $icon = 'feather icon-help-circle')
|
|
{
|
|
$this->help = compact('text', 'icon');
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get column of the field.
|
|
*
|
|
* @return string|array
|
|
*/
|
|
public function column()
|
|
{
|
|
return $this->column;
|
|
}
|
|
|
|
/**
|
|
* Get or set label of the field.
|
|
*
|
|
* @param mixed|null $label
|
|
* @return $this|string
|
|
*/
|
|
public function label($label = null)
|
|
{
|
|
if ($label == null) {
|
|
return $this->label;
|
|
}
|
|
|
|
if ($label instanceof \Closure) {
|
|
$label = $label($this->label);
|
|
}
|
|
|
|
$this->label = $label;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get original value of the field.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function original()
|
|
{
|
|
return $this->original;
|
|
}
|
|
|
|
/**
|
|
* Sanitize input data.
|
|
*
|
|
* @param array $input
|
|
* @param string $column
|
|
* @return array
|
|
*/
|
|
protected function sanitizeInput($input, $column)
|
|
{
|
|
if ($this instanceof Field\MultipleSelect) {
|
|
$value = Arr::get($input, $column);
|
|
Arr::set($input, $column, array_filter($value));
|
|
}
|
|
|
|
return $input;
|
|
}
|
|
|
|
/**
|
|
* Add html attributes to elements.
|
|
*
|
|
* @param array|string $attribute
|
|
* @param mixed $value
|
|
* @return $this
|
|
*/
|
|
public function attribute($attribute, $value = null)
|
|
{
|
|
if (is_array($attribute)) {
|
|
$this->attributes = array_merge($this->attributes, $attribute);
|
|
} else {
|
|
$this->attributes[$attribute] = (string) $value;
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param string $key
|
|
* @return bool
|
|
*/
|
|
public function hasAttribute(string $key)
|
|
{
|
|
return array_key_exists($key, $this->attributes);
|
|
}
|
|
|
|
/**
|
|
* @param string $key
|
|
* @return mixed|null
|
|
*/
|
|
public function getAttribute(string $key)
|
|
{
|
|
return $this->attributes[$key] ?? null;
|
|
}
|
|
|
|
/**
|
|
* Specifies a regular expression against which to validate the value of the input.
|
|
*
|
|
* @param string $error
|
|
* @param string $regexp
|
|
* @return $this
|
|
*/
|
|
public function pattern($regexp, $error = null)
|
|
{
|
|
if ($error) {
|
|
$this->attribute('data-pattern-error', $error);
|
|
}
|
|
|
|
return $this->attribute('pattern', $regexp);
|
|
}
|
|
|
|
/**
|
|
* set the input filed required.
|
|
*
|
|
* @param bool $isLabelAsterisked
|
|
* @return $this
|
|
*/
|
|
public function required($isLabelAsterisked = true)
|
|
{
|
|
if ($isLabelAsterisked) {
|
|
$this->setLabelClass(['asterisk']);
|
|
}
|
|
|
|
$this->rules('required');
|
|
|
|
return $this->attribute('required', true);
|
|
}
|
|
|
|
/**
|
|
* Set the field automatically get focus.
|
|
*
|
|
* @param bool $value
|
|
* @return $this
|
|
*/
|
|
public function autofocus(bool $value = true)
|
|
{
|
|
return $this->attribute('autofocus', $value);
|
|
}
|
|
|
|
/**
|
|
* Set the field as readonly mode.
|
|
*
|
|
* @param bool $value
|
|
* @return $this
|
|
*/
|
|
public function readOnly(bool $value = true)
|
|
{
|
|
if (! $value) {
|
|
unset($this->attributes['readonly']);
|
|
|
|
return $this;
|
|
}
|
|
|
|
return $this->attribute('readonly', $value);
|
|
}
|
|
|
|
/**
|
|
* Set field as disabled.
|
|
*
|
|
* @param bool $value
|
|
* @return $this
|
|
*/
|
|
public function disable(bool $value = true)
|
|
{
|
|
if (! $value) {
|
|
unset($this->attributes['disabled']);
|
|
|
|
return $this;
|
|
}
|
|
|
|
return $this->attribute('disabled', $value);
|
|
}
|
|
|
|
/**
|
|
* Get or set field placeholder.
|
|
*
|
|
* @param string $placeholder
|
|
* @return $this|string
|
|
*/
|
|
public function placeholder($placeholder = null)
|
|
{
|
|
if ($placeholder === null) {
|
|
return $this->placeholder ?: $this->defaultPlaceholder();
|
|
}
|
|
|
|
$this->placeholder = $placeholder;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
protected function defaultPlaceholder()
|
|
{
|
|
return trans('admin.input').' '.$this->label;
|
|
}
|
|
|
|
/**
|
|
* @param mixed $value
|
|
* @return mixed
|
|
*/
|
|
protected function prepareInputValue($value)
|
|
{
|
|
return $value;
|
|
}
|
|
|
|
/**
|
|
* @param \Closure $closure
|
|
* @return $this
|
|
*/
|
|
public function saving(\Closure $closure)
|
|
{
|
|
$this->savingCallbacks[] = $closure;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Prepare for a field value before update or insert.
|
|
*
|
|
* @param mixed $value
|
|
* @return mixed
|
|
*/
|
|
final public function prepare($value)
|
|
{
|
|
$value = $this->prepareInputValue($value);
|
|
|
|
if ($this->savingCallbacks) {
|
|
foreach ($this->savingCallbacks as $callback) {
|
|
$value = $callback->call($this->data(), $value);
|
|
}
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
/**
|
|
* Format the field attributes.
|
|
*
|
|
* @return string
|
|
*/
|
|
protected function formatAttributes()
|
|
{
|
|
$html = [];
|
|
|
|
foreach ($this->attributes as $name => $value) {
|
|
$html[] = $name.'="'.e($value).'"';
|
|
}
|
|
|
|
return implode(' ', $html);
|
|
}
|
|
|
|
/**
|
|
* @param bool $value
|
|
* @return $this
|
|
*/
|
|
public function horizontal(bool $value = true)
|
|
{
|
|
$this->horizontal = $value;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function getViewElementClasses()
|
|
{
|
|
if ($this->horizontal) {
|
|
return [
|
|
'label' => "col-md-{$this->width['label']} {$this->getLabelClass()}",
|
|
'field' => "col-md-{$this->width['field']} {$this->getFieldClass()}",
|
|
'form-group' => "form-group row {$this->getFormGroupClass()}",
|
|
];
|
|
}
|
|
|
|
return [
|
|
'label' => $this->getLabelClass(),
|
|
'field' => $this->getFieldClass(),
|
|
'form-group' => $this->getFormGroupClass(),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Set element class.
|
|
*
|
|
* @param string|array $class
|
|
* @param bool $normalize
|
|
* @return $this
|
|
*/
|
|
public function setElementClass($class, bool $normalize = true)
|
|
{
|
|
if ($normalize) {
|
|
$class = $this->normalizeElementClass($class);
|
|
}
|
|
|
|
$this->elementClass = array_merge($this->elementClass, (array) $class);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Add element class.
|
|
*
|
|
* @param string|array $class
|
|
* @param bool $normalize
|
|
* @return $this
|
|
*/
|
|
public function addElementClass($class, bool $normalize = false)
|
|
{
|
|
$this->setElementClass($class, $normalize);
|
|
|
|
$this->elementClass = array_values(array_unique(array_merge($this->elementClass, $this->getDefaultElementClass())));
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get element class.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getElementClass()
|
|
{
|
|
if (! $this->elementClass) {
|
|
$this->elementClass = $this->getDefaultElementClass();
|
|
}
|
|
|
|
return $this->elementClass;
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
protected function getDefaultElementClass()
|
|
{
|
|
return array_merge($this->normalizeElementClass((array) $this->getElementName()), [static::NORMAL_CLASS]);
|
|
}
|
|
|
|
/**
|
|
* @param string|array $class
|
|
* @return array|string
|
|
*/
|
|
public function normalizeElementClass($class)
|
|
{
|
|
if (is_array($class)) {
|
|
return array_map([$this, 'normalizeElementClass'], $class);
|
|
}
|
|
|
|
return static::FIELD_CLASS_PREFIX.str_replace(['[', ']', '->', '.'], '_', $class);
|
|
}
|
|
|
|
/**
|
|
* Get element class selector.
|
|
*
|
|
* @return string|array
|
|
*/
|
|
public function getElementClassSelector()
|
|
{
|
|
$elementClass = $this->getElementClass();
|
|
|
|
$formId = $this->getFormElementId();
|
|
$formId = $formId ? '#'.$formId : '';
|
|
|
|
if (Arr::isAssoc($elementClass)) {
|
|
$classes = [];
|
|
|
|
foreach ($elementClass as $index => $class) {
|
|
$classes[$index] = $formId.' .'.(is_array($class) ? implode('.', $class) : $class);
|
|
}
|
|
|
|
return $classes;
|
|
}
|
|
|
|
return $formId.' .'.implode('.', $elementClass);
|
|
}
|
|
|
|
/**
|
|
* Get element class string.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function getElementClassString()
|
|
{
|
|
$elementClass = $this->getElementClass();
|
|
|
|
if (Arr::isAssoc($elementClass)) {
|
|
$classes = [];
|
|
|
|
foreach ($elementClass as $index => $class) {
|
|
$classes[$index] = is_array($class) ? implode(' ', $class) : $class;
|
|
}
|
|
|
|
return $classes;
|
|
}
|
|
|
|
return implode(' ', $elementClass);
|
|
}
|
|
|
|
/**
|
|
* @return $this
|
|
*/
|
|
public function hideInDialog()
|
|
{
|
|
if (
|
|
$this->form instanceof Form
|
|
&& $this->form->inDialog()
|
|
) {
|
|
$this->display(false);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return string|null
|
|
*/
|
|
protected function getFormElementId()
|
|
{
|
|
return $this->form ? $this->form->getElementId() : null;
|
|
}
|
|
|
|
/**
|
|
* Remove element class.
|
|
*
|
|
* @param $class
|
|
* @return $this
|
|
*/
|
|
public function removeElementClass($class)
|
|
{
|
|
Helper::deleteByValue($this->elementClass, $class);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param array|string $labelClass
|
|
* @param bool $append
|
|
* @return $this
|
|
*/
|
|
public function setLabelClass($labelClass, bool $append = true)
|
|
{
|
|
$this->labelClass = $append
|
|
? array_unique(array_merge($this->labelClass, (array) $labelClass))
|
|
: (array) $labelClass;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getLabelClass()
|
|
{
|
|
return implode(' ', $this->labelClass);
|
|
}
|
|
|
|
/**
|
|
* @param mixed $value
|
|
* @param callable $callback
|
|
* @return $this|mixed
|
|
*/
|
|
public function when($value, $callback)
|
|
{
|
|
if ($value) {
|
|
return $callback($this, $value) ?: $this;
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param string|array $class
|
|
* @param bool $append
|
|
* @return $this
|
|
*/
|
|
public function setFormGroupClass($class, bool $append = true)
|
|
{
|
|
$this->formGroupClass = $append
|
|
? array_unique(array_merge($this->formGroupClass, (array) $class))
|
|
: (array) $class;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getFormGroupClass()
|
|
{
|
|
return implode(' ', $this->formGroupClass);
|
|
}
|
|
|
|
/**
|
|
* @param string|array $class
|
|
* @param bool $append
|
|
* @return $this
|
|
*/
|
|
public function setFieldClass($class, bool $append = true)
|
|
{
|
|
$this->fieldClass = $append
|
|
? array_unique(array_merge($this->fieldClass, (array) $class))
|
|
: (array) $class;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getFieldClass()
|
|
{
|
|
return implode(' ', $this->fieldClass);
|
|
}
|
|
|
|
/**
|
|
* Get the view variables of this field.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function defaultVariables()
|
|
{
|
|
return [
|
|
'name' => $this->getElementName(),
|
|
'help' => $this->help,
|
|
'class' => $this->getElementClassString(),
|
|
'value' => $this->value(),
|
|
'label' => $this->label,
|
|
'viewClass' => $this->getViewElementClasses(),
|
|
'column' => $this->column,
|
|
'errorKey' => $this->getErrorKey(),
|
|
'attributes' => $this->formatAttributes(),
|
|
'placeholder' => $this->placeholder(),
|
|
'disabled' => $this->attributes['disabled'] ?? false,
|
|
'formId' => $this->getFormElementId(),
|
|
'selector' => $this->getElementClassSelector(),
|
|
'options' => $this->options,
|
|
];
|
|
}
|
|
|
|
protected function isCreating()
|
|
{
|
|
return request()->isMethod('POST');
|
|
}
|
|
|
|
protected function isEditing()
|
|
{
|
|
return request()->isMethod('PUT');
|
|
}
|
|
|
|
/**
|
|
* Get view of this field.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function view()
|
|
{
|
|
return $this->view ?: 'admin::form.'.strtolower(class_basename(static::class));
|
|
}
|
|
|
|
/**
|
|
* Set view of current field.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function setView($view)
|
|
{
|
|
$this->view = $view;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get script of current field.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getScript()
|
|
{
|
|
return $this->script;
|
|
}
|
|
|
|
/**
|
|
* Set script of current field.
|
|
*
|
|
* @return self
|
|
*/
|
|
public function script($script)
|
|
{
|
|
$this->script = $script;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* To set this field should render or not.
|
|
*
|
|
* @return self
|
|
*/
|
|
public function display(bool $display)
|
|
{
|
|
$this->display = $display;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* 设置默认属性.
|
|
*
|
|
* @param string $attribute
|
|
* @param mixed $value
|
|
* @return $this
|
|
*/
|
|
public function defaultAttribute(string $attribute, $value)
|
|
{
|
|
if (! array_key_exists($attribute, $this->attributes)) {
|
|
$this->attribute($attribute, $value);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* If this field should render.
|
|
*
|
|
* @return bool
|
|
*/
|
|
protected function shouldRender()
|
|
{
|
|
return $this->display;
|
|
}
|
|
|
|
/**
|
|
* 保存数据为json格式.
|
|
*
|
|
* @param int $option
|
|
* @return $this
|
|
*/
|
|
public function saveAsJson($option = 0)
|
|
{
|
|
return $this->saving(function ($value) use ($option) {
|
|
if ($value === null || is_scalar($value)) {
|
|
return $value;
|
|
}
|
|
|
|
return json_encode($value, $option);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 保存数据为字符串格式.
|
|
*
|
|
* @return $this
|
|
*/
|
|
public function saveAsString()
|
|
{
|
|
return $this->saving(function ($value) {
|
|
if (is_object($value) || is_array($value)) {
|
|
return json_encode($value);
|
|
}
|
|
|
|
return (string) $value;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Collect assets required by this field.
|
|
*/
|
|
public static function requireAssets()
|
|
{
|
|
static::$js && Admin::js(static::$js);
|
|
static::$css && Admin::css(static::$css);
|
|
}
|
|
|
|
/**
|
|
* 设置默认class.
|
|
*/
|
|
protected function setDefaultClass()
|
|
{
|
|
if (is_string($class = $this->getElementClassString())) {
|
|
$this->defaultAttribute('class', $class);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Render this filed.
|
|
*
|
|
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View|string
|
|
*/
|
|
public function render()
|
|
{
|
|
if (! $this->shouldRender()) {
|
|
return '';
|
|
}
|
|
|
|
$this->setDefaultClass();
|
|
|
|
$this->callComposing();
|
|
|
|
$this->withScript();
|
|
|
|
return Admin::view($this->view(), $this->variables());
|
|
}
|
|
|
|
protected function withScript()
|
|
{
|
|
if ($this->script) {
|
|
Admin::script($this->script);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function __toString()
|
|
{
|
|
$view = $this->render();
|
|
|
|
return $view instanceof Renderable ? $view->render() : (string) $view;
|
|
}
|
|
}
|