2, 'field' => 8, ]; /** * Form constructor. * * @param array $data * @param mixed $key */ public function __construct($data = [], $key = null) { $this->data($data); $this->key($key); $this->initFormAttributes(); } /** * Initialize the form attributes. */ protected function initFormAttributes() { $this->setHtmlAttribute([ 'method' => 'POST', 'action' => '', 'class' => 'form-horizontal', 'accept-charset' => 'UTF-8', 'pjax-container' => true, ]); } /** * Action uri of the form. * * @param string $action * * @return $this */ public function action($action) { return $this->setHtmlAttribute('action', $action); } /** * @return mixed */ public function getAction() { return $this->getHtmlAttribute('action'); } /** * Method of the form. * * @param string $method * * @return $this */ public function method($method = 'POST') { return $this->setHtmlAttribute('method', strtoupper($method)); } /** * Set primary key. * * @param mixed $value * @return $this */ public function key($value) { $this->primaryKey = $value; return $this; } /** * @return mixed */ public function getKey() { return $this->primaryKey; } /** * @param $data * @return $this */ public function data($data) { $this->data = new Fluent(Helper::array($data)); return $this; } /** * @return Fluent */ public function model() { if (! $this->data) { $this->data([]); } 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 $name * @return Field|null */ public function field($name) { foreach ($this->fields as $field) { if ($field->column() === $name) { return $field; } } } /** * 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. * * @return $this */ public function disableResetButton() { array_delete($this->buttons, 'reset'); return $this; } /** * Disable submit button. * * @return $this */ public function disableSubmitButton() { array_delete($this->buttons, 'submit'); return $this; } /** * Set field and label width in current form. * * @param int $fieldWidth * @param int $labelWidth * * @return $this */ public function setWidth($fieldWidth = 8, $labelWidth = 2) { $this->width = [ 'label' => $labelWidth, 'field' => $fieldWidth, ]; collect($this->fields)->each(function ($field) use ($fieldWidth, $labelWidth) { /* @var Field $field */ $field->setWidth($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::getExtensions(), $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) { array_push($this->fields, $field); $field->setForm($this); $field->setWidth($this->width['field'], $this->width['label']); $field::collectAssets(); return $this; } /** * Get variables for render form. * * @return array */ protected function getVariables() { $this->setHtmlAttribute('id', $this->getFormId()); foreach ($this->fields as $field) { $field->fill($this->model()->toArray()); } return [ 'start' => $this->open(), 'end' => $this->close(), 'fields' => $this->fields, 'method' => $this->getHtmlAttribute('method'), 'buttons' => $this->buttons, ]; } /** * @return string */ protected function open() { return <<formatHtmlAttributes()}> HTML; } /** * @return string */ protected function close() { return ''; } /** * Determine if form fields has files. * * @return bool */ public function hasFile() { foreach ($this->fields as $field) { if ($field instanceof Field\File) { return true; } } return false; } /** * @param $id * @return $this */ public function setFormId($id) { $this->formId = $id; return $this; } /** * @return string */ public function getFormId() { return $this->formId ?: ($this->formId = 'form-'.Str::random(8)); } /** * Generate a Field object and add to form builder if Field exists. * * @param string $method * @param array $arguments * * @return Field|null */ public function __call($method, $arguments) { if ($className = static::findFieldClass($method)) { $name = Arr::get($arguments, 0, ''); $element = new $className($name, array_slice($arguments, 1)); $this->pushField($element); return $element; } if (static::hasMacro($method)) { return $this->macroCall($method, $arguments); } } /** * Disable submit with ajax. * * @param bool $disable * @return $this */ public function disableAjaxSubmit(bool $disable = true) { $this->useAjaxSubmit = !$disable; return $this; } /** * @return bool */ public function allowAjaxSubmit() { return $this->useAjaxSubmit === true; } protected function setupSubmitScript() { Admin::script( <<getFormId()}'); f.find('[type="submit"]').click(function () { var t = $(this); LA.Form({ \$form: f, before: function () { f.validator('validate'); if (f.find('.has-error').length > 0) { return false; } t.button('loading'); }, after: function () { t.button('reset'); } }); return false; }); JS ); } /** * Render the form. * * @return string */ public function render() { $this->useAjaxSubmit && $this->setupSubmitScript(); return view('admin::widgets.form', $this->getVariables())->render(); } /** * Output as string. * * @return string */ public function __toString() { return $this->render(); } }