From 696509fc20adeae80bca40bb9dd40c4713e19ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Neto?= Date: Mon, 28 Jan 2019 11:47:34 +0000 Subject: [PATCH 01/35] Start replacing methods --- src/FormBuilder.php | 1048 +++++-------------------------------------- src/FormService.php | 242 ++++------ 2 files changed, 189 insertions(+), 1101 deletions(-) diff --git a/src/FormBuilder.php b/src/FormBuilder.php index 86012ce..bb1d53c 100644 --- a/src/FormBuilder.php +++ b/src/FormBuilder.php @@ -4,991 +4,153 @@ class FormBuilder { - /** - * List of allowed single word - * values for autocomplete attribute - * - * @var array - */ - private $_allowedAutoComplete; + private $_attrs = []; - /** - * Form input labels locale - * - * @var string - */ - private $_Flocale; - - /** - * Form inline form flag - * - * @var string - */ - private $_FinlineForm; - - /** - * Form method - * - * @var string - */ - private $_Fmethod; - - /** - * Multipart flag - * - * @var boolean - */ - private $_Fmultipart; - - /** - * Form array data - * - * @var array - */ - private $_Fdata; - - /** - * Inputs id prefix - * @var string - */ - private $_FidPrefix; - - /** - * Form autocomplete attribute - * @var string|null - */ - private $_Fautocomplete; - - /** - * Input autocomplete attribute - * @var string|null - */ - private $_autocomplete; - - /** - * Input meta data - * - * @var array - */ - private $_meta; - - /** - * Input attributes - * - * @var array - */ - private $_attrs; - - /** - * Input wrapper attributes - * - * @var array - */ - private $_wrapperAttrs; - - /** - * Form control type - * - * @var string - */ - private $_type; - - /** - * Form/Link - * - * @var string - */ - private $_url; - - /** - * Input placeholder - * - * @var string - */ - private $_placeholder; - - /** - * Flag to determine checkbox/radio style - * - * @var boolean - */ - private $_checkInline; - - /** - * Input size - * - * @var string - */ - private $_size; - - /** - * Readonly flag - * - * @var boolean - */ - private $_readonly; - - /** - * Disabled flag - * - * @var boolean - */ - private $_disabled; - - /** - * Required flag - * - * @var boolean - */ - private $_required; - - /** - * Input id - * - * @var string - */ - private $_id; - - /** - * Input name - * - * @var string - */ - private $_name; - - /** - * Input label - * - * @var string - */ - private $_label; - - /** - * Select options - * - * @var array - */ - private $_options; - - /** - * Input help text - * - * @var string - */ - private $_help; - - /** - * Input color - * - * @var string - */ - private $_color; - - /** - * Input outline flag - * - * @var boolean - */ - private $_outline; - - /** - * Input block flag - * - * @var boolean - */ - private $_block; - - /** - * Input value - * - * @var boolean - */ - private $_value; - - /** - * Select multiple flag - * - * @var boolean - */ - private $_multiple; - - public function __construct() - { - $this->_resetFlags(); - $this->_resetFormFlags(); - - //All allowed single word autocomplete values. If the name of input field matches, - //they will be automatically set as autocomplete value - //Flip the array to make searches faster - $this->_allowedAutoComplete = array_flip(['name', 'honorific-prefix', 'given-name', 'additional-name', - 'family-name', 'honorific-suffix', 'nickname', 'username', 'new-password', 'current-password', - 'organization-title', 'organization', 'street-address', 'address-line1', 'address-line2', 'address-line3', - 'address-level4', 'address-level3', 'address-level2', 'address-level1', 'country', 'country-name', - 'postal-code', 'cc-name', 'cc-given-name', 'cc-additional-name', 'cc-family-name', 'cc-number', 'cc-exp', - 'cc-exp-month', 'cc-exp-year', 'cc-csc', 'cc-type', 'transaction-currency', 'transaction-amount', 'language', - 'bday', 'bday-day', 'bday-month', 'bday-year', 'sex', 'url', 'photo', 'tel', 'tel-country-code', 'tel-national', - 'tel-area-code', 'tel-local', 'tel-local-prefix', 'tel-local-suffix', 'tel-extension', 'email', 'impp']); - } - - /** - * Set a class attribute - * - * @param string $attr - * @param mixed $value - */ - public function set(string $attr, $value) - { - $this->{'_' . $attr} = $value; - } - - /** - * Retrieve a class attribute - * - * @param string $attr - * @return mixed - */ - public function get(string $attr) - { - return $this->{'_' . $attr}; - } - - /** - * Return a open form tag - * - * @return string - */ - public function open(): string - { - $props = [ - 'action' => $this->_url, - 'method' => $this->_Fmethod === 'get' ? 'get' : 'post' - ]; - - if($this->_Fmultipart){ - $props['enctype'] = 'multipart/form-data'; - } - - if($this->_FinlineForm) { - $props['class'] = 'form-inline'; - } - - if (!is_null($this->_Fautocomplete)) { - $props['autocomplete'] = $this->_Fautocomplete; - } - - $attrs = $this->_buildAttrs($props, ['class-form-control']); - - $ret = '
'; - - if ($this->_Fmethod !== 'get') { - $ret .= csrf_field(); - - if ($this->_Fmethod !== 'post' && $this->_Fmethod !== 'get') { - $ret .= method_field($this->_Fmethod); - } + public function set($key, $value) { + $formatter = '_format'.ucfirst($key); + if(method_exists($this, $formatter)){ + $value = $this->$formatter($value); } - - $this->_resetFlags(); - - return $ret; - } - - /** - * Return a close form tag - * - * @return string - */ - public function close(): string - { - $ret = '
'; - - $this->_resetFormFlags(); - $this->_resetFlags(); - - return $ret; + $this->_attrs[$key] = $value; } - /** - * Return a open fieldset tag - * - * @return string - */ - public function fieldsetOpen(): string - { - $attrs = $this->_buildAttrs(['class' => 'form-group']); - $ret = ''; - - if ($this->_meta['legend']) { - $ret .= '' . $this->_e($this->_meta['legend']) . ''; + private function _formatFormData($value){ + if (is_object($value) && method_exists($value, 'toArray')) { + return $value->toArray(); } - - $this->_resetFlags(); - - return $ret; - } - - /** - * Return a close fieldset tag - * - * @return string - */ - public function fieldsetClose(): string - { - $this->_resetFlags(); - - return ''; - } - - /** - * Return a file input tag - * - * @return string - */ - public function file(): string - { - $attrs = $this->_buildAttrs(); - - return $this->_renderWrapperCommomField(''); - } - - /** - * Return a text input tag - * - * @return string - */ - public function text(): string - { - return $this->_renderInput(); - } - - /** - * Return a password input tag - * - * @return string - */ - public function password(): string - { - return $this->_renderInput('password'); + return $value; } - /** - * Return a range input tag - * - * @return string - */ - public function range(): string - { - return $this->_renderInput('range'); + public function render(): string { + $render = $this->_attrs['render']; + $methodName = '_render' . ucfirst($render); + $output = $this->$methodName(); + $this->_resetAttributes(); + return $output; } - /** - * Return a date input tag - * - * @return string - */ - public function date(): string - { - return $this->_renderInput('date'); - } - - /** - * Return a time input tag - * - * @return string - */ - public function time(): string - { - return $this->_renderInput('time'); - } - - /** - * Return a email input tag - * - * @return string - */ - public function email(): string - { - return $this->_renderInput('email'); - } - - /** - * Return a tel input tag - * - * @return string - */ - public function tel(): string - { - return $this->_renderInput('tel'); - } - - /** - * Return a url input tag - * - * @return string - */ - public function url(): string - { - return $this->_renderInput('url'); - } - - /** - * Return a number input tag - * - * @return string - */ - public function number(): string - { - return $this->_renderInput('number'); - } - - /** - * Return a hidden input tag - * - * @return string - */ - public function hidden(): string - { - $value = $this->_getValue(); - $attrs = $this->_buildAttrs(['value' => $value]); - - $this->_resetFlags(); + private function _renderFormOpen() : string { + extract($this->_get('method', 'formUrl', 'formMultipart')); - return ''; - } - - /** - * Return a textarea tag - * - * @return string - */ - public function textarea(): string - { - $attrs = $this->_buildAttrs(['rows' => 3]); - $value = $this->_getValue(); - - return $this->_renderWrapperCommomField(''); - } - - /** - * Return a select tag - * - * @return string - */ - public function select(): string - { - $attrs = $this->_buildAttrs(); - $value = $this->_getValue(); - $options = ''; - - if ($this->_multiple) { - if (!is_array($value)) { - $value = [$value]; - } + if(!$method) { + $method = 'post'; + } - foreach ($this->_options as $key => $label) { + $enctype = $formMultipart ? 'multipart/form-data' : null; - if (array_key_exists($key, $value)) { - $match = true; - } else { - $match = false; - } + $attrs = $this->_buildHtmlAttrs(['method' => $method, 'action' => $formUrl, 'enctype' => $enctype]); + $output = '
'; - $checked = ($match) ? ' selected' : ''; - $options .= ''; - } - } else { - foreach ($this->_options as $optvalue => $label) { - $checked = $optvalue == $value ? ' selected' : ''; - $options .= ''; + if ($method !== 'get') { + $output .= csrf_field(); + if ($method !== 'post') { + $output .= method_field($method); } } - return $this->_renderWrapperCommomField(''); + return $output; } - /** - * Return a checkbox tag - * - * @return string - */ - public function checkbox(): string - { - return $this->_renderCheckboxOrRadio(); + private function _renderFormClose() : string { + $this->_resetAttributes(true); + return '
'; } - /** - * Return a radio tag - * - * @return string - */ - public function radio(): string - { - return $this->_renderCheckboxOrRadio(); + private function _renderButton() : string { + extract($this->_get('size', 'color', 'type', 'value', 'disabled')); + $sizeCls = !$size ? '' : 'btn-'.$size; + $colorCls = !$color ? '' : 'btn-'.$color; + $class = join(' ', array_filter(['btn', $colorCls, $sizeCls])); + $attrs = $this->_buildHtmlAttrs(['type' => $type, 'class' => $class, 'disabled' => $disabled]); + return ''; } - /** - * Return a button tag - * - * @return string - */ - public function button(): string - { - return $this->_renderButtonOrAnchor(); - } - - /** - * Return a submit input tag - * - * @return string - */ - public function submit(): string - { - return $this->_renderButtonOrAnchor(); - } - - /** - * Return a reset button tag - * - * @return string - */ - public function reset(): string - { - return $this->_renderButtonOrAnchor(); - } - - /** - * Return a anchor tag - * - * @return string - */ - public function anchor(): string - { - return $this->_renderButtonOrAnchor(); - } - - /** - * Return a generic input tag - * - * @param string $type - * @return string - */ - private function _renderInput($type = 'text'): string - { - $value = $this->_getValue(); - $attrs = $this->_buildAttrs(['value' => $value, 'type' => $type]); - - return $this->_renderWrapperCommomField(''); - } - - /** - * Return a button or anchor tag - * - * @return string - */ - private function _renderButtonOrAnchor(): string - { - $size = $this->_size ? ' btn-' . $this->_size : ''; - $outline = $this->_outline ? 'outline-' : ''; - $block = $this->_block ? ' btn-block' : ''; - $disabled = $this->_disabled ? ' disabled' : ''; - $value = $this->_e($this->_value); - $cls = 'btn btn-' . $outline . $this->_color . $size . $block; - - if ($this->_type == 'anchor') { - $href = $this->_url ?: 'javascript:void(0)'; - $attrs = $this->_buildAttrs( - [ - 'class' => $cls . $disabled, - 'href' => $href, - 'role' => 'button', - 'aria-disabled' => $disabled ? 'true' : null - ] - ); - $ret = '' . $value . ''; - } else { - $attrs = $this->_buildAttrs(['class' => $cls, 'type' => $this->_type]); - $ret = ''; - } - - $this->_resetFlags(); - - return $ret; - } - - /** - * Return a label tag - * - * @return string - */ - private function _getLabel(): string - { - - $label = $this->_label === true ? $this->_name : $this->_label; - $result = ''; - - if ($label) { - - $classStr = ''; - if($this->_FinlineForm) { - $classStr = ' class="sr-only"'; - } - - $id = $this->_getId(); - $result = ''; - } - - return $result; - } - - /** - * Return a string with HTML element attributes - * - * @param array $props - * @param array $ignore - * @return string - */ - private function _buildAttrs(array $props = [], array $ignore = []): string - { - $props = array_merge(array_filter($this->_attrs, function($k){ - return $k != 'class'; - }, ARRAY_FILTER_USE_KEY), $props); - - if($this->_type){ - $props['type'] = $this->_type; - } - - if($this->_name){ - $props['name'] = $this->_name; - } - - if (!is_null($this->_autocomplete)) { - $props['autocomplete'] = $this->_autocomplete; - } else if ($this->_name && isset($this->_allowedAutoComplete[$this->_name])) { - $props['autocomplete'] = $this->_name; - } - + private function _renderInput() : string { + extract($this->_get('type', 'name', 'placeholder', 'help', 'disabled')); + $class = 'form-control'; $id = $this->_getId(); - if($id){ - $props['id'] = $this->_getId(); - } - - $props['class'] = isset($props['class']) ? $props['class'] : ''; - - if ($this->_type == 'select' && $this->_multiple && $this->_name) { - $props['name'] = $props['name'] . '[]'; - } - - if ($this->_placeholder) { - $props['placeholder'] = $this->_placeholder; - } - - if ($this->_help) { - $props['aria-describedby'] = $this->_getIdHelp(); - } - - if($this->_required === true) { - $props['required'] = true; - } - - switch($this->_type) { - case 'file': - $formControlClass = 'form-control-file'; - break; - case 'range': - $formControlClass = 'form-control-range'; - break; - default: - $formControlClass = 'form-control'; - break; - } - - if (!$props['class'] && !in_array('class-form-control', $ignore)) { - $props['class'] = $formControlClass; - } - - if ($this->_size) { - $props['class'] .= ' '.$formControlClass.'-' . $this->_size; - } - - if($this->_FinlineForm) { - $props['class'] .= ' mb-2 mr-sm-2'; - } - - $props['class'] .= ' ' . $this->_getValidationFieldClass(); - - if (isset($this->_attrs['class'])) { - $props['class'] .= ' ' . $this->_attrs['class']; - } - - $props['class'] = trim($props['class']); - - if(!$props['class']) { - $props['class'] = false; - } - - if ($this->_type == 'select' && $this->_multiple) { - $props['multiple'] = true; - } - - if ($this->_readonly) { - $props['readonly'] = true; - } - - if ($this->_disabled) { - $props['disabled'] = true; - } - - if (in_array($this->_type, ['radio', 'checkbox'])) { - $value = $this->_getValue(); - if ( - $value && ( - $this->_type === 'checkbox' || $this->_type === 'radio' && $value === $this->_meta['value'] - ) - ) { - $props['checked'] = true; - } - } - - if ($this->_type == 'hidden') { - $props['autocomplete'] = false; - $props['class'] = false; - } - - return $this->_arrayToHtmlAttrs($props); + $attrs = $this->_buildHtmlAttrs([ + 'type' => $type, + 'name' => $name, + 'value' => $this->_getValue(), + 'class' => $class, + 'id' => $id, + 'placeholder' => $placeholder, + 'aria-describedby' => $help ? 'help-'.$id : null, + 'disabled' => $disabled + ]); + return $this->_wrapperInput(''); + } + + private function renderLabel() : string { + extract($this->_get('label')); + $id = $this->_getId(); + return ''; } - /** - * Return a input value - * - * @return mixed - */ - private function _getValue() - { - $name = $this->_name; - - if ($this->_hasOldInput()) { - return old($name); - } - - if ($this->_value !== null) { - return $this->_value; + private function _getText($key){ + extract($this->_get('formLocale')); + if($formLocale){ + // ... } - - if (isset($this->_Fdata[$name])) { - return $this->_Fdata[$name]; - } - } - - /** - * Check if has a old request - * - * @return boolean - */ - private function _hasOldInput() - { - return count((array) old()) != 0; + return $key; } - /** - * Return a element id - * - * @return string - */ - private function _getId() - { - $id = $this->_id; - - if (!$id && $this->_name) { - $id = $this->_name; - if ($this->_type == 'radio') { - $id .= '-' . str_slug($this->_meta['value']); - } + private function _resetAttributes($resetAll = false) { + // Remove all attributes + if($resetAll) { + $this->_attrs = []; + return; } - - if(!$id) { - return null; + + // Keep attributes which key starting with 'form' + $keys = array_keys($this->_attrs); + foreach($keys as $key){ + if(substr($key, 0, 4) == 'form'){ + continue; + } + unset($this->_attrs[$key]); } - - return $this->_FidPrefix . $id; } - /** - * Return a help text id HTML element - * - * @return string - */ - private function _getIdHelp() - { + private function _wrapperInput(string $input) : string { + extract($this->_get('help')); $id = $this->_getId(); - - return $id ? 'help-' . $id : ''; + $label = $this->renderLabel(); + $helpText = $help ? ''.$this->_getText($help).'' : ''; + return '
'.$label.$input.$helpText.'
'; } - /** - * Return a help text - * - * @return string - */ - private function _getHelpText(): string - { - $id = $this->_getIdHelp(); - - return $this->_help ? '' . $this->_e($this->_help) . '' : ''; + private function _getId() { + extract($this->_get('name', 'formIdPrefix')); + return ($formIdPrefix ?? 'inp-') . $name; } - /** - * Return a text with translations, if available - * - * @param string $key - * - * @return string - */ - private function _e($key): string - { - $fieldKey = $key ?: $this->_name; - - return $this->_Flocale ? __($this->_Flocale . '.' . $fieldKey) : $fieldKey; + private function _getValue() { + extract($this->_get('name', 'value', 'formData')); + return old($name, $value) ?? ($formData[$name] ?? null); } - private function _getValidationFieldClass(): string - { - if (!$this->_name) { - return ''; - } - - if (session('errors') === null) { - return ''; - } - - if ($this->_getValidationFieldMessage()) { - return ' is-invalid'; - } - - return ' is-valid'; - } - - /** - * Return a checkbox or radio HTML element - * - * @return string - */ - private function _renderCheckboxOrRadio(): string - { - $attrs = $this->_buildAttrs(["class" => "form-check-input", "type" => $this->_type, "value" => $this->_meta['value']]); - $inline = $this->_checkInline ? ' form-check-inline' : ''; - $label = $this->_e($this->_label); - $id = $this->_getId(); - - $this->_resetFlags(); - - return '
'; - } - - private function _arrayToHtmlAttrs($attributes){ - return join(' ', array_map(function($key) use ($attributes) { - $value = $attributes[$key]; - if(is_bool($value)){ - return $value ? $key : ''; - } else { - return $key.'="'.htmlspecialchars($value).'"'; - } + private function _buildHtmlAttrs($attributes) : string { + return join(' ', array_filter( + array_map(function($key) use ($attributes) { + $value = $attributes[$key]; + if(is_bool($value)){ + return $value ? $key : ''; + } elseif($value) { + return $key.'="'.htmlspecialchars($value).'"'; + } + return ''; }, array_keys($attributes)) - ); + )); } - /** - * Return a input with a wrapper HTML markup - * - * @param string $field - * @return string - */ - private function _renderWrapperCommomField(string $field): string - { - $label = $this->_getLabel(); - $help = $this->_getHelpText(); - $error = $this->_getValidationFieldMessage(); - - $classList = isset($this->_wrapperAttrs['class']) ? $this->_wrapperAttrs['class'] : ''; - $this->_wrapperAttrs['class'] = "form-group " . $classList; - $wrapperAttrs = $this->_arrayToHtmlAttrs($this->_wrapperAttrs); - - $this->_resetFlags(); - - $formGroupOpen = '
'; - $formGroupClose = '
'; - - if($this->_FinlineForm) { - $formGroupOpen = $formGroupClose = ''; + private function _get(...$keys) : array { + $return = []; + foreach($keys as $key){ + $return[$key] = $this->_attrs[$key] ?? null; } - - return $formGroupOpen . $label . $field . $help . $error . $formGroupClose; - } - - /** - * Return a validation error message - * - * @param string $prefix - * @param string $sufix - * @return string|null - */ - private function _getValidationFieldMessage(string $prefix = '
', string $sufix = '
') - { - $errors = session('errors'); - if (!$errors) { - return null; - } - $error = $errors->first($this->_name); - - if (!$error) { - return null; - } - - return $prefix . $error . $sufix; - } - - /** - * Reset input flags - */ - private function _resetFlags() - { - - $this->_render = null; - $this->_meta = []; - $this->_attrs = []; - $this->_wrapperAttrs = []; - $this->_type = null; - $this->_url = null; - $this->_placeholder = null; - $this->_checkInline = false; - $this->_size = null; - $this->_readonly = false; - $this->_disabled = false; - $this->_id = null; - $this->_name = null; - $this->_label = null; - $this->_options = []; - $this->_help = null; - $this->_color = "primary"; - $this->_outline = false; - $this->_block = false; - $this->_value = null; - $this->_multiple = false; - $this->_autocomplete = null; - } - - /** - * Reset form flags - */ - private function _resetFormFlags() - { - - $this->_Flocale = null; - $this->_Fmethod = 'post'; - $this->_Fmultipart = false; - $this->_FinlineForm = false; - $this->_Fdata = null; - $this->_FidPrefix = ''; - $this->_Fautocomplete = null; + return $return; } -} +} \ No newline at end of file diff --git a/src/FormService.php b/src/FormService.php index 357d519..ff7bbcb 100644 --- a/src/FormService.php +++ b/src/FormService.php @@ -9,27 +9,6 @@ */ class FormService { - /** - * The Form builder instance - * - * @var FormBuilder - */ - private $_builder; - - /** - * Render to be used - * - * @var string - */ - private $_render; - - /** - * Allowed renders - * - * @var array - */ - private $_allowedRenders = ['open', 'close', 'fieldsetOpen', 'fieldsetClose', 'file', 'text', 'range', 'password', 'date', 'time', 'email', 'tel', 'url', 'number', 'hidden', 'select', 'checkbox', 'radio', 'textarea', 'button', 'submit', 'anchor', 'reset']; - /** * Create a new FormSevice instance */ @@ -45,16 +24,7 @@ public function __construct() */ public function __toString() { - $output = ''; - - if (in_array($this->_render, $this->_allowedRenders)) { - - $output = $this->_builder->{$this->_render}(); - } - - $this->_render = null; - - return $output; + return $this->_builder->render(); } /** @@ -64,7 +34,7 @@ public function __toString() */ public function open(): FormService { - return $this->render('open'); + return $this->_set('render', 'formOpen'); } /** @@ -74,7 +44,7 @@ public function open(): FormService */ public function close(): FormService { - return $this->render('close'); + return $this->_set('render', 'formClose'); } /** @@ -85,7 +55,7 @@ public function close(): FormService */ public function idPrefix(string $prefix = ''): FormService { - return $this->_set('FidPrefix', $prefix); + return $this->_set('formIdPrefix', $prefix); } /** @@ -96,7 +66,7 @@ public function idPrefix(string $prefix = ''): FormService */ public function multipart(bool $multipart = true): FormService { - return $this->_set('Fmultipart', $multipart); + return $this->_set('formMultipart', $multipart); } /** @@ -107,7 +77,7 @@ public function multipart(bool $multipart = true): FormService */ public function method(string $method): FormService { - return $this->_set('Fmethod', $method); + return $this->_set('method', $method); } /** @@ -168,16 +138,7 @@ public function delete(): FormService */ public function fill($data): FormService { - - if (method_exists($data, 'toArray')) { - $data = $data->toArray(); - } - - if (!is_array($data)) { - $data = []; - } - - return $this->_set('Fdata', $data); + return $this->_set('formData', $data); } /** @@ -188,37 +149,18 @@ public function fill($data): FormService */ public function locale(string $path): FormService { - return $this->_set('Flocale', $path); + return $this->_set('formLocale', $path); } /** - * Set inline form to inline inputs - * @param bool $inline - * @return FormService - */ - public function inlineForm(bool $inline = true): FormService - { - return $this->_set('FinlineForm', $inline); - } - - /** - * Set autocomplete value ('on', 'off', or one of the permitted values) - * - * If set on the form, only 'on' or 'off' are valid and are inherited by input fields. - * The inherited value can be overridden on individual input fields - * - * See: https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill + * Set autocomplete attribute on form, or on individual input fields * * @param string $value * @return FormService */ - public function autocomplete(string $value = 'on'): FormService + public function autocomplete($value = true): FormService { - if ($this->_render == "open") { - return $this->_set('Fautocomplete', $value); - } - - return $this->_set('autocomplete', $value); + return $this; } /** @@ -228,7 +170,7 @@ public function autocomplete(string $value = 'on'): FormService */ public function inline(bool $inline = true): FormService { - return $this->_set('checkInline', $inline); + return $this; } /** @@ -239,7 +181,7 @@ public function inline(bool $inline = true): FormService */ public function url(string $url): FormService { - return $this->_set('url', url($url)); + return $this->_set('formUrl', url($url)); } /** @@ -251,7 +193,7 @@ public function url(string $url): FormService */ public function route(string $route, array $params = []): FormService { - return $this->_set('url', route($route, $params)); + return $this->_set('formUrl', route($route, $params)); } /** @@ -262,7 +204,7 @@ public function route(string $route, array $params = []): FormService */ public function fieldsetOpen(string $legend = null): FormService { - return $this->_set('meta', ['legend' => $legend])->render('fieldsetOpen'); + return $this; } /** @@ -272,7 +214,7 @@ public function fieldsetOpen(string $legend = null): FormService */ public function fieldsetClose(): FormService { - return $this->render('fieldsetClose'); + return $this; } /** @@ -295,7 +237,7 @@ public function help(string $text): FormService */ public function file(string $name = null, string $label = null): FormService { - return $this->name($name)->label($label)->type('file'); + return $this; } /** @@ -308,7 +250,7 @@ public function file(string $name = null, string $label = null): FormService */ public function text(string $name = null, $label = null, string $default = null): FormService { - return $this->type('text')->name($name)->label($label)->value($default); + return $this->render('input')->type('text')->name($name)->label($label)->value($default); } /** @@ -321,7 +263,7 @@ public function text(string $name = null, $label = null, string $default = null) */ public function date(string $name = null, $label = null, string $default = null): FormService { - return $this->type('date')->name($name)->label($label)->value($default); + return $this; } /** @@ -334,7 +276,33 @@ public function date(string $name = null, $label = null, string $default = null) */ public function time(string $name = null, $label = null, string $default = null): FormService { - return $this->type('time')->name($name)->label($label)->value($default); + return $this; + } + + /** + * Create a telephone input + * + * @param string $name + * @param string $label + * @param string $default + * @return FormService + */ + public function tel(string $name = null, $label = null, string $default = null): FormService + { + return $this; + } + + /** + * Create a url input + * + * @param string $name + * @param string $label + * @param string $default + * @return FormService + */ + public function urlInput(string $name = null, $label = null, string $default = null): FormService + { + return $this; } /** @@ -347,7 +315,7 @@ public function time(string $name = null, $label = null, string $default = null) */ public function range(string $name = null, $label = null, string $default = null): FormService { - return $this->type('range')->name($name)->label($label)->value($default); + return $this; } /** @@ -359,7 +327,7 @@ public function range(string $name = null, $label = null, string $default = null */ public function hidden(string $name = null, string $default = null): FormService { - return $this->name($name)->value($default)->type('hidden'); + return $this; } /** @@ -373,7 +341,7 @@ public function hidden(string $name = null, string $default = null): FormService */ public function select(string $name = null, string $label = null, $options = [], $default = null): FormService { - return $this->name($name)->label($label)->options($options)->value($default)->type('select'); + return $this; } /** @@ -384,8 +352,7 @@ public function select(string $name = null, string $label = null, $options = [], */ public function options(array $options = []): FormService { - $items = is_iterable($options) ? $options : [0 => 'Must be iterable']; - return $this->_set('options', $items); + return $this; } /** @@ -399,7 +366,7 @@ public function options(array $options = []): FormService */ public function checkbox(string $name = null, string $label = null, string $value = null, string $default = null): FormService { - return $this->_checkboxRadio('checkbox', $name, $label, $value, $default); + return $this; } /** @@ -413,7 +380,7 @@ public function checkbox(string $name = null, string $label = null, string $valu */ public function radio(string $name = null, string $label = null, string $value = null, string $default = null): FormService { - return $this->_checkboxRadio('radio', $name, $label, $value, $default); + return $this; } /** @@ -426,7 +393,7 @@ public function radio(string $name = null, string $label = null, string $value = */ public function textarea(string $name = null, $label = null, string $default = null): FormService { - return $this->type('textarea')->name($name)->value($default)->label($label); + return $this; } /** @@ -450,7 +417,7 @@ public function label($label): FormService */ public function button(string $value = null, $color = 'primary', $size = null): FormService { - return $this->type('button')->color($color)->size($size)->value($value); + return $this->_set('render', 'button')->value($value)->color($color)->size($size); } /** @@ -463,7 +430,7 @@ public function button(string $value = null, $color = 'primary', $size = null): */ public function submit(string $value, $color = 'primary', $size = null): FormService { - return $this->button($value)->type('submit')->color($color)->size($size); + return $this->type('submit')->button($value, $color, $size); } /** @@ -476,7 +443,7 @@ public function submit(string $value, $color = 'primary', $size = null): FormSer */ public function reset(string $value, $color = 'primary', $size = null): FormService { - return $this->button($value)->type('reset')->color($color)->size($size); + return $this->type('reset')->button($value, $color, $size); } /** @@ -488,11 +455,7 @@ public function reset(string $value, $color = 'primary', $size = null): FormServ */ public function anchor(string $value, $url = null): FormService { - if ($url) { - $this->url($url); - } - - return $this->button($value)->type('anchor'); + return $this; } /** @@ -503,14 +466,7 @@ public function anchor(string $value, $url = null): FormService */ public function checked(bool $checked = true): FormService { - $type = $this->_builder->get('type'); - $meta = $this->_builder->get('meta'); - - if ($type === 'radio' && $checked) { - $checked = $meta['value']; - } - - return $this->value($checked); + return $this; } /** @@ -521,11 +477,7 @@ public function checked(bool $checked = true): FormService */ public function value($value = null): FormService { - if ($value !== null) { - return $this->_set('value', $value); - } - - return $this; + return $this->_set('value', $value); } /** @@ -536,7 +488,7 @@ public function value($value = null): FormService */ public function type($type): FormService { - return $this->_set('type', $type)->render($type); + return $this->_set('type', $type); } /** @@ -547,9 +499,7 @@ public function type($type): FormService */ public function render(string $render): FormService { - $this->_render = $render; - - return $this; + return $this->_set('render', $render); } /** @@ -560,7 +510,7 @@ public function render(string $render): FormService */ public function id($id): FormService { - return $this->_set('id', $id); + return $this; } /** @@ -592,7 +542,7 @@ public function size(string $size = null): FormService */ public function lg(): FormService { - return $this->size('lg'); + return $this->_set('size', 'lg'); } /** @@ -602,7 +552,7 @@ public function lg(): FormService */ public function sm(): FormService { - return $this->size('sm'); + return $this->_set('size', 'sm'); } /** @@ -623,7 +573,7 @@ public function color(string $color = null): FormService */ public function primary(): FormService { - return $this->color('primary'); + return $this; } /** @@ -633,7 +583,7 @@ public function primary(): FormService */ public function secondary(): FormService { - return $this->color('secondary'); + return $this; } /** @@ -643,7 +593,7 @@ public function secondary(): FormService */ public function success(): FormService { - return $this->color('success'); + return $this; } /** @@ -653,7 +603,7 @@ public function success(): FormService */ public function danger(): FormService { - return $this->color('danger'); + return $this; } /** @@ -663,7 +613,7 @@ public function danger(): FormService */ public function warning(): FormService { - return $this->color('warning'); + return $this; } /** @@ -673,7 +623,7 @@ public function warning(): FormService */ public function info(): FormService { - return $this->color('info'); + return $this; } /** @@ -683,7 +633,7 @@ public function info(): FormService */ public function light(): FormService { - return $this->color('light'); + return $this; } /** @@ -693,7 +643,7 @@ public function light(): FormService */ public function dark(): FormService { - return $this->color('dark'); + return $this; } /** @@ -703,7 +653,7 @@ public function dark(): FormService */ public function link(): FormService { - return $this->color('link'); + return $this; } /** @@ -714,7 +664,7 @@ public function link(): FormService */ public function outline(bool $outline = true): FormService { - return $this->_set('outline', $outline); + return $this; } /** @@ -725,7 +675,7 @@ public function outline(bool $outline = true): FormService */ public function block(bool $status= true): FormService { - return $this->_set('block', $status); + return $this; } /** @@ -736,7 +686,7 @@ public function block(bool $status= true): FormService */ public function readonly($status = true): FormService { - return $this->_set('readonly', $status); + return $this; } /** @@ -758,7 +708,7 @@ public function disabled($status = true): FormService */ public function required($status = true) : FormService { - return $this->_set('required', $status); + return $this; } /** @@ -780,7 +730,7 @@ public function placeholder($placeholder): FormService */ public function attrs(array $attrs = []): FormService { - return $this->_set('attrs', $attrs); + return $this; } /** @@ -791,7 +741,7 @@ public function attrs(array $attrs = []): FormService */ public function wrapperAttrs(array $attrs = []): FormService { - return $this->_set('wrapperAttrs', $attrs); + return $this; } /** @@ -802,42 +752,18 @@ public function wrapperAttrs(array $attrs = []): FormService */ public function multiple(bool $multiple = true): FormService { - return $this->_set('multiple', $multiple); - } - - /** - * Set a form builder attribute - * - * @param string $attr - * @param mixed $value - * @return FormService - */ - private function _set($attr, $value): FormService - { - $this->_builder->set($attr, $value); - return $this; } /** - * Render a checkbox or a radio input + * Set the size * - * @param string $type - * @param string $name - * @param string $label - * @param mixed $value - * @param string $default + * @param string $size * @return FormService */ - private function _checkboxRadio($type, $name, $label, $value, $default): FormService + private function _set(string $key, $value): FormService { - $inputValue = $value === null ? $name : $value; - - if ($default) { - $default = $inputValue; - } - - return $this->_set('meta', ['value' => $inputValue])->type($type)->name($name)->label($label)->value($default); + $this->_builder->set($key, $value); + return $this; } - } From 1200435b9a7233f2b0d36e86b585962a5781a91b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sousa?= Date: Sun, 24 Feb 2019 11:18:34 +0000 Subject: [PATCH 02/35] Refactoring some methods --- src/FormBuilder.php | 71 +++++++++++++++++++++++++++++++++++---------- src/FormService.php | 46 ++++++++++++++--------------- 2 files changed, 79 insertions(+), 38 deletions(-) diff --git a/src/FormBuilder.php b/src/FormBuilder.php index bb1d53c..5142f83 100644 --- a/src/FormBuilder.php +++ b/src/FormBuilder.php @@ -30,7 +30,7 @@ public function render(): string { } private function _renderFormOpen() : string { - extract($this->_get('method', 'formUrl', 'formMultipart')); + extract($this->_get('method', 'url', 'formMultipart', 'autocomplete')); if(!$method) { $method = 'post'; @@ -38,7 +38,13 @@ private function _renderFormOpen() : string { $enctype = $formMultipart ? 'multipart/form-data' : null; - $attrs = $this->_buildHtmlAttrs(['method' => $method, 'action' => $formUrl, 'enctype' => $enctype]); + $attrs = $this->_buildHtmlAttrs([ + 'method' => $method, + 'action' => $url, + 'enctype' => $enctype, + 'autocomplete' => $autocomplete + ]); + $output = '
'; if ($method !== 'get') { @@ -56,6 +62,21 @@ private function _renderFormClose() : string { return '
'; } + private function _renderFieldsetOpen() : string { + $output = '
'; + extract($this->_get('legend')); + + if($legend){ + $output .= '' . $this->_getText($legend) . ''; + } + + return $output; + } + + private function _renderFieldsetClose() : string { + return '
'; + } + private function _renderButton() : string { extract($this->_get('size', 'color', 'type', 'value', 'disabled')); $sizeCls = !$size ? '' : 'btn-'.$size; @@ -66,8 +87,19 @@ private function _renderButton() : string { } private function _renderInput() : string { - extract($this->_get('type', 'name', 'placeholder', 'help', 'disabled')); + extract($this->_get('type', 'name', 'placeholder', 'help', 'disabled', 'autocomplete')); $class = 'form-control'; + + switch($type){ + case 'file': + $class .= '-file'; + break; + case 'range': + $class .= '-range'; + break; + } + + $id = $this->_getId(); $attrs = $this->_buildHtmlAttrs([ 'type' => $type, @@ -75,7 +107,8 @@ private function _renderInput() : string { 'value' => $this->_getValue(), 'class' => $class, 'id' => $id, - 'placeholder' => $placeholder, + 'autocomplete' => $autocomplete, + 'placeholder' => $this->_getText($placeholder), 'aria-describedby' => $help ? 'help-'.$id : null, 'disabled' => $disabled ]); @@ -91,7 +124,7 @@ private function renderLabel() : string { private function _getText($key){ extract($this->_get('formLocale')); if($formLocale){ - // ... + return __($formLocale . '.' . $key); } return $key; } @@ -104,21 +137,22 @@ private function _resetAttributes($resetAll = false) { } // Keep attributes which key starting with 'form' - $keys = array_keys($this->_attrs); - foreach($keys as $key){ - if(substr($key, 0, 4) == 'form'){ - continue; - } - unset($this->_attrs[$key]); - } + $this->_attrs = array_filter($this->_attrs, function($key) { + return substr($key, 0, 4) === 'form'; + }, ARRAY_FILTER_USE_KEY); } private function _wrapperInput(string $input) : string { - extract($this->_get('help')); + extract($this->_get('help', 'wrapperAttrs')); $id = $this->_getId(); $label = $this->renderLabel(); $helpText = $help ? ''.$this->_getText($help).'' : ''; - return '
'.$label.$input.$helpText.'
'; + + $attrs = $wrapperAttrs ?? []; + $attrs['class'] = join(' ', array_filter([$attrs['class'] ?? null, 'form-group'])); + $attributes = $this->_buildHtmlAttrs($attrs, false); + + return '
'.$label.$input.$helpText.'
'; } private function _getId() { @@ -131,7 +165,14 @@ private function _getValue() { return old($name, $value) ?? ($formData[$name] ?? null); } - private function _buildHtmlAttrs($attributes) : string { + private function _buildHtmlAttrs(array $attributes, $appendAttrs = true) : string { + + if($appendAttrs){ + extract($this->_get('attrs')); + $attributes['class'] = join(' ', array_filter([$attributes['class'] ?? null, $attrs['class'] ?? null])); + $attributes = array_merge($attrs ?? [], $attributes); + } + return join(' ', array_filter( array_map(function($key) use ($attributes) { $value = $attributes[$key]; diff --git a/src/FormService.php b/src/FormService.php index ff7bbcb..78e6fd9 100644 --- a/src/FormService.php +++ b/src/FormService.php @@ -160,7 +160,7 @@ public function locale(string $path): FormService */ public function autocomplete($value = true): FormService { - return $this; + return $this->_set('autocomplete', $value); } /** @@ -181,7 +181,7 @@ public function inline(bool $inline = true): FormService */ public function url(string $url): FormService { - return $this->_set('formUrl', url($url)); + return $this->_set('url', url($url)); } /** @@ -193,7 +193,7 @@ public function url(string $url): FormService */ public function route(string $route, array $params = []): FormService { - return $this->_set('formUrl', route($route, $params)); + return $this->_set('url', route($route, $params)); } /** @@ -204,7 +204,7 @@ public function route(string $route, array $params = []): FormService */ public function fieldsetOpen(string $legend = null): FormService { - return $this; + return $this->render('fieldsetOpen')->_set('legend', $legend); } /** @@ -214,7 +214,7 @@ public function fieldsetOpen(string $legend = null): FormService */ public function fieldsetClose(): FormService { - return $this; + return $this->render('fieldsetClose'); } /** @@ -237,7 +237,7 @@ public function help(string $text): FormService */ public function file(string $name = null, string $label = null): FormService { - return $this; + return $this->render('input')->type('file')->name($name)->label($label); } /** @@ -263,7 +263,7 @@ public function text(string $name = null, $label = null, string $default = null) */ public function date(string $name = null, $label = null, string $default = null): FormService { - return $this; + return $this->render('input')->type('date')->name($name)->label($label)->value($default); } /** @@ -276,7 +276,7 @@ public function date(string $name = null, $label = null, string $default = null) */ public function time(string $name = null, $label = null, string $default = null): FormService { - return $this; + return $this->render('input')->type('time')->name($name)->label($label)->value($default); } /** @@ -289,7 +289,7 @@ public function time(string $name = null, $label = null, string $default = null) */ public function tel(string $name = null, $label = null, string $default = null): FormService { - return $this; + return $this->render('input')->type('tel')->name($name)->label($label)->value($default); } /** @@ -302,7 +302,7 @@ public function tel(string $name = null, $label = null, string $default = null): */ public function urlInput(string $name = null, $label = null, string $default = null): FormService { - return $this; + return $this->render('input')->type('url')->name($name)->label($label)->value($default); } /** @@ -315,7 +315,7 @@ public function urlInput(string $name = null, $label = null, string $default = n */ public function range(string $name = null, $label = null, string $default = null): FormService { - return $this; + return $this->render('input')->type('range')->name($name)->label($label)->value($default); } /** @@ -542,7 +542,7 @@ public function size(string $size = null): FormService */ public function lg(): FormService { - return $this->_set('size', 'lg'); + return $this->size('lg'); } /** @@ -552,7 +552,7 @@ public function lg(): FormService */ public function sm(): FormService { - return $this->_set('size', 'sm'); + return $this->size('sm'); } /** @@ -573,7 +573,7 @@ public function color(string $color = null): FormService */ public function primary(): FormService { - return $this; + return $this->color('primary'); } /** @@ -583,7 +583,7 @@ public function primary(): FormService */ public function secondary(): FormService { - return $this; + return $this->color('secondary'); } /** @@ -593,7 +593,7 @@ public function secondary(): FormService */ public function success(): FormService { - return $this; + return $this->color('success'); } /** @@ -603,7 +603,7 @@ public function success(): FormService */ public function danger(): FormService { - return $this; + return $this->color('danger'); } /** @@ -613,7 +613,7 @@ public function danger(): FormService */ public function warning(): FormService { - return $this; + return $this->color('warning'); } /** @@ -623,7 +623,7 @@ public function warning(): FormService */ public function info(): FormService { - return $this; + return $this->color('info'); } /** @@ -633,7 +633,7 @@ public function info(): FormService */ public function light(): FormService { - return $this; + return $this->color('light'); } /** @@ -643,7 +643,7 @@ public function light(): FormService */ public function dark(): FormService { - return $this; + return $this->color('dark'); } /** @@ -730,7 +730,7 @@ public function placeholder($placeholder): FormService */ public function attrs(array $attrs = []): FormService { - return $this; + return $this->_set('attrs', $attrs); } /** @@ -741,7 +741,7 @@ public function attrs(array $attrs = []): FormService */ public function wrapperAttrs(array $attrs = []): FormService { - return $this; + return $this->_set('wrapperAttrs', $attrs); } /** From 74a3902752411202cc970305858843943ccc3e9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sousa?= Date: Sun, 24 Feb 2019 11:21:12 +0000 Subject: [PATCH 03/35] Adding min and max methodss --- src/FormBuilder.php | 4 +++- src/FormService.php | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/FormBuilder.php b/src/FormBuilder.php index 5142f83..7a735b7 100644 --- a/src/FormBuilder.php +++ b/src/FormBuilder.php @@ -87,7 +87,7 @@ private function _renderButton() : string { } private function _renderInput() : string { - extract($this->_get('type', 'name', 'placeholder', 'help', 'disabled', 'autocomplete')); + extract($this->_get('type', 'name', 'placeholder', 'help', 'disabled', 'autocomplete', 'min', 'max')); $class = 'form-control'; switch($type){ @@ -107,6 +107,8 @@ private function _renderInput() : string { 'value' => $this->_getValue(), 'class' => $class, 'id' => $id, + 'min' => $min, + 'max' => $max, 'autocomplete' => $autocomplete, 'placeholder' => $this->_getText($placeholder), 'aria-describedby' => $help ? 'help-'.$id : null, diff --git a/src/FormService.php b/src/FormService.php index 78e6fd9..1c501f9 100644 --- a/src/FormService.php +++ b/src/FormService.php @@ -318,6 +318,26 @@ public function range(string $name = null, $label = null, string $default = null return $this->render('input')->type('range')->name($name)->label($label)->value($default); } + /** + * Set a minimum value for a field + * @param string $value + * @return FormService + */ + public function min($value) + { + return $this->_set('min', $value); + } + + /** + * Set a maximum value for a field + * @param string $value + * @return FormService + */ + public function max($value) + { + return $this->_set('max', $value); + } + /** * Create a hidden input * From bcac52606effd3223bf4753c19eac647b6ce0457 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sousa?= Date: Sun, 24 Feb 2019 11:42:46 +0000 Subject: [PATCH 04/35] Adding hidden input --- src/FormBuilder.php | 56 +++++++++++++++++++++++++++++++-------------- src/FormService.php | 2 +- 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/FormBuilder.php b/src/FormBuilder.php index 7a735b7..9b76f1c 100644 --- a/src/FormBuilder.php +++ b/src/FormBuilder.php @@ -87,9 +87,17 @@ private function _renderButton() : string { } private function _renderInput() : string { + $attributes = $this->getInputAttributes(); + $attrs = $this->_buildHtmlAttrs($attributes); + $input = ''; + return $this->_wrapperInput($input); + } + + private function getInputAttributes() : array + { extract($this->_get('type', 'name', 'placeholder', 'help', 'disabled', 'autocomplete', 'min', 'max')); + $class = 'form-control'; - switch($type){ case 'file': $class .= '-file'; @@ -99,31 +107,39 @@ private function _renderInput() : string { break; } - $id = $this->_getId(); - $attrs = $this->_buildHtmlAttrs([ + + $attributes = [ 'type' => $type, 'name' => $name, 'value' => $this->_getValue(), - 'class' => $class, - 'id' => $id, - 'min' => $min, - 'max' => $max, - 'autocomplete' => $autocomplete, - 'placeholder' => $this->_getText($placeholder), - 'aria-describedby' => $help ? 'help-'.$id : null, - 'disabled' => $disabled - ]); - return $this->_wrapperInput(''); + 'id' => $id + ]; + + if($type !== 'hidden') { + $attributes = array_merge($attributes, [ + 'class' => $class, + 'min' => $min, + 'max' => $max, + 'autocomplete' => $autocomplete, + 'placeholder' => $this->_getText($placeholder), + 'aria-describedby' => $help ? 'help-'.$id : null, + 'disabled' => $disabled + ]); + } + + return $attributes; } - private function renderLabel() : string { + private function renderLabel() : string + { extract($this->_get('label')); $id = $this->_getId(); return ''; } - private function _getText($key){ + private function _getText($key) + { extract($this->_get('formLocale')); if($formLocale){ return __($formLocale . '.' . $key); @@ -131,7 +147,8 @@ private function _getText($key){ return $key; } - private function _resetAttributes($resetAll = false) { + private function _resetAttributes($resetAll = false) + { // Remove all attributes if($resetAll) { $this->_attrs = []; @@ -145,7 +162,12 @@ private function _resetAttributes($resetAll = false) { } private function _wrapperInput(string $input) : string { - extract($this->_get('help', 'wrapperAttrs')); + extract($this->_get('type', 'help', 'wrapperAttrs')); + + if($type === 'hidden') { + return $input; + } + $id = $this->_getId(); $label = $this->renderLabel(); $helpText = $help ? ''.$this->_getText($help).'' : ''; diff --git a/src/FormService.php b/src/FormService.php index 1c501f9..881f165 100644 --- a/src/FormService.php +++ b/src/FormService.php @@ -347,7 +347,7 @@ public function max($value) */ public function hidden(string $name = null, string $default = null): FormService { - return $this; + return $this->render('input')->type('hidden')->name($name)->value($default); } /** From 172d65821fe9ec5031eab21a0275fe99c9d084ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sousa?= Date: Sun, 24 Feb 2019 11:45:39 +0000 Subject: [PATCH 05/35] Adding custom id attribute --- src/FormBuilder.php | 7 ++++++- src/FormService.php | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/FormBuilder.php b/src/FormBuilder.php index 9b76f1c..18cd7b5 100644 --- a/src/FormBuilder.php +++ b/src/FormBuilder.php @@ -180,7 +180,12 @@ private function _wrapperInput(string $input) : string { } private function _getId() { - extract($this->_get('name', 'formIdPrefix')); + extract($this->_get('id', 'name', 'formIdPrefix')); + + if($id){ + return $id; + } + return ($formIdPrefix ?? 'inp-') . $name; } diff --git a/src/FormService.php b/src/FormService.php index 881f165..e276e10 100644 --- a/src/FormService.php +++ b/src/FormService.php @@ -530,7 +530,7 @@ public function render(string $render): FormService */ public function id($id): FormService { - return $this; + return $this->_set('id', $id); } /** From 7a46f5d3389486abe109c3ed5768c6e7e38e7929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sousa?= Date: Sun, 24 Feb 2019 11:48:17 +0000 Subject: [PATCH 06/35] Adding readonly attribute --- src/FormBuilder.php | 25 +++++++++++++------------ src/FormService.php | 2 +- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/FormBuilder.php b/src/FormBuilder.php index 18cd7b5..9b6aba7 100644 --- a/src/FormBuilder.php +++ b/src/FormBuilder.php @@ -95,7 +95,7 @@ private function _renderInput() : string { private function getInputAttributes() : array { - extract($this->_get('type', 'name', 'placeholder', 'help', 'disabled', 'autocomplete', 'min', 'max')); + extract($this->_get('type', 'name', 'placeholder', 'help', 'disabled', 'readonly', 'autocomplete', 'min', 'max')); $class = 'form-control'; switch($type){ @@ -116,19 +116,20 @@ private function getInputAttributes() : array 'id' => $id ]; - if($type !== 'hidden') { - $attributes = array_merge($attributes, [ - 'class' => $class, - 'min' => $min, - 'max' => $max, - 'autocomplete' => $autocomplete, - 'placeholder' => $this->_getText($placeholder), - 'aria-describedby' => $help ? 'help-'.$id : null, - 'disabled' => $disabled - ]); + if($type === 'hidden') { + return $attributes; } - return $attributes; + return array_merge($attributes, [ + 'class' => $class, + 'min' => $min, + 'max' => $max, + 'autocomplete' => $autocomplete, + 'placeholder' => $this->_getText($placeholder), + 'aria-describedby' => $help ? 'help-'.$id : null, + 'disabled' => $disabled, + 'readonly' => $readonly + ]); } private function renderLabel() : string diff --git a/src/FormService.php b/src/FormService.php index e276e10..aee9ba3 100644 --- a/src/FormService.php +++ b/src/FormService.php @@ -706,7 +706,7 @@ public function block(bool $status= true): FormService */ public function readonly($status = true): FormService { - return $this; + return $this->_set('readonly', $status); } /** From 5752057f7ad18f663c515b5f18a3c8d20782bd58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sousa?= Date: Sun, 24 Feb 2019 11:51:35 +0000 Subject: [PATCH 07/35] Adding required attribute --- src/FormBuilder.php | 5 +++-- src/FormService.php | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/FormBuilder.php b/src/FormBuilder.php index 9b6aba7..b1f7a69 100644 --- a/src/FormBuilder.php +++ b/src/FormBuilder.php @@ -95,7 +95,7 @@ private function _renderInput() : string { private function getInputAttributes() : array { - extract($this->_get('type', 'name', 'placeholder', 'help', 'disabled', 'readonly', 'autocomplete', 'min', 'max')); + extract($this->_get('type', 'name', 'placeholder', 'help', 'disabled', 'readonly', 'required', 'autocomplete', 'min', 'max')); $class = 'form-control'; switch($type){ @@ -128,7 +128,8 @@ private function getInputAttributes() : array 'placeholder' => $this->_getText($placeholder), 'aria-describedby' => $help ? 'help-'.$id : null, 'disabled' => $disabled, - 'readonly' => $readonly + 'readonly' => $readonly, + 'required' => $required ]); } diff --git a/src/FormService.php b/src/FormService.php index aee9ba3..d2e3bee 100644 --- a/src/FormService.php +++ b/src/FormService.php @@ -728,7 +728,7 @@ public function disabled($status = true): FormService */ public function required($status = true) : FormService { - return $this; + return $this->_set('required', $status); } /** From cdd262ec6dad287c76c93e64b1658b68774db787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sousa?= Date: Sun, 24 Feb 2019 11:53:39 +0000 Subject: [PATCH 08/35] Adding link color --- src/FormService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FormService.php b/src/FormService.php index d2e3bee..d897567 100644 --- a/src/FormService.php +++ b/src/FormService.php @@ -673,7 +673,7 @@ public function dark(): FormService */ public function link(): FormService { - return $this; + return $this->color('link'); } /** From 28d6bbfb2f541a49bbda8707004306cb388a0ef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sousa?= Date: Sun, 24 Feb 2019 11:55:45 +0000 Subject: [PATCH 09/35] Adding outline style --- src/FormBuilder.php | 4 ++-- src/FormService.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/FormBuilder.php b/src/FormBuilder.php index b1f7a69..4f4617b 100644 --- a/src/FormBuilder.php +++ b/src/FormBuilder.php @@ -78,9 +78,9 @@ private function _renderFieldsetClose() : string { } private function _renderButton() : string { - extract($this->_get('size', 'color', 'type', 'value', 'disabled')); + extract($this->_get('size', 'color', 'outline', 'type', 'value', 'disabled')); $sizeCls = !$size ? '' : 'btn-'.$size; - $colorCls = !$color ? '' : 'btn-'.$color; + $colorCls = !$color ? '' : 'btn-'.($outline ? 'outline-' : '').$color; $class = join(' ', array_filter(['btn', $colorCls, $sizeCls])); $attrs = $this->_buildHtmlAttrs(['type' => $type, 'class' => $class, 'disabled' => $disabled]); return ''; diff --git a/src/FormService.php b/src/FormService.php index d897567..6064cd8 100644 --- a/src/FormService.php +++ b/src/FormService.php @@ -684,7 +684,7 @@ public function link(): FormService */ public function outline(bool $outline = true): FormService { - return $this; + return $this->_set('outline', $outline); } /** From e8f8c1acc7e75fb83474913c1e3106ec4b238e87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sousa?= Date: Sun, 24 Feb 2019 11:57:40 +0000 Subject: [PATCH 10/35] Adding block style --- src/FormBuilder.php | 5 +++-- src/FormService.php | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/FormBuilder.php b/src/FormBuilder.php index 4f4617b..725cb74 100644 --- a/src/FormBuilder.php +++ b/src/FormBuilder.php @@ -78,10 +78,11 @@ private function _renderFieldsetClose() : string { } private function _renderButton() : string { - extract($this->_get('size', 'color', 'outline', 'type', 'value', 'disabled')); + extract($this->_get('size', 'color', 'outline', 'block', 'type', 'value', 'disabled')); $sizeCls = !$size ? '' : 'btn-'.$size; $colorCls = !$color ? '' : 'btn-'.($outline ? 'outline-' : '').$color; - $class = join(' ', array_filter(['btn', $colorCls, $sizeCls])); + $blockCls = !$block ? '' : 'btn-block'; + $class = join(' ', array_filter(['btn', $colorCls, $sizeCls, $blockCls])); $attrs = $this->_buildHtmlAttrs(['type' => $type, 'class' => $class, 'disabled' => $disabled]); return ''; } diff --git a/src/FormService.php b/src/FormService.php index 6064cd8..01270af 100644 --- a/src/FormService.php +++ b/src/FormService.php @@ -679,12 +679,12 @@ public function link(): FormService /** * Set outline style * - * @param bool $outline + * @param bool $status * @return FormService */ - public function outline(bool $outline = true): FormService + public function outline(bool $status = true): FormService { - return $this->_set('outline', $outline); + return $this->_set('outline', $status); } /** @@ -695,7 +695,7 @@ public function outline(bool $outline = true): FormService */ public function block(bool $status= true): FormService { - return $this; + return $this->_set('block', $status); } /** From a71fdc7a90a0708b1ee81227af6aba5f53653ab0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sousa?= Date: Sun, 24 Feb 2019 12:27:14 +0000 Subject: [PATCH 11/35] Adding select field --- src/FormBuilder.php | 59 ++++++++++++++++++++++++++++++++++----------- src/FormService.php | 26 ++++++++++---------- 2 files changed, 58 insertions(+), 27 deletions(-) diff --git a/src/FormBuilder.php b/src/FormBuilder.php index 725cb74..62fdc31 100644 --- a/src/FormBuilder.php +++ b/src/FormBuilder.php @@ -6,7 +6,8 @@ class FormBuilder { private $_attrs = []; - public function set($key, $value) { + public function set($key, $value) + { $formatter = '_format'.ucfirst($key); if(method_exists($this, $formatter)){ $value = $this->$formatter($value); @@ -14,14 +15,16 @@ public function set($key, $value) { $this->_attrs[$key] = $value; } - private function _formatFormData($value){ + private function _formatFormData($value) + { if (is_object($value) && method_exists($value, 'toArray')) { return $value->toArray(); } return $value; } - public function render(): string { + public function render(): string + { $render = $this->_attrs['render']; $methodName = '_render' . ucfirst($render); $output = $this->$methodName(); @@ -29,7 +32,8 @@ public function render(): string { return $output; } - private function _renderFormOpen() : string { + private function _renderFormOpen() : string + { extract($this->_get('method', 'url', 'formMultipart', 'autocomplete')); if(!$method) { @@ -57,12 +61,14 @@ private function _renderFormOpen() : string { return $output; } - private function _renderFormClose() : string { + private function _renderFormClose() : string + { $this->_resetAttributes(true); return ''; } - private function _renderFieldsetOpen() : string { + private function _renderFieldsetOpen() : string + { $output = '
'; extract($this->_get('legend')); @@ -73,7 +79,8 @@ private function _renderFieldsetOpen() : string { return $output; } - private function _renderFieldsetClose() : string { + private function _renderFieldsetClose() : string + { return '
'; } @@ -87,16 +94,33 @@ private function _renderButton() : string { return ''; } - private function _renderInput() : string { + private function _renderInput() : string + { $attributes = $this->getInputAttributes(); $attrs = $this->_buildHtmlAttrs($attributes); - $input = ''; - return $this->_wrapperInput($input); + return $this->_wrapperInput(''); + } + + private function _renderSelect() : string + { + extract($this->_get('options')); + + $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 .= ''; + } + + $attributes = $this->getInputAttributes(); + $attrs = $this->_buildHtmlAttrs($attributes); + return $this->_wrapperInput(''); } private function getInputAttributes() : array { - extract($this->_get('type', 'name', 'placeholder', 'help', 'disabled', 'readonly', 'required', 'autocomplete', 'min', 'max')); + extract($this->_get('render', 'type', 'multiple', 'name', 'placeholder', 'help', 'disabled', 'readonly', 'required', 'autocomplete', 'min', 'max')); $class = 'form-control'; switch($type){ @@ -113,14 +137,20 @@ private function getInputAttributes() : array $attributes = [ 'type' => $type, 'name' => $name, - 'value' => $this->_getValue(), 'id' => $id ]; + // If the field is a hidden field, we don't need add more attributes if($type === 'hidden') { return $attributes; } + if($render !== 'select') { + $attributes['value'] = $this->_getValue(); + } else { + $attributes['multiple'] = $multiple; + } + return array_merge($attributes, [ 'class' => $class, 'min' => $min, @@ -201,8 +231,9 @@ private function _buildHtmlAttrs(array $attributes, $appendAttrs = true) : strin if($appendAttrs){ extract($this->_get('attrs')); - $attributes['class'] = join(' ', array_filter([$attributes['class'] ?? null, $attrs['class'] ?? null])); - $attributes = array_merge($attrs ?? [], $attributes); + $fieldAttrs = $attrs ?? []; + $attributes['class'] = join(' ', array_filter([$attributes['class'] ?? null, $fieldAttrs['class'] ?? null])); + $attributes = array_merge($fieldAttrs, $attributes); } return join(' ', array_filter( diff --git a/src/FormService.php b/src/FormService.php index 01270af..a74bb08 100644 --- a/src/FormService.php +++ b/src/FormService.php @@ -361,7 +361,7 @@ public function hidden(string $name = null, string $default = null): FormService */ public function select(string $name = null, string $label = null, $options = [], $default = null): FormService { - return $this; + return $this->render('select')->name($name)->label($label)->options($options)->value($default); } /** @@ -372,7 +372,18 @@ public function select(string $name = null, string $label = null, $options = [], */ public function options(array $options = []): FormService { - return $this; + return $this->_set('options', $options); + } + + /** + * Set a multiple select attribute + * + * @param bool $multiple + * @return FormService + */ + public function multiple(bool $status = true): FormService + { + return $this->_set('multiple', $status); } /** @@ -764,17 +775,6 @@ public function wrapperAttrs(array $attrs = []): FormService return $this->_set('wrapperAttrs', $attrs); } - /** - * Set a multiple select attribute - * - * @param bool $multiple - * @return FormService - */ - public function multiple(bool $multiple = true): FormService - { - return $this; - } - /** * Set the size * From c6e972677db5a32f9d01cf88237d7087ec939752 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sousa?= Date: Sun, 24 Feb 2019 12:34:26 +0000 Subject: [PATCH 12/35] Adding form-control sizing --- src/FormBuilder.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/FormBuilder.php b/src/FormBuilder.php index 62fdc31..2ac059c 100644 --- a/src/FormBuilder.php +++ b/src/FormBuilder.php @@ -120,7 +120,7 @@ private function _renderSelect() : string private function getInputAttributes() : array { - extract($this->_get('render', 'type', 'multiple', 'name', 'placeholder', 'help', 'disabled', 'readonly', 'required', 'autocomplete', 'min', 'max')); + extract($this->_get('render', 'type', 'multiple', 'name', 'size', 'placeholder', 'help', 'disabled', 'readonly', 'required', 'autocomplete', 'min', 'max')); $class = 'form-control'; switch($type){ @@ -132,6 +132,10 @@ private function getInputAttributes() : array break; } + if($size){ + $class .= ' form-control-' . $size; + } + $id = $this->_getId(); $attributes = [ From e446eb34aed5e34db2fa8ae7e2ccbe61700c79a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Neto?= Date: Sat, 15 Jun 2019 10:27:30 +0100 Subject: [PATCH 13/35] Render all field types --- src/FormBuilder.php | 269 ++++++++++++++++++++++++++++++-------------- src/FormService.php | 63 ++++++++--- 2 files changed, 229 insertions(+), 103 deletions(-) diff --git a/src/FormBuilder.php b/src/FormBuilder.php index 2ac059c..2905f58 100644 --- a/src/FormBuilder.php +++ b/src/FormBuilder.php @@ -2,14 +2,15 @@ namespace NetoJose\Bootstrap4Forms; -class FormBuilder { +class FormBuilder +{ private $_attrs = []; public function set($key, $value) { - $formatter = '_format'.ucfirst($key); - if(method_exists($this, $formatter)){ + $formatter = '_format' . ucfirst($key); + if (method_exists($this, $formatter)) { $value = $this->$formatter($value); } $this->_attrs[$key] = $value; @@ -32,24 +33,25 @@ public function render(): string return $output; } - private function _renderFormOpen() : string + private function _renderFormOpen(): string { - extract($this->_get('method', 'url', 'formMultipart', 'autocomplete')); + extract($this->_get('method', 'url', 'formMultipart', 'formInline', 'autocomplete')); - if(!$method) { + if (!$method) { $method = 'post'; } $enctype = $formMultipart ? 'multipart/form-data' : null; $attrs = $this->_buildHtmlAttrs([ - 'method' => $method, - 'action' => $url, - 'enctype' => $enctype, - 'autocomplete' => $autocomplete + 'method' => $method, + 'action' => $url, + 'enctype' => $enctype, + 'autocomplete' => $autocomplete, + 'class' => $formInline ? 'form-inline' : null, ]); - $output = '
'; + $output = ''; if ($method !== 'get') { $output .= csrf_field(); @@ -61,124 +63,188 @@ private function _renderFormOpen() : string return $output; } - private function _renderFormClose() : string + private function _renderFormClose(): string { $this->_resetAttributes(true); return '
'; } - private function _renderFieldsetOpen() : string + private function _renderFieldsetOpen(): string { $output = '
'; extract($this->_get('legend')); - - if($legend){ + + if ($legend) { $output .= '' . $this->_getText($legend) . ''; } return $output; } - private function _renderFieldsetClose() : string + private function _renderFieldsetClose(): string { return '
'; } - private function _renderButton() : string { - extract($this->_get('size', 'color', 'outline', 'block', 'type', 'value', 'disabled')); - $sizeCls = !$size ? '' : 'btn-'.$size; - $colorCls = !$color ? '' : 'btn-'.($outline ? 'outline-' : '').$color; - $blockCls = !$block ? '' : 'btn-block'; - $class = join(' ', array_filter(['btn', $colorCls, $sizeCls, $blockCls])); - $attrs = $this->_buildHtmlAttrs(['type' => $type, 'class' => $class, 'disabled' => $disabled]); - return ''; - } - - private function _renderInput() : string + private function _renderInput(): string { $attributes = $this->getInputAttributes(); $attrs = $this->_buildHtmlAttrs($attributes); - return $this->_wrapperInput(''); + return $this->_wrapperInput(''); } - private function _renderSelect() : string + private function _renderSelect(): string { extract($this->_get('options')); $fieldValue = $this->_getValue(); $arrValues = is_array($fieldValue) ? $fieldValue : [$fieldValue]; $optionsList = ''; - foreach($options as $value => $label){ + foreach ($options as $value => $label) { $attrs = $this->_buildHtmlAttrs(['value' => $value, 'selected' => in_array($value, $arrValues)], false); $optionsList .= ''; } $attributes = $this->getInputAttributes(); $attrs = $this->_buildHtmlAttrs($attributes); - return $this->_wrapperInput(''); + return $this->_wrapperInput(''); } - private function getInputAttributes() : array + private function _renderTextarea(): string { - extract($this->_get('render', 'type', 'multiple', 'name', 'size', 'placeholder', 'help', 'disabled', 'readonly', 'required', 'autocomplete', 'min', 'max')); - - $class = 'form-control'; - switch($type){ - case 'file': - $class .= '-file'; - break; - case 'range': - $class .= '-range'; - break; - } + $attributes = $this->getInputAttributes(); + $value = $attributes['value']; + unset($attributes['value']); + $attrs = $this->_buildHtmlAttrs($attributes); + return $this->_wrapperInput(''); + } + + private function _renderCheckbox(): string + { + $attributes = $this->getInputAttributes(); + $attrs = $this->_buildHtmlAttrs($attributes); + return $this->_wrapperRadioCheckbox(''); + } + + private function _renderRadio(): string + { + $attributes = $this->getInputAttributes(); + $attrs = $this->_buildHtmlAttrs($attributes); + return $this->_wrapperRadioCheckbox(''); + } + + private function _renderAnchor(): string + { + extract($this->_get('url', 'value')); + $class = $this->getBtnAnchorClasses(); + $attrs = $this->_buildHtmlAttrs(['href' => $url, 'class' => $class]); + return '' . $value . ''; + } + + private function _renderButton(): string + { + extract($this->_get('type', 'value', 'disabled')); + $class = $this->getBtnAnchorClasses(); + $attrs = $this->_buildHtmlAttrs(['type' => $type, 'class' => $class, 'disabled' => $disabled]); + return ''; + } + + private function getBtnAnchorClasses() + { + extract($this->_get('size', 'color', 'outline', 'block', 'type', 'value', 'formInline')); + return $this->createAttrsList( + 'btn', + [$size, 'btn-' . $size], + [$color, 'btn-' . ($outline ? 'outline-' : '') . $color], + [$block, 'btn-block'], + [$formInline, 'mx-sm-2'] + ); + } + + private function isRadioOrCheckbox(): bool + { + extract($this->_get('render')); + return in_array($render, ['checkbox', 'radio']); + } + + private function getInputAttributes(): array + { + extract($this->_get('render', 'type', 'multiple', 'name', 'size', 'placeholder', 'help', 'disabled', 'readonly', 'required', 'autocomplete', 'min', 'max', 'checked')); + + $isRadioOrCheckbox = $this->isRadioOrCheckbox(); + $type = $isRadioOrCheckbox ? $render : $type; + + $class = 'form-check-input'; + if (!$isRadioOrCheckbox) { + $class = 'form-control'; + switch ($type) { + case 'file': + $class .= '-file'; + break; + case 'range': + $class .= '-range'; + break; + } - if($size){ - $class .= ' form-control-' . $size; + if ($size) { + $class .= ' form-control-' . $size; + } } $id = $this->_getId(); $attributes = [ - 'type' => $type, - 'name' => $name, + 'type' => $type, + 'name' => $name, 'id' => $id ]; // If the field is a hidden field, we don't need add more attributes - if($type === 'hidden') { + if ($type === 'hidden') { return $attributes; } - if($render !== 'select') { + if ($render !== 'select') { $attributes['value'] = $this->_getValue(); } else { $attributes['multiple'] = $multiple; } return array_merge($attributes, [ - 'class' => $class, + 'class' => $class, 'min' => $min, 'max' => $max, 'autocomplete' => $autocomplete, 'placeholder' => $this->_getText($placeholder), - 'aria-describedby' => $help ? 'help-'.$id : null, + 'aria-describedby' => $help ? 'help-' . $id : null, + 'checked' => $checked, 'disabled' => $disabled, 'readonly' => $readonly, 'required' => $required ]); } - private function renderLabel() : string + private function renderLabel(): string { - extract($this->_get('label')); + extract($this->_get('label', 'formInline', 'render')); + + $class = in_array($render, ['checkbox', 'radio']) ? 'form-check-label' : ''; + if ($formInline) { + $class = join(' ', [$class, 'mx-sm-2']); + } + $id = $this->_getId(); - return ''; + $attrs = $this->_buildHtmlAttrs([ + 'for' => $id, + 'class' => $class + ]); + return ''; } private function _getText($key) { extract($this->_get('formLocale')); - if($formLocale){ + if ($formLocale) { return __($formLocale . '.' . $key); } return $key; @@ -187,78 +253,109 @@ private function _getText($key) private function _resetAttributes($resetAll = false) { // Remove all attributes - if($resetAll) { + if ($resetAll) { $this->_attrs = []; return; } - + // Keep attributes which key starting with 'form' - $this->_attrs = array_filter($this->_attrs, function($key) { + $this->_attrs = array_filter($this->_attrs, function ($key) { return substr($key, 0, 4) === 'form'; }, ARRAY_FILTER_USE_KEY); } - private function _wrapperInput(string $input) : string { - extract($this->_get('type', 'help', 'wrapperAttrs')); + private function _wrapperInput(string $input): string + { + extract($this->_get('type', 'help', 'wrapperAttrs', 'formInline')); - if($type === 'hidden') { + if ($type === 'hidden') { return $input; } - $id = $this->_getId(); - $label = $this->renderLabel(); - $helpText = $help ? ''.$this->_getText($help).'' : ''; - - $attrs = $wrapperAttrs ?? []; - $attrs['class'] = join(' ', array_filter([$attrs['class'] ?? null, 'form-group'])); + $id = $this->_getId(); + $label = $this->renderLabel(); + $helpText = $help ? '' . $this->_getText($help) . '' : ''; + $attrs = $wrapperAttrs ?? []; + $attrs['class'] = $this->createAttrsList( + $attrs['class'] ?? null, + $formInline ? 'input-group' : 'form-group' + ); $attributes = $this->_buildHtmlAttrs($attrs, false); - return '
'.$label.$input.$helpText.'
'; + return '
' . $label . $input . $helpText . '
'; } - private function _getId() { - extract($this->_get('id', 'name', 'formIdPrefix')); + private function _wrapperRadioCheckbox(string $input): string + { + extract($this->_get('inline')); - if($id){ + $class = $this->createAttrsList('form-check', [$inline, 'form-check-inline']); + $label = $this->renderLabel(); + return ' +
+ ' . $input . ' + ' . $label . ' +
'; + } + + private function _getId() + { + extract($this->_get('id', 'name', 'formIdPrefix', 'render', 'value')); + + if ($id) { return $id; } - return ($formIdPrefix ?? 'inp-') . $name; + return ($formIdPrefix ?? 'inp-') . $name . ($render === 'radio' ? '-' . $value : ''); } - private function _getValue() { + private function _getValue() + { extract($this->_get('name', 'value', 'formData')); return old($name, $value) ?? ($formData[$name] ?? null); } - private function _buildHtmlAttrs(array $attributes, $appendAttrs = true) : string { - - if($appendAttrs){ + private function _buildHtmlAttrs(array $attributes, $appendAttrs = true): string + { + + if ($appendAttrs) { extract($this->_get('attrs')); $fieldAttrs = $attrs ?? []; - $attributes['class'] = join(' ', array_filter([$attributes['class'] ?? null, $fieldAttrs['class'] ?? null])); + $attributes['class'] = $this->createAttrsList($attributes['class'] ?? null, $fieldAttrs['class'] ?? null); $attributes = array_merge($fieldAttrs, $attributes); } - + return join(' ', array_filter( - array_map(function($key) use ($attributes) { + array_map(function ($key) use ($attributes) { $value = $attributes[$key]; - if(is_bool($value)){ + if (is_bool($value)) { return $value ? $key : ''; - } elseif($value) { - return $key.'="'.htmlspecialchars($value).'"'; + } elseif ($value) { + return $key . '="' . htmlspecialchars($value) . '"'; } return ''; }, array_keys($attributes)) )); } - private function _get(...$keys) : array { + private function createAttrsList(...$items) + { + $attrs = []; + foreach ($items as $item) { + if (is_array($item)) { + $item = $item[0] ? $item[1] : null; + } + $attrs[] = $item; + } + return join(' ', array_filter($attrs)); + } + + private function _get(...$keys): array + { $return = []; - foreach($keys as $key){ + foreach ($keys as $key) { $return[$key] = $this->_attrs[$key] ?? null; } return $return; } - -} \ No newline at end of file +} diff --git a/src/FormService.php b/src/FormService.php index a74bb08..1354d90 100644 --- a/src/FormService.php +++ b/src/FormService.php @@ -7,7 +7,8 @@ * * @author neto */ -class FormService { +class FormService +{ /** * Create a new FormSevice instance @@ -164,13 +165,13 @@ public function autocomplete($value = true): FormService } /** - * Set inline style for checkbox and radio inputs + * Set inline form style * @param bool $inline * @return FormService */ public function inline(bool $inline = true): FormService { - return $this; + return $this->_set('formInline', $inline); } /** @@ -390,28 +391,38 @@ public function multiple(bool $status = true): FormService * Create a checkbox input * * @param string $name - * @param string $label * @param string $value - * @param string $default + * @param string $label + * @param bool $checked * @return FormService */ - public function checkbox(string $name = null, string $label = null, string $value = null, string $default = null): FormService + public function checkbox(string $name = null, string $value = 'on', string $label = null, bool $checked = null): FormService { - return $this; + return $this->_radioOrCheckbox('checkbox', $name, $value, $label, $checked); } /** * Create a radio input * * @param string $name - * @param string $label * @param string $value - * @param string $default + * @param string $label + * @param bool $checked * @return FormService */ - public function radio(string $name = null, string $label = null, string $value = null, string $default = null): FormService + public function radio(string $name = null, string $value = null, string $label = null, bool $checked = null): FormService { - return $this; + return $this->_radioOrCheckbox('radio', $name, $value, $label, $checked); + } + + /** + * Set inline input style + * @param bool $inline + * @return FormService + */ + public function inlineInput(bool $inline = true): FormService + { + return $this->_set('inline', $inline); } /** @@ -424,7 +435,7 @@ public function radio(string $name = null, string $label = null, string $value = */ public function textarea(string $name = null, $label = null, string $default = null): FormService { - return $this; + return $this->_set('render', 'textarea')->name($name)->label($label)->value($default); } /** @@ -484,9 +495,9 @@ public function reset(string $value, $color = 'primary', $size = null): FormServ * @param string $url * @return FormService */ - public function anchor(string $value, $url = null): FormService + public function anchor(string $value, $url = null, $color = 'primary', $size = null): FormService { - return $this; + return $this->_set('render', 'anchor')->value($value)->url($url)->color($color)->size($size); } /** @@ -497,7 +508,7 @@ public function anchor(string $value, $url = null): FormService */ public function checked(bool $checked = true): FormService { - return $this; + return $this->_set('checked', $checked); } /** @@ -704,7 +715,7 @@ public function outline(bool $status = true): FormService * @param bool $status * @return FormService */ - public function block(bool $status= true): FormService + public function block(bool $status = true): FormService { return $this->_set('block', $status); } @@ -737,7 +748,7 @@ public function disabled($status = true): FormService * @param bool $status * @return FormService */ - public function required($status = true) : FormService + public function required($status = true): FormService { return $this->_set('required', $status); } @@ -775,6 +786,24 @@ public function wrapperAttrs(array $attrs = []): FormService return $this->_set('wrapperAttrs', $attrs); } + /** + * Create radio or checkbox input + * + * @param string $render + * @param string $name + * @param string $value + * @param string $label + * @param mixed $checked + * @return FormService + */ + private function _radioOrCheckbox($render, $name, $value, $label, $checked): FormService + { + if (is_bool($checked)) { + $this->checked($checked); + } + return $this->_set('render', $render)->name($name)->label($label)->value($value); + } + /** * Set the size * From f64f4b43e793d4dcef2350af1d8a8700ff6e1864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Neto?= Date: Sat, 15 Jun 2019 10:35:52 +0100 Subject: [PATCH 14/35] Fixing anchor url param --- src/FormService.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/FormService.php b/src/FormService.php index 1354d90..3e57666 100644 --- a/src/FormService.php +++ b/src/FormService.php @@ -180,9 +180,9 @@ public function inline(bool $inline = true): FormService * @param string $url * @return FormService */ - public function url(string $url): FormService + public function url(string $url = null): FormService { - return $this->_set('url', url($url)); + return $this->_set('url', url($url ?? '')); } /** From 32e851e7ec67a8f59e3cde243213d75dcb6734bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Neto?= Date: Sat, 15 Jun 2019 12:20:04 +0100 Subject: [PATCH 15/35] Error messages --- src/FormBuilder.php | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/FormBuilder.php b/src/FormBuilder.php index 2905f58..2957293 100644 --- a/src/FormBuilder.php +++ b/src/FormBuilder.php @@ -2,6 +2,8 @@ namespace NetoJose\Bootstrap4Forms; +use Illuminate\Support\ViewErrorBag; + class FormBuilder { @@ -193,6 +195,10 @@ private function getInputAttributes(): array $id = $this->_getId(); + if ($this->errors()->has($name)) { + $class .= ' is-invalid'; + } + $attributes = [ 'type' => $type, 'name' => $name, @@ -266,7 +272,7 @@ private function _resetAttributes($resetAll = false) private function _wrapperInput(string $input): string { - extract($this->_get('type', 'help', 'wrapperAttrs', 'formInline')); + extract($this->_get('type', 'help', 'wrapperAttrs', 'formInline', 'name')); if ($type === 'hidden') { return $input; @@ -275,6 +281,7 @@ private function _wrapperInput(string $input): string $id = $this->_getId(); $label = $this->renderLabel(); $helpText = $help ? '' . $this->_getText($help) . '' : ''; + $error = $this->getInputErrorMarkup($name); $attrs = $wrapperAttrs ?? []; $attrs['class'] = $this->createAttrsList( $attrs['class'] ?? null, @@ -282,19 +289,29 @@ private function _wrapperInput(string $input): string ); $attributes = $this->_buildHtmlAttrs($attrs, false); - return '
' . $label . $input . $helpText . '
'; + return '
' . $label . $input . $helpText . $error . '
'; } private function _wrapperRadioCheckbox(string $input): string { - extract($this->_get('inline')); + extract($this->_get('inline', 'name')); $class = $this->createAttrsList('form-check', [$inline, 'form-check-inline']); $label = $this->renderLabel(); + $error = $this->getInputErrorMarkup($name); return '
' . $input . ' ' . $label . ' + ' . $error . ' +
'; + } + + private function getInputErrorMarkup(string $name): string + { + return ' +
+ ' . $this->errors()->first($name) . '
'; } @@ -330,7 +347,7 @@ private function _buildHtmlAttrs(array $attributes, $appendAttrs = true): string $value = $attributes[$key]; if (is_bool($value)) { return $value ? $key : ''; - } elseif ($value) { + } elseif ($value !== null) { return $key . '="' . htmlspecialchars($value) . '"'; } return ''; @@ -350,6 +367,11 @@ private function createAttrsList(...$items) return join(' ', array_filter($attrs)); } + private function errors(): ViewErrorBag + { + return session('errors', app(ViewErrorBag::class)); + } + private function _get(...$keys): array { $return = []; From e27e929538f2111b61e127e062ccbbaecf88a10f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Neto?= Date: Sun, 16 Jun 2019 09:15:06 +0100 Subject: [PATCH 16/35] Show all error messages --- src/FormBuilder.php | 19 +++++++++++++++++++ src/FormService.php | 11 +++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/FormBuilder.php b/src/FormBuilder.php index 2957293..1354b3d 100644 --- a/src/FormBuilder.php +++ b/src/FormBuilder.php @@ -88,6 +88,25 @@ private function _renderFieldsetClose(): string return ''; } + private function _renderErrors(): string + { + $errors = $this->errors()->all(); + if (count($errors) < 1) { + return ''; + } + + extract($this->_get('errorsHeader')); + + $output = ''; + } + private function _renderInput(): string { $attributes = $this->getInputAttributes(); diff --git a/src/FormService.php b/src/FormService.php index 3e57666..386a488 100644 --- a/src/FormService.php +++ b/src/FormService.php @@ -48,6 +48,17 @@ public function close(): FormService return $this->_set('render', 'formClose'); } + /** + * Show all validation errors + * + * @param string $title + * @return FormService + */ + public function errors(string $title = null): FormService + { + return $this->_set('render', 'errors')->_set('errorsHeader', $title); + } + /** * Set a prefix id for all inputs * From f1efba964880a8e0e46a58ebebaaedca87222a1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Neto?= Date: Sun, 16 Jun 2019 09:41:28 +0100 Subject: [PATCH 17/35] All errors component accept attrs and id --- src/FormBuilder.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/FormBuilder.php b/src/FormBuilder.php index 1354b3d..07ab015 100644 --- a/src/FormBuilder.php +++ b/src/FormBuilder.php @@ -95,9 +95,9 @@ private function _renderErrors(): string return ''; } - extract($this->_get('errorsHeader')); - - $output = '