true, 'submit' => true]; /** * @var bool */ protected $useFormTag = true; /** * @var string */ protected $elementId; /** * @var array */ protected $width = [ 'label' => 2, 'field' => 8, ]; /** * @var array */ protected $confirm = []; /** * Form constructor. * * @param array $data * @param mixed $key */ public function __construct($data = [], $key = null) { if ($data) { $this->fill($data); } $this->setKey($key); $this->setUp(); } protected function setUp() { $this->initFields(); $this->initFormAttributes(); $this->initCurrentUrl(); $this->initPayload(); } /** * Initialize the form fields. */ protected function initFields() { $this->fields = new Collection(); } /** * Initialize the form attributes. */ protected function initFormAttributes() { $this->setHtmlAttribute([ 'method' => 'POST', 'action' => '', 'class' => 'form-horizontal', 'accept-charset' => 'UTF-8', 'pjax-container' => true, ]); } protected function initCurrentUrl() { if ($this instanceof LazyRenderable) { $this->setCurrentUrl($this->getCurrentUrl()); } } protected function initPayload() { if ($payload = \request(static::LAZY_PAYLOAD_NAME)) { $this->payload(json_decode($payload, true) ?? []); } } /** * Action uri of the form. * * @param string $action * * @return $this|string */ public function action($action = null) { if ($action === null) { return $this->getHtmlAttribute('action'); } return $this->setHtmlAttribute('action', admin_url($action)); } /** * Method of the form. * * @param string $method * * @return $this */ public function method(string $method = 'POST') { return $this->setHtmlAttribute('method', strtoupper($method)); } /** * @param string $title * @param string $content * * @return $this */ public function confirm(?string $title = null, ?string $content = null) { $this->confirm['title'] = $title; $this->confirm['content'] = $content; return $this; } /** * Set primary key. * * @param mixed $value * * @return $this */ public function setKey($value) { $this->primaryKey = $value; return $this; } /** * Get primary key. * * @return mixed */ public function getKey() { return $this->primaryKey; } /** * @param array|Arrayable|Closure $data * * @return Fluent */ public function data() { if (! $this->data) { $this->fill([]); } return $this->data; } /** * @param array|Arrayable|Closure $data * * @return $this */ public function fill($data) { $this->data = new Fluent(Helper::array($data)); return $this; } /** * @return Fluent */ public function model() { return $this->data(); } /** * Add a fieldset to form. * * @param string $title * @param Closure $setCallback * * @return Field\Fieldset */ public function fieldset(string $title, Closure $setCallback) { $fieldset = new Field\Fieldset(); $this->html($fieldset->start($title))->plain(); $setCallback($this); $this->html($fieldset->end())->plain(); return $fieldset; } /** * Get specify field. * * @param string|Field $name * * @return Field|null */ public function field($name) { foreach ($this->fields as $field) { if (is_array($field->column())) { return in_array($name, $field->column(), true) ? $field : null; } if ($field === $name || $field->column() === $name) { return $field; } } } /** * @return Field[]|Collection */ public function fields() { return $this->fields; } /** * Validate this form fields. * * @param Request $request * * @return bool|MessageBag */ public function validate(Request $request) { $failedValidators = []; /** @var \Dcat\Admin\Form\Field $field */ foreach ($this->fields() as $field) { if (! $validator = $field->getValidator($request->all())) { continue; } if (($validator instanceof Validator) && ! $validator->passes()) { $failedValidators[] = $validator; } } $message = $this->mergeValidationMessages($failedValidators); return $message->any() ? $message : false; } /** * Merge validation messages from input validators. * * @param \Illuminate\Validation\Validator[] $validators * * @return MessageBag */ protected function mergeValidationMessages($validators) { $messageBag = new MessageBag(); foreach ($validators as $validator) { $messageBag = $messageBag->merge($validator->messages()); } return $messageBag; } /** * Disable Pjax. * * @return $this */ public function disablePjax() { $this->forgetHtmlAttribute('pjax-container'); return $this; } /** * Disable form tag. * * @return $this; */ public function disableFormTag() { $this->useFormTag = false; return $this; } /** * Disable reset button. * * @param bool $value * * @return $this */ public function disableResetButton(bool $value = true) { $this->buttons['reset'] = ! $value; return $this; } /** * Disable submit button. * * @param bool $value * * @return $this */ public function disableSubmitButton(bool $value = true) { $this->buttons['submit'] = ! $value; return $this; } /** * Set field and label width in current form. * * @param int $fieldWidth * @param int $labelWidth * * @return $this */ public function width($fieldWidth = 8, $labelWidth = 2) { $this->width = [ 'label' => $labelWidth, 'field' => $fieldWidth, ]; $this->fields->each(function ($field) use ($fieldWidth, $labelWidth) { /* @var Field $field */ $field->width($fieldWidth, $labelWidth); }); return $this; } /** * Find field class with given name. * * @param string $method * * @return bool|string */ public static function findFieldClass($method) { $class = Arr::get(\Dcat\Admin\Form::extensions(), $method); if (class_exists($class)) { return $class; } return false; } /** * Add a form field to form. * * @param Field $field * * @return $this */ public function pushField(Field $field) { $this->fields->push($field); if ($this->layout()->hasColumns()) { $this->layout()->addField($field); } $field->setForm($this); $field->width($this->width['field'], $this->width['label']); $this->setFileUploadUrl($field); $field::requireAssets(); return $this; } protected function setFileUploadUrl(Field $field) { if ($field instanceof Field\File && method_exists($this, 'form')) { $formData = [static::REQUEST_NAME => get_called_class()]; $field->url(route(admin_api_route('form.upload'))); $field->deleteUrl(route(admin_api_route('form.destroy-file'), $formData)); $field->withFormData($formData); } } /** * Get variables for render form. * * @return array */ protected function variables() { $this->setHtmlAttribute('id', $this->getElementId()); $this->fillFields($this->model()->toArray()); return array_merge([ 'start' => $this->open(), 'end' => $this->close(), 'fields' => $this->fields, 'method' => $this->getHtmlAttribute('method'), 'rows' => $this->rows(), 'layout' => $this->layout(), 'elementId' => $this->getElementId(), 'ajax' => $this->ajax, 'footer' => $this->renderFooter(), ], $this->variables); } /** * 表单底部内容. * * @return string */ protected function renderFooter() { if (empty($this->buttons['reset']) && empty($this->buttons['submit'])) { return; } $buttons = ''; if (! empty($this->buttons['reset'])) { $reset = trans('admin.reset'); $buttons .= ""; } if (! empty($this->buttons['submit'])) { $submit = $this->getSubmitButtonLabel(); $buttons .= ""; } return <<