diff --git a/src/FormBuilder.php b/src/FormBuilder.php index 5ad8523..1e63592 100644 --- a/src/FormBuilder.php +++ b/src/FormBuilder.php @@ -60,7 +60,7 @@ public function render(): string private function renderFormOpen(): string { - extract($this->get('id', 'method', 'url', 'formMultipart', 'formInline', 'autocomplete')); + extract($this->get('id', 'method', 'url', 'formMultipart', 'formInline', 'autocomplete', 'attrs')); if (!$method) { $method = 'post'; @@ -68,14 +68,19 @@ private function renderFormOpen(): string $enctype = $formMultipart ? 'multipart/form-data' : null; - $attrs = $this->buildHtmlAttrs([ + $attrs = $attrs ?? []; + $attrs['class'] = $this->createAttrsList( + ($formInline ? 'form-inline' : null), + $attrs['class'] ?? null + ); + + $attrs = $this->buildHtmlAttrs(array_merge($attrs, [ 'method' => in_array($method, ['get', 'post']) ? $method : 'post', 'action' => $url, 'enctype' => $enctype, 'autocomplete' => $autocomplete, - 'class' => $formInline ? 'form-inline' : null, 'id' => $id - ]); + ])); $output = '
'; @@ -140,14 +145,14 @@ private function renderInput(): string private function renderSelect(): string { - extract($this->get('options')); + extract($this->get('options', 'placeholder')); $fieldValue = $this->getValue(); $arrValues = is_array($fieldValue) ? $fieldValue : [$fieldValue]; - $optionsList = ''; - foreach ($options as $value => $label) { - $attrs = $this->buildHtmlAttrs(['value' => $value, 'selected' => in_array($value, $arrValues)], false); - $optionsList .= ''; + $optionsList = $this->getSelectOptions($arrValues, $options); + + if ($placeholder) { + $optionsList = '' . $optionsList; } $attributes = $this->getInputAttributes(); @@ -252,6 +257,9 @@ private function getInputAttributes(): array $attributes['value'] = $this->getValue(); } else { $attributes['multiple'] = $multiple; + if ($multiple) { + $attributes['name'] .= '[]'; + } } // If the field is a hidden field, we don't need add more attributes @@ -263,7 +271,7 @@ private function getInputAttributes(): array if ($this->hasOldInput()) { $isChecked = old($name) === $value; } else { - $isChecked = isset($formData[$name]) ? $formData[$name] === $value : $checked; + $isChecked = isset($formData[$name]) ? boolval($formData[$name]) === boolval($value) : $checked; } $attributes['checked'] = $isChecked; } @@ -281,23 +289,119 @@ private function getInputAttributes(): array ]); } + private function getSelectOptions($arrValues, $options, $optgroup_label = '') + { + extract($this->get('optgroup')); + + $optionsList = ''; + foreach ($options as $value => $label) { + if (is_array($label)) { + $optionsList .= '' + . $this->getSelectOptions($arrValues, $label, $value.';') . ''; + }else{ + if ($optgroup) { + $value = $optgroup_label.$value; + } + $attrs = $this->buildHtmlAttrs([ + 'value' => $value, + 'selected' => in_array($value, $arrValues) + ], false); + $optionsList .= ''; + } + } + return $optionsList; + } + private function renderLabel(): string { - extract($this->get('label', 'formInline', 'render')); + extract($this->get('label', 'formInline', 'render', 'labelAttrs')); + + if (is_null($label)) { + return ''; + } $class = in_array($render, ['checkbox', 'radio']) ? 'form-check-label' : ''; if ($formInline) { $class = join(' ', [$class, 'mx-sm-2']); } - $id = $this->getId(); - $attrs = $this->buildHtmlAttrs([ - 'for' => $id, - 'class' => $class - ], false); + $attrs = $labelAttrs ?? []; + $attrs['class'] = $this->createAttrsList( + $attrs['class'] ?? null, + $class + ); + $attrs['for'] = $this->getId(); + $attrs = $this->buildHtmlAttrs($attrs, false); return ''; } + private function wrapperInputGroup(string $input): string + { + extract($this->get('append', 'prepend', 'formInline', 'wrapperGroupAttrs', 'type', 'options')); + + if ((!$append && !$prepend) || !(in_array($type, ['text', 'date', 'time', 'tel', 'url']) || is_array($options))) { + return $input; + } + + $output = ($prepend ? $this->getInputGroup('prepend', $prepend) : '') . $input; + $output .= $append ? $this->getInputGroup('append', $append) : ''; + $attrs = $wrapperGroupAttrs ?? []; + $attrs['class'] = $this->createAttrsList( + 'input-group', + $attrs['class'] ?? null + ); + $attrs = $this->buildHtmlAttrs($attrs, false); + + if (!$formInline) { + $output = '
' . $output . '
'; + } + + return $output; + } + + private function getInputGroup(string $type, $value): string + { + $wrapperType = 'wrapper'. ucwords($type) . 'Attrs'; + extract($this->get('onlyInput', $wrapperType)); + + $attrs = $$wrapperType ?? []; + $attrs['class'] = $this->createAttrsList( + 'input-group-' . $type, + $attrs['class'] ?? null + ); + + $attrs = $this->buildHtmlAttrs($attrs, false); + $output = '
'; + + if (is_array($value)) { + foreach ($value as $text) { + $output .= $this->getInputGroupText($type, $text); + } + }else{ + $output .= $this->getInputGroupText($type, $value); + } + + return $output . '
'; + } + + private function getInputGroupText(string $type, string $value): string + { + extract($this->get($type . 'Attrs', $type . 'Style')); + + $attrs = ${$type . 'Attrs'} ?? []; + $attrs['class'] = $this->createAttrsList( + ( ${$type . 'Style'} ? 'input-group-text' : ''), + $attrs['class'] ?? null + ); + + if (!array_key_exists('id', $attrs)) { + $attrs['id'] = $type . '-' . $this->getId(); + } + + $attrs = $this->buildHtmlAttrs($attrs, false); + return '
' . $this->getText($value) . '
'; + } + private function getText($key) { extract($this->get('formLocale')); @@ -339,13 +443,18 @@ private function wrapperInput(string $input): string $formInline ? 'input-group' : 'form-group' ); $attributes = $this->buildHtmlAttrs($attrs, false); + $input = $this->wrapperInputGroup($input); return '
' . $label . $input . $helpText . $error . '
'; } private function wrapperRadioCheckbox(string $input): string { - extract($this->get('inline', 'name', 'wrapperAttrs')); + extract($this->get('inline', 'name', 'wrapperAttrs', 'onlyInput')); + + if ($onlyInput) { + return $input; + } $attrs = $wrapperAttrs ?? []; $attrs['class'] = $this->createAttrsList( @@ -398,7 +507,7 @@ private function getValue() } if ($this->hasOldInput()) { - return old($name, $value); + return old(preg_replace("/\[\]/", "", $name), $value); } $fromFill = $formData[$name] ?? null; diff --git a/src/FormService.php b/src/FormService.php index 3f43062..a279d29 100644 --- a/src/FormService.php +++ b/src/FormService.php @@ -212,10 +212,10 @@ public function url(string $url = null): FormService * Set route for links and form action * * @param string $route - * @param array $params + * @param array|string $params * @return FormService */ - public function route(string $route, array $params = []): FormService + public function route(string $route, $params = []): FormService { return $this->_set('url', route($route, $params)); } @@ -364,6 +364,28 @@ public function max($value) return $this->_set('max', $value); } + /** + * Set a append for a field + * + * @param mixed $value + * @return FormService + */ + public function append(string $value, array $attrs = null, bool $style = true): FormService + { + return $this->_set('append', $value)->_set('appendAttrs', $attrs)->_set('appendStyle', $style); + } + + /** + * Set a prepend for a field + * + * @param mixed $value + * @return FormService + */ + public function prepend(string $value, array $attrs = null, bool $style = true): FormService + { + return $this->_set('prepend', $value)->_set('prependAttrs', $attrs)->_set('prependStyle', $style); + } + /** * Create a hidden input * @@ -469,11 +491,12 @@ public function textarea(string $name = null, $label = null, string $default = n * Set a label * * @param string $label + * @param array $attrs * @return FormService */ - public function label($label): FormService + public function label($label, array $attrs = []): FormService { - return $this->_set('label', $label); + return $this->_set('label', $label)->labelAttrs($attrs); } /** @@ -538,6 +561,17 @@ public function checked(bool $checked = true): FormService return $this->_set('checked', $checked); } + /** + * Set optgroup label inside options value + * + * @param bool $optgroup + * @return FormService + */ + public function optgroup(bool $optgroup = true): FormService + { + return $this->_set('optgroup', $optgroup); + } + /** * Set a input value * @@ -802,10 +836,21 @@ public function attrs(array $attrs = []): FormService return $this->_set('attrs', $attrs); } + /** + * Set custom attributes for a label input + * + * @param array $attrs + * @return FormService + */ + public function labelAttrs(array $attrs = []): FormService + { + return $this->_set('labelAttrs', $attrs); + } + /** * Disable input states (valid and invalid classes) and error message * - * @param string $disable + * @param bool $disable * @return FormService */ public function disableValidation(bool $disable = true): FormService @@ -824,6 +869,39 @@ public function wrapperAttrs(array $attrs = []): FormService return $this->_set('wrapperAttrs', $attrs); } + /** + * Set custom attributes for a wrapper input group + * + * @param array $attrs + * @return FormService + */ + public function wrapperGroupAttrs(array $attrs = []): FormService + { + return $this->_set('wrapperGroupAttrs', $attrs); + } + + /** + * Set custom attributes for a wrapper append input + * + * @param array $attrs + * @return FormService + */ + public function wrapperAppendAttrs(array $attrs = []): FormService + { + return $this->_set('wrapperAppendAttrs', $attrs); + } + + /** + * Set custom attributes for a wrapper prepend input + * + * @param array $attrs + * @return FormService + */ + public function wrapperPrependAttrs(array $attrs = []): FormService + { + return $this->_set('wrapperPrependAttrs', $attrs); + } + /** * Create radio or checkbox input *