okipa / laravel-form-components
即用可定制表单组件。
Requires
- php: 8.1.*|8.2.*
- illuminate/contracts: ^9.0|^10.0
Requires (Dev)
- brianium/paratest: ^6.4
- laravel/pint: ^1.1
- nunomaduro/collision: ^6.0
- nunomaduro/larastan: ^2.0
- orchestra/testbench: ^7.0|^8.0
- phpmd/phpmd: ^2.11
- phpstan/phpstan-mockery: ^1.0
- roave/security-advisories: dev-latest
README
节省时间并充分利用一组动态、即用可定制和完全可定制的表单组件。
组件与 Livewire 兼容,并可用于以下 UI 框架
- Bootstrap 5
- Bootstrap 4
- TailwindCSS 3(即将推出功能)
发现这个包很有帮助?请考虑支持我的工作!
兼容性
升级指南
使用示例
只需在视图中调用所需的组件,然后让此包处理耗时的 HTML 生成部分。
<x:form::form class="row" method="PUT" :action="route('user.update', $user)" :bind="$user"> <div class="col-md-6"> <x:form::input name="name"/> <x:form::input type="email" name="email"/> <x:form::textarea name="biography" :locales="['fr', 'en']"/> </div> <div class="col-md-6"> <x:form::select name="hobbies" :options="[1 => 'Sport', 2 => 'Cinema', 3 => 'Literature', 4 => 'Travel']" caption="Select your favorite hobbies." multiple/> <x:form::checkbox name="technologies" :group="[1 => 'Laravel', 2 => 'Bootstrap', 3 => 'Tailwind', 4 => 'Livewire']" inline/> <x:form::radio name="gender" :group="[1 => 'Male', 2 => 'Female', 3 => 'Other']" inline/> <x:form::toggle-switch name="active"/> </div> <div class="col-12 mt-2"> <x:form::button.link class="btn-secondary me-3">{{ __('Cancel') }}</x:form::button.link> <x:form::button.submit/> </div> </x:form:form>
并显示这些组件
目录
安装
您可以通过 composer 安装此包
composer require okipa/laravel-form-components
配置
您可以使用以下命令发布配置文件
php artisan vendor:publish --tag=form-components:config
在其配置中,此包允许您选择要使用的 UI 框架。
请注意,在使用此包之前,您必须安装和配置您想要使用的 UI 框架。
视图
您可以发布包视图以进行自定义(如果需要)
php artisan vendor:publish --tag=form-components:views
组件
表单
组件可以包裹在表单组件中。
如果没有设置自定义方法,则默认将设置 GET
方法。
当需要时,将自动生成隐藏的 CSRF 和欺骗方法字段,根据定义的表单方法
- 您不需要定义
@method()
指令,可以直接在action
属性中声明您的PUT
、PATCH
或DELETE
操作 - 您不需要定义
@csrf()
指令,它将与POST
、PUT
、PATCH
和DELETE
操作自动声明
表单使用默认的 novalidate
HTML 属性生成,这阻止了浏览器验证,以利于服务器端验证(这对于安全问题来说是一个好习惯)。
<x:form::form method="PUT"> <x:form::input name="first_name"/> ... </x:form::form>
输入和文本区域
将输入和文本区域添加到您的表单中。
如果您没有为输入设置自定义类型,它将采用默认的 text
类型。
单选按钮、复选框和按钮输入必须使用它们自己的组件,因为它们的行为不同。
文本区域组件可以像输入组件一样使用,但不需要声明类型。
<x:form::input type="file" name="avatar"/> <x:form::input name="first_name"/> <x:form::input type="email" name="email"/> ... <x:form::textarea name="description"/>
选择
在您的表单中设置选择组件。
通过提供关联值/标签数组自动生成选项。
HTML 选择元素本身不接受占位符属性,但是选择组件允许您处理一个类似于占位符的选项被添加到其他选项之前。这个占位符将与其他组件一样表现。
默认情况下,此选择占位符选项被选中、禁用并隐藏。然而,如果您需要设置一个可空的 nullable
字段,例如,您将能够允许它被选中。为此,只需将 allowPlaceholderToBeSelected
属性添加到您的组件中。
在多选模式下,此包将负责将名称转换为数组名称,因此您无需手动添加。
@php($options = [1 => 'Laravel', 2 => 'Bootstrap', 3 => 'Tailwind', 4 => 'Livewire']) <x:form::select name="hobby" placeholder="What is your hobby prefered hobby?" :options="$options" selected="1"/> <x:form::select name="hobbies" :options="$options" :selected="[2, 3]" allowPlaceholderToBeSelected multiple/> {{-- You'll be able to selected the placeholder and the name will be converted to hobbies[] --}}
复选框、开关和单选按钮
复选框、开关和单选按钮组件可供您使用。
由于单选输入从不单独使用,因此使用它们时,您必须声明一个必需的 group
属性,等待一个值/标签关联数组,单选字段将从其中生成。
至于复选框和开关输入,您可以在单选或组模式下使用它们。要在组模式下使用它们,您还必须声明一个 group
属性。
在组模式下,此包将负责将名称转换为数组名称,因此您无需手动添加。
如果您想显示这些输入组件并排显示,只需定义一个 inline
属性。
<x:form::checkbox name="newsletter_subscription" :checked="true"/> {{-- 1 generated checkbox --}} <x:form::checkbox name="technologies" :group="['laravel' => 'Laravel', 'bootstrap' => 'Bootstrap']" :checked="laravel"/> {{-- 2 generated checkboxes --}} <x:form::toggle-switch name="active" :checked="false" inline/> {{-- 1 generated toggle switch with inline mode --}} <x:form::toggle-switch name="technologies" :group="['tailwind' => 'Tailwind', 'livewire" => 'Livewire']" :checked="livewire"/> {{-- 2 generated toggle switches --}} <x:form::radio name="gender" :group="['female' => 'Female', 'male' => 'Male']" :checked="male" inline/> {{-- 2 generated radios with inline mode --}}
按钮
提供提交和链接按钮组件。
提交按钮允许您触发表单,如果未定义,将提供默认的 __('Submit')
正文。
链接按钮允许您通过提供类似按钮的显示方式来设置表单中的操作,如 Back
或 Cancel
。由于此组件是HTML链接,它将通过分析其正文来提供默认标题。
默认情况下,如果没有定义自定义类属性,这两个组件将设置一个基本背景颜色。
<x:form::form> ... <div class="d-grid"> <x:form::button.submit>Submit this form</x:form::submit> {{-- Will provide `btn-primary` class with Bootstrap UI --}} <x:form::button.link class="btn-secondary" href="{{ back() }}"> {{-- Will auto-generate `title="Back"` --}} <i class="fas fa-undo fa-fw"></i> Back </x:form::submit> </div> </x:form::form>
如何
处理属性和类
提供组件是使用 Blade组件 构建的。
遵循Blade组件的工作方式,您可以设置任何HTML属性和类。
- 属性将替换默认属性。
- 类将合并到现有类中。
设置 id
按照您为任何HTML元素所做的方式定义组件ID。
如果没有设置自定义ID,将使用kebab cased <type>-<name>
值生成ID。
<x:form::input id="custom-id" name="first_name"/> {{-- Default id: `input-first-name` --}} <x:form::textarea id="custom-id" name="first_name"/> {{-- Default id: `textarea-first-name` --}}
启用或禁用输入底部外边距。
默认情况下,所有输入组件都将声明底部外边距,以便在表单中正确定位。
有时您可能需要禁用此默认底部外边距:您可以将 marginBottom
属性设置为 false
来完成此操作。
<x:form::input name="first_name"/> {{-- Will declare a bottom margin --}} <x:form::textarea name="first_name" :marginBottom="false"/> {{-- Will not declare any bottom margin --}}
管理标签和占位符
您可以在所有输入组件上定义标签(除了 Radio)。
如果没有定义自定义标签,标签将采用 __('validation.attributes.<name>)
默认值。
遵循相同的行为,所有允许使用 placeholder
(包括 Select)的输入组件将提供一个默认的占位符,该占位符将采用 label
值。
您可以通过设置自定义占位符来覆盖此默认值。
您还可以通过将它们设置为 false
来隐藏自动生成的标签和占位符。
<x:form::input name="first_name" label="First Name" placeholder="Please fill your first name..."/> {{-- Will display the custom label and placeholder --}} <x:form::input name="last_name" :label="false" :placeholder="false"/> {{-- Will hide the label and placeholder --}} <x:form::input type="tel" name="phone_number"/> {{-- Will display default auto-generated label and placeholder --}}
处理浮动标签显示
此包允许您启用或禁用浮动标签显示。
您可以使用 config('form-components.floating_label')
配置来设置全局浮动标签行为。
您将能够在表单级别覆盖所有包含组件的此全局行为。
<x:form::form :floatingLabel="true"> <x:form::input name="first_name"/> {{-- Will display a floating label even if it has been disabled in config --}} </x:form::form>
最后,您还可以在组件本身上覆盖所有其他定义的行为。
<x:form::input name="first_name" :floatingLabel="true"/>
设置附加组件
您可以在输入和文本区域组件上定义 prepend
和 append
HTML附件。
<x:form::input name="" prepend="<i class="fas fa-code fa-fw"></i>"/> <x:form::input name="search" append="<i class="fas fa-search fa-fw"></i>"/>
注意:您可以使用HTML而不是组件来管理复杂的附件。
绑定数据
您可以将Eloquent模型、对象、集合或数组绑定,以自动填充绑定组件的值。
在表单组件上绑定数据将触发其包含的所有组件的绑定。
您可以直接在组件上绑定数据并覆盖表单绑定。
在验证错误的情况下,组件将通过旧值重新填充,这些旧值将覆盖绑定值。
对于特定的用例,您还可以使用 @bind($boundDataBatch)
和 @endbind
Blade 指令来绑定一组组件。
@php $dataBatch1 = ['description' => 'A wonderful description']; $dataBatch2 = ['first_name' => 'John', 'last_name' => 'Bonham']; @endphp <x:form::form :bind="$user"> <x:form::input type="email" name="email"/> {{-- Will set the value from `$user->email` --}} <x:form::textarea name="description" :bind="$dataBatch1"/> {{-- Will set the value from `$dataBatch1['description`] --}} @bind($dataBatch2) <x:form::input name="first_name"/> {{-- Will set the value from `$dataBatch2['first_name`] --}} <x:form::input name="last_name"/> {{-- Will set the value from `$dataBatch2['last_name`] --}} @endbind </x:form::form>
设置自定义值
您可以通过在组件上设置自定义值来覆盖数据绑定。
@php($data = ['description' => 'A wonderful description'];) <x:form::form :bind="$user"> ... <x:form::textarea name="description" :bind="$user" :value="$data['description']"/> {{-- Will set the value from `$data['description`] --}} </x:form::form>
处理验证状态和错误
当触发验证错误时,组件将能够显示或隐藏其成功/错误状态和错误消息。
- 如果激活了验证成功显示,则只有当表单中的其他组件被检测为无效时,组件才会被标记为有效。
- 如果激活了验证失败显示,则错误组件将被标记为无效,并显示相关的错误消息。
您可以在不同级别控制此行为。
- 使用
config('form-components.display_validation_success')
和config('form-components.display_validation_failure')
定义全局默认行为。 - 在表单上自定义此行为,并应用于其包含的所有组件。
- 直接在组件上设置特定的行为。
<x:form::form displayValidationSuccess="false" displayValidationFailure="false"> <x:form::input type="email" name="email"/> {{-- Disabled success/error statuses and error message --}} <x:form::textarea name="description" displayValidationSuccess="true" displayValidationFailure="true"/> {{-- Enabled success/error statuses and error message --}} </x:form::form>
您还可以自定义用于确定表单组件成功/错误状态和错误消息的错误包。
<x:form::form errorBag="form_error_bag"> {{-- Error bag for all components within the form --}} @errorbag('group_error_bag') {{-- Error bag for a group of components --}} <x:form::input name="first_name"/> <x:form::input name="last_name"/> @enderrorbag <x:form::input type="email" name="email" errorBag="component_error_bag"/> {{-- Error bag for a specific component --}} ... </x:form::form>
添加标题
通过添加标题来帮助用户并在组件下显示额外的说明。
<x:form::input name="name" caption="Please fill this input with your full name."/>
激活多语言模式
在 input
和 textarea
组件上激活多语言模式,以利用以下功能。
- 组件复制:每个语言区域将显示一个组件。
- 名称本地化:
name="description"
将转换为name="description[<locale>]"
。 - 默认标签和错误消息本地化:用于生成默认标签和错误消息的
__(validation.attributes.name)
翻译将附加(<LOCALE>)
。
<x:form::input name="name" :locales="['fr', 'en']"/> <x:form::textarea name="description" :locales="['fr', 'en']"/>
与 Livewire 插件。
表单和输入组件与 Livewire 兼容。
与未使用此包时一样,您不需要在每个要连接的组件上定义 wire:model
HTML 属性,只需定义 wire="<optional-modifier>"
HTML 属性即可使它工作。
每个连接的输入组件将使用其自己的 name
属性,并将其转换为有效的 wire:model="<name>"
。
<x:form::form wire:submit.prevent="submit"> <x:form::input name="name"/> {{-- Will not be wired --}} <x:form::input type="email" name="email" wire/> {{-- Will bind the value from the Livewire component `$email` property with no defined Livewire modifier --}} <x-form::input name="description" wire="lazy"/> {{-- Will bind the value from the Livewire component `$description` property with the the `lazy` Livewire modifier --}} <x-form::submit/> </x:form::form>
遵循相同的逻辑,您还可以直接从包含它们的表单连接输入组件。
<x-form::form wire:submit.prevent="submit" wire> <x-form::input type="email" name="email"/> {{-- Will bind the value from the Livewire component `$email` property with no defined Livewire modifier --}} <x-form::input name="description" wire="lazy"/> {{-- Will bind the value from the Livewire component `$description` property with the the `lazy` Livewire modifier --}} <x-form::submit/> </x:form::form>
对于特定的用例,您还可以使用 @wire($modifier)
和 @endwire
Blade 指令来使用特定的 Livewire 修饰符连接一组组件。
<x-form::form wire:submit.prevent="submit" wire="lazy"> <x-form::input name="first_name"/> {{-- Will bind the value from the Livewire component `$first_name` property with the `lazy` Livewire modifier --}} @wire('debounce.150ms') <x-form::input name="last_name"/> {{-- Will bind the value from the Livewire component `$last_name` property with the `debounce.150ms` Livewire modifier --}} @endbind @wire(null) <x-form::input type="email" name="email"/> {{-- Will bind the value from the Livewire component `$email` property with no defined Livewire modifier --}} <x-form::input name="description" wire="lazy"/> {{-- Will bind the value from the Livewire component `$description` property with the the `lazy` Livewire modifier --}} @endbind <x-form::submit/> </x-form::form>
测试
composer test
变更日志
请参阅 变更日志 以获取有关最近更改的更多信息。
贡献
请参阅 贡献指南 以获取详细信息。
安全漏洞
请参阅 我们的安全策略 了解如何报告安全漏洞。
致谢
许可证
MIT 许可证 (MIT)。有关更多信息,请参阅 许可证文件。