wisam-alhennawi/lara-forms-builder

这是我的一款包 lara-forms-builder


README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

关于

此包的主要功能是

  • 通过一个命令和一个 Livewire 组件生成 Livewire 表单(显示、创建、更新)。

要求

使用此包需要以下依赖项

💡 => 您可以使用自动设置和配置来安装它。

请注意,(pikaday & moment)npm 包仅当您在表单中包含日期字段时才需要。

安装

composer require wisam-alhennawi/lara-forms-builder

自动设置和配置

php artisan make:lara-forms-builder-setup

此命令将执行以下操作

  • 如果尚未安装,安装 "laravel/jetstream": "^3.0""livewire/livewire": "^2.0"。安装 jetstream 将安装 "tailwindcss": "^3.0" & "alpinejs": "^3.0"
  • 安装 npm 包 "pikaday": "^1.0""moment": "^2.0" 并进行必要的配置。
  • 将确认模态组件添加到 app.blade.php 布局。
  • 发布配置文件 lara-forms-builder.php 并进行必要的配置。
  • 发布资产文件 lara-forms-builder.css 并进行必要的配置。
  • 运行 npm install & npm run build

配置

发布资产

  1. 配置 (必填)

    您必须发布配置文件并将其添加到 tailwind.config.js 以应用样式

    php artisan vendor:publish --tag="lara-forms-builder-config"

    这是发布配置文件的内容

    return [
        'default_group_wrapper_class' => 'lfb-group-wrapper',
        'default_field_wrapper_class' => 'lfb-field-wrapper',
        'card_field_error_wrapper_classes' => 'shadow mb-4 overflow-hidden rounded-md col-span-2 sm:col-span-2',
        'primary_button_classes' => 'lfb-primary-button',
        'secondary_button_classes' => 'lfb-secondary-button',
        'footer_buttons_wrapper_classes' => 'lfb-buttons-wrapper',
        'previous_button_classes' => 'lfb-secondary-button',
        'next_button_classes' => 'lfb-primary-button',
    ];

    更新 tailwind.config.js

    export default {
         content: [
         './config/lara-forms-builder.php',
        ],
         theme: {
             extend: {
                 colors: {
                     'primary': '', // #7c8e63
                     'secondary': '', // #aebf85
                     'danger': '' // #DC3545
                 },
             },
         },
    };
  2. CSS (必填)

    发布 CSS 文件是应用样式所必需的。

    php artisan vendor:publish --tag="lara-forms-builder-assets"

    这将在 public/vendor/lara-forms-builder/css/ 目录中创建一个新的 CSS 文件 lara-forms-builder.css。之后,您必须通过添加以下内容将此文件导入您的 resources/css/app.css 中:

    @import "../../public/vendor/lara-forms-builder/css/lara-forms-builder.css";

    您还可以随意编辑 lara-forms-builder.css 中的默认样式以满足您的表单样式要求。

  3. 翻译(可选)

    php artisan vendor:publish --tag="lara-forms-builder-translations"
  4. 视图(可选)

    php artisan vendor:publish --tag="lara-forms-builder-views"

在表单中使用日期(可选)

如要求部分所述,如果您的表单包含日期字段,您必须按照以下步骤安装所需的依赖项

  • 安装 pikaday

    npm install pikaday

    将这些添加到您的 resources/js/app.js

    import Pikaday from 'pikaday';
    window.Pikaday = Pikaday;

    将这些添加到您的 resources/css/app.css

    @import 'pikaday/css/pikaday.css';
  • 安装 moment

    npm install moment

使用确认模态

为了在项目中使用确认模态,您必须将其全局包含在您要使用的 blade 视图的默认布局中。因此,您可以将 @livewire('modals.confirmation') 添加到您的 views/layouts/app.blade.php 中的 <body> 标签内。

用法

从创建新的 Livewire

使用此命令,您可以根据模型创建新的 Livewire 表单,此外,您还可以添加 [--langModelFileName=] 标签来指定模型字段标签的 lang 文件

php artisan make:lara-forms-builder name model --langModelFileName=

示例

php artisan make:lara-forms-builder UserForm User --langModelFileName=users
php artisan make:lara-forms-builder Users.UserForm User --langModelFileName=users       //this will make a UserForm component inside Users directory.

表单组件类型和属性

表单以声明方式指定,在表单组件类中的 fields 函数作为数组,例如:

protected function fields(): array
    {
        return [
            [
                'fields' => [
                    'name' => [
                        'type' => 'input',
                        'label' => __('models/users.fields.name'),
                    ],
                    'email' => [
                        'type' => 'input',
                        'label' => __('models/users.fields.email'),
                        'readOnly' => true
                    ],
                    'role' => [
                        'type' => 'radio',
                        'label' => __('models/users.fields.role'),
                        'options' => [
                            '1' => __('Employee'),
                            '2' => __('Manager')
                        ]
                    ],
                    'status' => [
                        'type' => 'select',
                        'label' => __('models/users.fields.status'),
                        'options' => [
                            [
                                'value' => '1',
                                'label' => __('Pending')
                            ],
                            [
                                'value' => '2',
                                'label' => __('Active')
                            ],
                            [
                                'value' => '3',
                                'label' => __('Retired')
                            ]
                        ]
                    ],
                    'last_update' => [
                        'type' => 'date-picker',
                        'label' => __('models/users.fields.last_update')
                    ],
                    'remark' => [
                        'type' => 'textarea',
                        'label' => __('models/users.fields.remark'),
                        'field_wrapper_class' => 'col-span-2',
                    ],
                ]
            ]
        ];
    }

上面的定义然后以本截图所示的方式渲染(需要额外的语言依赖性翻译)

Rendered Form according to code snippet

所有表单组件都具有以下一般属性

  • type (必填):指定表单组件的类型,有关支持的类型及其各自属性,请参阅以下小节
  • label(必填):组件的标签文本,也可以包含HTML标签(请负责任地处理,不要允许用户输入用作标签)
  • validationAttribute(可选):如果设置,则值将用作验证消息的属性标签。如果没有设置,则label也将用作验证消息的字段名称。
  • helpText(可选):在组件底部显示的帮助文本
  • readOnly(可选):当设置为true时,表单字段不允许输入或更改,仅显示当前值
  • rules(可选):应用于此字段的验证规则。如果没有设置,如果可用,则将使用与字段同名的Eloquent模型规则,否则不应用任何规则。
  • field_wrapper_class(可选):要添加到包围表单组件的div的CSS类

类型input

input表单字段是一个经典的html输入元素。它有以下附加属性

  • inputType(可选):指定具体的输入类型,例如email、number、url。如果未提供,则默认为text。

类型textarea

textarea表单字段代表一个文本区域,并具有以下附加属性

  • rows(可选):定义文本区域的行数,如果未设置,则默认为5。

类型select

select表单字段是一个单选下拉框。它具有以下附加属性

  • options(必填):指定在下拉框中显示的选项,以数组的形式提供,包含具有valuelabel属性的属性对象,或者当分组时,为具有valuelabel属性的属性对象的嵌套数组。
  • isGrouped(可选):定义选项是否分组,如果未设置,则默认为false。
  • styled(可选,不能与isGrouped组合使用):当设置为true时,使用可定制的div基于的select组件而不是HTML选择元素。
  • searchable(可选,仅在styledtrue时):当设置为true时,添加一个搜索字段,允许根据搜索表达式过滤选项(简单的不区分大小写的子字符串匹配)。

类型radio

radio表单字段代表单选按钮,并具有以下附加属性

  • options(必填):指定单选按钮选择的选项,以简单的数组value => label形式提供。

类型cards

cards表单字段是一个特殊的布局元素,用于通过单击具有丰富内容和图标的几个卡片中的一张来选择不同的选项。它具有以下附加属性

  • options(必填):指定要选择的选项,作为一个具有valuelabel属性的对象数组(可以是HTML)。
  • icon(可选):在所有卡片中显示的SVG标记或URL,如果未设置,则不显示图标。
  • card_field_error_wrapper_class(可选):要添加到错误消息框的CSS类
  • errorMessageIcon(可选):在错误消息中显示的自定义图标标记,如果未设置,则使用默认图标。

类型checkbox

checkbox表单字段是一个单选框,没有其他附加属性。

类型checkbox-group

checkbox-group表单字段是一组多选框。它具有以下附加属性

  • options(必填):指定复选框的值和标签,以具有valuelabel属性的对象数组提供,或者当按类别分组时,为具有valuelabel属性的属性对象的嵌套数组。
  • hasCategory (可选):定义是否按类别分组复选框条目,默认未设置时为 false。

类型 date-picker

《date-picker》表单字段添加了一个 Pikaday 日期选择器。它没有任何其他属性。

类型 file

《file》表单字段代表一个用于单个文件上传的文件输入。它有以下附加属性

  • preview (可选):如果设置为值 image,将显示上传的或现有的文件的预览。为了正确显示现有文件的预览(在编辑现有模型时),必须将下载现有文件的 URL 设置为附加属性 $this.{$key . '_preview'},例如,对于字段键 contact_property,使用 contact_photo_preview。预览 URL 可以在 afterFormProperties 函数中确定并设置。
  • removeIcon (可选):显示为移除/重置所选文件之前要显示的自定义图标标记。如果未设置,则使用默认图标。

由于二进制文件通常不直接作为 Eloquent 模型的属性存储,而必须单独处理,因此此类表单字段在实现表单时通常需要额外的文件处理逻辑。实现遵循 Livewire 文件上传的原则(https://laravel-livewire.com/docs/2.x/file-uploads),本质上提供了文件上传的视图部分。建议在回调或覆盖函数之一中添加文件处理,例如以下代码片段用于属性 attachment

public function saveAttachment($attachmentValue) {
    $attachmentValue->storeAs('attachments', $attachmentValue->getClientOriginalName());
}

类型 search-picker

public array $contactIdOptions = [];

public function getContactIdOptions($searchPickerTerm)
{
    return Contact::select('id', 'name')
            ->where('name', 'like', '%' . $searchPickerTerm . '%')
            ->get()
            ->each(function($row){
                $row->key = $row->id;
                $row->value = $row->name;
                $row->labels = collect(['White', 'Green', 'Blue', 'Red', 'Yellow'])->random(rand(0, 3))->toArray();
            })
            ->toArray();
}

// will return ($contact_id_search_picker_selected_value) which used in blade to display the selected option
public function getContactIdSearchPickerSelectedValueProperty()
{
    if ($this->contact_id) {
        return Contact::find($this->contact_id)->name;
    }
    return null;
}

protected function fields(): array
{
    return [
        [
            'fields' => [
                    'contact_id' => [
                    'type' => 'search-picker',
                    'label' => 'Contact Person',
                    'searchPickerResultsProperty' => 'contactIdOptions',
                    'placeholder' => __('Search for contact person'),
                    'field_wrapper_class' => 'col-span-1',
                ],
            ]
        ]
    ];
}

《search-picker》表单字段是一个具有搜索功能的输入字段,它将结果作为列表显示在字段下方。它有以下附加属性

  • placeholder (可选):指定输入字段的占位符。
  • searchPickerResultsProperty (必需):指定义义包含搜索结果的数组。数组中的每个元素都应该具有以下结构
    [
        'key' => '',
        'value' => '',
        'labels' => [] // optional
    ]

注意: getContactIdOptions()getContactIdSearchPickerSelectedValueProperty() 函数应遵循表单字段名称 contact_id 的命名约定。

Rendered Form according to code snippet

表单布局

选项卡

  • 为使用选项卡组织内容的组件提供自定义布局。
  • 每个选项卡都表示为一个数组(在 fields() 方法中),包含 'key''title''content'。其中 'content' 数组包含有关表单字段、它们的类型、标签、选项和样式的信息。

多步骤

  • 多步骤功能旨在简化具有选项卡布局的多步骤表单的创建。它提供了初始化步骤、设置活动步骤编号、在步骤之间导航以及检索表单多步骤结构信息的方法。
  • 用法
    • 目前它仅适用于 选项卡布局,默认情况下是禁用的。
    • 要启用 multi-step 功能,在配置表单时将 isMultiStep 属性设置为 true。
  • 示例
    use WisamAlhennawi\LaraFormsBuilder\LaraFormComponent;
    use WisamAlhennawi\LaraFormsBuilder\Traits\HasTabs;
    
    class CustomerForm extends LaraFormComponent
    {
        use HasTabs;
    
        public function mount(Customer $customer)
        {
            $this->mountForm($customer, [
                'activeTab' => 'address-data',
                'hasTabs' => true,
                'isMultiStep' => true, // Optional if you want to use the multi-step form feature
            ]);
        }
    
        protected function fields(): array
        {
            return [
                [
                    'key' => 'address-data',
                    'title' => __('Address Data'),
                    'content' => [
                        'group_info' => [
                            'group_wrapper_class' => 'grid grid-cols-4 gap-6',
                            'default_group_wrapper_class' => false
                        ],
                        'fields' => [
                            // Fields for the 'Address Data' tab
                            // Example:
                            'company' => [
                                'type' => 'input',
                                'label' => __('models/customers.fields.company'),
                                'field_wrapper_class' => 'col-span-4',
                            ],
                            // ... other fields
                        ],
                    ],
                ],
                [
                    'key' => 'contact-data',
                    'title' => __('Contact Data'),
                    'content' => [
                        'group_info' => [
                            'group_wrapper_class' => 'grid grid-cols-6 gap-6',
                            'default_group_wrapper_class' => false
                        ],
                        'fields' => [
                            // Fields for the 'Contact Data' tab
                            // Example:
                            'phone' => [
                                'type' => 'input',
                                'label' => __('customers.fields.phone'),
                                'field_wrapper_class' => 'col-span-2',
                            ],
                            // ... other fields
                        ],
                    ],
                ],
                // .. other tabs
            ];
        }
    
        // ... other component properties and methods
    }
    ```php

表单方法

  • protected function successMessage()
    • 目的
      • 《successMessage》函数负责根据表单提交的结果生成成功消息。
    • 自定义成功消息
      • 如果通过 $customSuccessMessage 属性提供了自定义成功消息,则将使用它。
    • 默认成功消息
      • 如果没有设置自定义成功消息,则使用创建和更新模式默认成功消息。
        trans('A new entry has been created successfully.')
        trans('Changes were saved successfully.')
      • 这些默认消息可以通过在语言文件中添加翻译键进行进一步自定义。
        'A new '.$modelName.' has been created successfully.'
        'The '.$modelName.' has been updated successfully.'
        示例
        'A new user has been created successfully.'
        'The user has been updated successfully.'
    • 显示成功消息
      • 成功消息将以闪存消息或通过浏览器事件的形式显示给用户。显示方式取决于$hasSession属性的值,默认为true。
    • 另一种自定义成功消息的方法是覆盖组件类中的successMessage()方法。

变更日志

有关最近更改的更多信息,请参阅变更日志

贡献

有关详细信息,请参阅贡献指南

安全漏洞

请查看我们关于如何报告安全漏洞的安全策略

鸣谢

许可证

MIT许可证(MIT)。有关更多信息,请参阅许可证文件