anthonyedmonds/laravel-form-builder
Composer 安装命令:
composer require anthonyedmonds/laravel-form-builder
包简介
Create one-thing-per-page forms with forking logic and task lists; ideal for the GOV.UK Design System!
README 文档
README
Laravel Form Builder
Create one-thing-per-page forms broken down into tasks; ideal for the GOV.UK Design System!
What's in the box?
- Laravel Form Builder classes, interfaces, and traits
- Basic frontend pages for demonstration and testing purposes
The user interface is left up to you to implement and style as you desire.
Upgrading
Guidance on upgrading versions can be found in the upgrade guide.
Installation
Composer
You can install this library using Composer:
composer require anthonyedmonds/laravel-form-builder
Service Provider
The Form Builder service provider will be automatically registered.
If you need to manually load it, you can add the following to your config/app.php file:
'providers' => [ // ... AnthonyEdmonds\LaravelFormBuilder\LaravelFormBuilderServiceProvider::class, ],
Publish files
The following can be published using php artisan vendor:publish:
| Key | Usage | Target |
|---|---|---|
| config | The Form Builder configuration file | config/form-builder.php |
| views | The Form Builder blades and components | resources/vendor/form-builder/... |
The configuration file is required for registering forms.
The views are optional, used primarily as a basis for building your own form UI components.
If you are using GOV.UK Laravel, you can switch to the pre-made views by changing the template config setting.
Routes
Add the Form Builder routes to your routes/web.php:
Route::laravelFormBuilder();
Configuration
The config/form-builder.php file contains the following options:
| Key | Usage | Type | Default |
|---|---|---|---|
| forms | A list of Forms available in the system | class-string[] | [] |
| template | Which view template to use | string | default |
Structure
Each Form follows a simple structure, with movement controlled automatically based on the user's choices:
Form > Start or Resume
Tasks > Task > Question
Summary > Submit or Draft > Confirmation > Exit
- Upon entering a
Form, the system will check whether they have an active session- If they do, they will be asked whether they want to resume or start fresh
- If not, they will be shown a start page (if enabled)
- Users will then be shown a list of
Tasks- They may pick any
Taskto complete, though aTaskcan be disabled if they cannot start it yet
- They may pick any
- Entering a
Taskshows the user theQuestionlist- Entering a
Questionallows the user to provide answers to any number of fields - Once all
Questionclasses within aTaskhave been answered, they can return to theTaskslist
- Entering a
- Once all
Taskclasses have been completed, the user can then view aSummaryof their answers- They may then submit their answers, or save as a draft (if enabled)
- After successful submission, users will be shown a confirmation screen (if enabled)
- Users then exit the
Form
This library provides all of the flow control basis required, based on the content you provide.
The user's answers are stored in a session directly on the related Model as they progress through the Form.
A diagram is available here which shows the internal workings.
Setting up a Form
Every Form starts by extending the Form class.
As a minimum, you will need to provide a unique key() for the Form, the modelClass(), and a set of tasks().
You can customise the behaviour of your Form elements by overriding functions in your classes.
Model
The Model to be used with your Form must implement the UsesForm interface.
The HasForm trait is provided to fill in most of the needed functionality.
As a minimum with the trait, you will need to provide a viewRoute().
This will allow users to view their submission after completing the Form.
Drafts
A flag is provided on the Model to enable or disable saving as a draft.
If you enable saving as a draft, it is recommended to customise the saveAsDraft() function appropriately.
Tasks
Every Form is broken up into several Task classes.
These are wrapped up in a Tasks class.
You can have as many or as few Task classes as you like; it is recommended to keep each Task to a minimum.
public function tasks(): array { return [ MyTask::class, NextTask::class, ... ]; }
As a minimum, you will need to provide a list of tasks().
Task Groups
You may group your tasks by providing a keyed array instead:
public function tasks(): array { return [ 'Group one' => [ MyTask::class, ... ], 'Group two' => [ NextTask::class, ... ], ]; }
It is not recommended to mix grouped and ungrouped Task classes, as this may become visually confusing.
Showing and hiding Task classes
You can control which Task classes are shown by adding any needed logic to the tasks() method.
Users may be confused by the constant appearance and disappearance of tasks, so it is recommended to keep it simple, and consistent.
You may find it is better to have a Task in the Not Required state, instead of hiding it entirely.
Start and Confirmation pages
Flags are provided on the Form to control whether to show the Start and Confirmation pages.
If Start is disabled, users will be taken straight to the Tasks page.
If Confirmation is disabled, users will be taken straight to the viewRoute() of the Model.
Creating a Task
Each Task contains any number of Question classes.
As a minimum, you will need to provide a unique key(), and a list of questions().
Statuses
Every Task has a status based on the status each Question.
You can customise the logic of which statuses are shown by overriding the relevant functions on the Task.
For more information, see the HasStates trait.
Showing and hiding Questions
You can control which Question classes are shown by adding any needed logic to the questions() method.
Users may be confused by the constant appearance and disappearance of questions, so it is recommended to keep it simple, and consistent.
You may find it is better to have a Question in the Not Required state, instead of hiding it entirely.
Creating a Question
Each Question contains any number of fields, which should directly correspond to attributes on the Model.
A Question can be used in any number of Task classes, especially when abstracted if they are similar.
You can customise how values are read and written to the Model; by default, it will use the provided field key.
Fields
Every Question has one or more Fields, which control the inputs shown on the page.
[
Field::input('name', 'What is their name?')
->setHint('Provide their full name')
->optional(),
]
Field comes with a helper for each common input type.
In this example, the first parameter is the name of the input, which corresponds to the name property on the Model.
The second parameter is the question being asked.
When there is only one Field in a Question, it should be used as the page title.
The hint method adds a line of supporting text to the Field.
The optional method marks the Field as not required; Fields are required by default.
Many other methods are available to further customise the input.
Customising the Model attribute
Out of the box, Field classes use their name to determine which Model attribute it relates to.
This controls most of Form Builder's automatic behaviour.
You can set an attribute property to customise that behaviour.
This can be useful where you have a simple input for a complicated attribute, such as a relationship.
For example, you might ask for an e-mail to find a User, but capture their ID on the Model:
/** Model with `user` relationship */ $model = new MyModel(); /** Field value will be equal to $model->user?->email */ Field::input('email', 'What is the user\'s e-mail address?') ->setAttribute('user.email');
Additional fields
The Question blade has two customisable sections before and after the main Field.
These can be used to add additional content to your question blade.
They can be utilised as follows:
@extends('form-builder::question') @section('before-main') <x-govuk::h1>Example</x-govuk::h1> @endsection @section('before-fields') <x-govuk::p>This is a starting paragraph</x-govuk::p> @endsection @section('after-fields') <x-govuk::p>This is an ending paragraph</x-govuk::p> @endsection
Skippable Questions
A flag is provided to allow users to skip a question.
This can be useful for optional questions, where it may be clearer that the user does not have to give a response.
If you enable skipping, it is recommended to customise the applySkip() function appropriately.
Looping Questions
A flag is provided to redirect users back to the same Question after saving.
This can be useful for adding multiple responses to the same question.
When doing this, the Question should also be skippable, with the skip option being used to progress forward.
If skipping is not enabled, the user will must be provided with a way to move forward.
Statuses
Each Question has a status based on the user's answers to each field.
You can customise the logic of which statuses are shown by overriding the relevant functions on the Question.
For more information, see the HasStates trait.
Clearing Answers
Form Builder determines whether a Question has been answered by whether the Model has a matching $attribute key, even if that key is null.
To clear a Question as if it had never been answered, you can call $model->clearAnswer('attribute-key'); to remove the needed keys.
This is often used when changing the answer to an earlier Question which should wipe answers elsewhere in the Form.
Using and accessing Forms
Users have two main entry points to any Form, new and edit.
Start a new Form
Users can be redirected to the new endpoint using any of the following:
Model::formRoute()Model::newForm()->route()route('forms.new', MyForm::key())
Edit an existing Model
Users can be redirect to the edit endpoint using any of the following:
Model::formRoute($model)$model->form()->editRoute()route('forms.edit', [MyForm::key(), $model])
Pre-filling Form Fields
It may be useful to pre-fill some Form Fields based on the context of where the Form was started.
This can be done by using the URL query string in combination with the makeForForm() method on the Model.
As an example, to pass the system key to the Form you could do the following:
- Call
Model::formRoute()and append a query string to the URL/forms/my-form/new?system=blah
- Override the
makeForForm()method on theModelto set the desired properties-
public static function makeForForm(): UsesForm { $model = new MyModel(); if (Request::has('system') === true) { $model->system()->associate( Request::input('system'), ); } return $model; }
-
This can be done for as many fields as required, and can save users time.
Question templates
Some templates have been provided to simplify common complicated questions.
You can extend these templates in place of any Question.
You may override, modify, and further extend them as needed.
UploadFiles
Upload multiple files one at a time, complete with a table of files, validation, download, and draft management.
This template leverages the Laravel FileStore library.
You can specify the filesRequired() parameter to set a minimum number of uploaded files required.
Adding a FileStore to your Model
When adding a FileStore to your Model, extend the FormBuilderFileStore class.
You can use the FormBuilderFileStore as per the normal FileStore class.
Viewing models
If you would like to use the Form Builder Summary page for a viewing a model, you may use the view() method on your model.
This will generate a Summary style page without the ability to change any answers.
A link back to the Form should be included, if the model can be edited.
You can control whether an individual Question can be edited by adjusting the canChange() method.
Testing
To assist with the creation of unit tests, an AssertsForms trait has been provided.
You can add this to your base TestCase class to use the following methods:
| Assertion | Usage |
|---|---|
| assertField(array $expectations, Field $field) | Provide the expected values for the Field, then the field itself |
Help and support
You are welcome to raise any issues or questions on GitHub.
If you wish to contribute to this library, raise an issue before submitting a forked pull request.
Licence
Published under the MIT licence.
anthonyedmonds/laravel-form-builder 适用场景与选型建议
anthonyedmonds/laravel-form-builder 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1.32k 次下载、GitHub Stars 达 1, 最近一次更新时间为 2024 年 04 月 17 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「form」 「builder」 「laravel」 「question」 「gov.uk」 「task list」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 anthonyedmonds/laravel-form-builder 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 anthonyedmonds/laravel-form-builder 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 anthonyedmonds/laravel-form-builder 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Diese Contao 4 Erweiterung stellt Google reCAPTCHA V2 in Form eines neuen Formularfeldes im Formulargenerator bereit. This extension provides Google reCAPTCHA V2 in the form of a new form field in the form generator of Contao Open Source CMS.
A Sphinx Query Builder extension for the Laravel Database package
Anax Database Active Record module for model classes.
A Laravel Filament Forms slug field.
A simple package to create tables in Discord messages.
A jQuery augmented PHP library for creating and validating HTML forms
统计信息
- 总下载量: 1.32k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1
- 点击次数: 16
- 依赖项目数: 2
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2024-04-17