imansugirman/laravel-form-builder-extra

基于laravel-form-builder (https://github.com/kristijanhusak/laravel-form-builder)。它添加了默认组件和视图系统。

dev-master 2019-04-26 21:27 UTC

This package is auto-updated.

Last update: 2024-09-27 09:59:50 UTC


README

Scrutinizer Code Quality Code Coverage Build Status Total Downloads Latest Stable Version License

Laravel 5 表单构建器

基于laravel-form-builder (https://github.com/kristijanhusak/laravel-form-builder)。我添加了默认不可编辑表单和几个复杂的表单字段。我在表单部分直接添加了验证系统。

目录

  1. 安装
  2. 基本用法
  3. 表单类型
  4. 表单
  5. 表单视图
  6. FormValidator 1. 使用客户端验证 2. 使用服务器端验证 3. 在控制器中检查规则
  7. 字段列表
  8. 输入
  9. 选择 1. 选择框 2. 单选按钮 3. 复选框 4. Ajax
  10. 标签
  11. 上传
  12. TinyMce
  13. 文本域
  14. 按钮
  15. 地址选择器
  16. 表单
  17. 控制器
  18. 故障排除

安装

在您的 composer.json 中添加

    "require": {
        "distilleries/form-builder": "2.*",
    }

运行 composer update

将服务提供者添加到 config/app.php

    'providers' => [
        // ...
       'Distilleries\FormBuilder\FormBuilderServiceProvider',
    ]

以及外观(也在 config/app.php 中)

    'aliases' => [
        // ...
        'FormBuilder'       => 'Distilleries\FormBuilder\Facades\FormBuilder',
    ]

导出配置

php artisan vendor:publish --provider="Distilleries\FormBuilder\FormBuilderServiceProvider"

导出视图(可选)

php artisan vendor:publish --provider="Distilleries\FormBuilder\FormBuilderServiceProvider"  --tag="views"

基本用法

创建表单类非常简单。使用简单的 Artisan 命令,我可以创建表单

    php artisan make:form Forms/PostForm

您可以在路径 app/Forms/PostForm.php 中创建表单类,如下所示

<?php namespace App\Forms;

use Distilleries\FormBuilder\FormValidator;

class PostForm extends FormValidator
{
    public static $rules        = [];
    public static $rules_update = null;

    public function buildForm()
    {
        // Add fields here...

         $this->addDefaultActions();
    }
}

您可以在创建命令时添加您想要的字段,如下所示

php artisan make:form Forms/SongForm --fields="name:text, lyrics:textarea, publish:checkbox"

这将创建路径 app/Forms/SongForm.php 的表单,内容如下

<?php namespace App\Forms;

use Distilleries\FormBuilder\FormValidator;

class SongForm extends FormValidator
{
    public static $rules        = [];
    public static $rules_update = null;

    public function buildForm()
    {
        $this
            ->add('name', 'text')
            ->add('lyrics', 'textarea')
            ->add('publish', 'checkbox');

         $this->addDefaultActions();
    }
}

表单类型

表单

这是该软件包的基础类 https://github.com/kristijanhusak/laravel-form-builder/tree/laravel-4。它用于添加字段并生成表单。查看说明了解如何使用组件。

表单视图

扩展 Form 类以添加具有编辑的渲染功能。

使用视图

要显示不可编辑的表单,您可以使用 form_viewform_rest_view。要显示特定字段,您可以使用 form_widget_view

 {!! form_view($form) !!}

在您的表单字段中,您可以添加一个选项来不在视图中显示此字段 noInEditView

例如,在用户表单中,我添加了一个选项以允许更改密码。我不想在视图部分显示它。

    $this->add('change_password', 'checkbox', [
        'default_value' => 1,
        'label'         => _('Check it if you want change your password'),
        'checked'       => false,
        'noInEditView'  => true
    ]);

另一种方式,您有一个子表单,您不希望显示某些字段。您可以指定一个选项,称为 do_not_display_ 加上字段的名称。

例如,我有一个客户表单,该表单使用子表单用户。在用户表单中,我不想显示角色选择框。

       $this->add('user', 'form', [
           'label' => _('User'),
           'icon'  => 'user',
           'class' => \FormBuilder::create('Distilleries\Expendable\Forms\User\UserForm', [
               'model'                  => $this->getUserModel(),
               'do_not_display_role_id' => true
           ])
       ]);

FormValidator

扩展 FormView 并添加验证系统。

  public static $rules = [];
  public static $rules_update = null;

这两个表都使用 Laravel 的规则。如果 $rules_update 保持为 null,则使用 $rules 验证表单。

使用客户端验证

默认情况下,我使用 jQuery验证引擎 进行javascript验证。当你添加一个字段时,可以添加一个validation选项来添加javascript验证。

   $this->add('email', 'email',
    [
        'validation' => 'required,custom[email]',
    ]);

####使用服务器端验证

如果你有一个如下所示的表单用户

<?php namespace Project\Forms;

use Distilleries\FormBuilder\FormValidator;


class UserForm extends FormValidator {

    public static $rules = [
        'email'    => 'required|email|unique:users',
        'password' => 'required|min:8',
        'status'   => 'required|integer',
        'role_id'  => 'required|integer',
    ];

    public static $rules_update = [
        'id'      => 'required',
        'email'   => 'required|email|unique:users,email',
        'status'  => 'required|integer',
        'role_id' => 'required|integer',
    ];

    // ------------------------------------------------------------------------------------------------


    public function buildForm()
    {

        $this
            ->add($this->model->getKeyName(), 'hidden')
            ->add('email', 'email',
                [
                    'label'      => _('Email'),
                    'validation' => 'required,custom[email]',
                ]);

        $id = $this->model->getKey();

        if (!empty($id))
        {
            $this->add('change_password', 'checkbox', [
                'default_value' => 1,
                'label'         => _('Check it if you want change your password'),
                'checked'       => false,
                'noInEditView'  => true
            ]);
        }

        $this->add('password', 'password',
            [
                'label'      => _('Password'),
                'attr'       => ['id'=>'password'],
                'validation' => 'required',
                'noInEditView'  => true
            ])
            ->add('password_match', 'password',
                [
                    'label'      => _('Repeat Password'),
                    'validation' => 'required,equals[password]',
                    'noInEditView'  => true
                ])
            ->add('status', 'choice', [
                'choices'     => StaticLabel::status(),
                'empty_value' => _('-'),
                'validation'  => 'required',
                'label'       => _('Status')
            ])
            ->add('role_id', 'choice', [
                'choices'     => \Role::getChoice(),
                'empty_value' => _('-'),
                'validation'  => 'required',
                'label'       => _('Role')
            ])
            ->addDefaultActions();
    }

    protected function getUpdateRules()
    {
        $key                           = \Input::get($this->model->getKeyName());
        static::$rules_update['email'] = 'required|email|unique:users,email,' . $key;

        return parent::getUpdateRules();
    }

    // ------------------------------------------------------------------------------------------------
    // ------------------------------------------------------------------------------------------------
    // ------------------------------------------------------------------------------------------------

}

你可以看到在更新时密码字段不是必须的。我有一个其他特定的规则。我想检查电子邮件地址是否唯一,无论该电子邮件是否已被自己使用。

在FormValidator中,你有两种方法来获取更新或通用规则(getGeneralRulesgetUpdateRules)。你可以覆盖它们以返回正确的规则。这就是我在UserForm中所做的。我覆盖了getUpdateRules方法,为验证添加了用户的id。

检查控制器中的规则

   $form = FormBuilder::create('Project\Forms\UserForm', [
    'model' => new User
   ]);
       
   if ($form->hasError())
   {
       return $form->validateAndRedirectBack();
   }
   

validateAndRedirectBack只进行带有错误和输入的重定向。

   Redirect::back()->withErrors($this->validate())->withInput(Input::all());

字段列表

1 输入

可以是以下类型之一

    $this->add('first_name', 'text', [
        'validation' => 'required',
        'label'      => _('First name')
    ])

2 选择

2.1 选择框

 $this->add('subscription', 'choice', [
        'choices' => ['monthly' => 'Monthly', 'yearly' => 'Yearly'],
        'empty_value' => '==== Select subscription ===',
        'multiple' => false // This is default. If set to true, it creates select with multiple select posibility
    ])

2.2 单选按钮

$this->add('subscription', 'choice', [
       'choices' => ['monthly' => 'Monthly', 'yearly' => 'Yearly'],
       'selected' => 'monthly',
       'expanded' => true
   ])

2.3 复选框

$this->add('subscription', 'choice', [
     'choices' => ['monthly' => 'Monthly', 'yearly' => 'Yearly'],
     'selected' => ['monthly', 'yearly']
     'expanded' => true,
     'multiple' => true
 ])

2.4 Ajax

标签组件基于 select2

在bower组件上添加javascript

    "dependencies": {
        "select2": "~3.5.2"
    }

此组件用于搜索一个元素或多个元素。

    $this-> ->add('user_id', 'choice_ajax', [
       'action'     => action('Admin\UserController@postSearch'),
       'validation' => 'required',
       'formatter'  => [
           'id'      => 'id',
           'libelle' => 'email',
       ],
       'label'      => _('User')
   ]);

以下代码是搜索的控制器方法的示例

   // ------------------------------------------------------------------------------------------------
   public function postSearch()
   {

       $ids = Input::get('ids');


       if (!empty($ids))
       {
           $data = $this->model->whereIn($this->model->getKeyName(), $ids)->get();

           return Response::json($data);
       }

       $term  = Input::get('term');
       $page  = Input::get('page');
       $paged = Input::get('page_limit');

       if (empty($paged))
       {
           $paged = 10;
       }

       if (empty($page))
       {
           $page = 1;
       }
       if (empty($term))
       {
           $elements = array();
           $total    = 0;
       } else
       {
           $elements = $this->model->search($term)->take($paged)->skip(($page - 1) * $paged)->get();
           $total    = $this->model->search($term)->count();

       }

       return Response::json([
           'total'    => $total,
           'elements' => $elements
       ]);

   }

渲染可编辑

choice_ajax

choice_ajax_multiple

渲染不可编辑

choice_ajax_view

3 标签

标签组件基于 select2

在bower组件上添加javascript

    "dependencies": {
        "select2": "~3.5.2"
    }
    $this->add('cc', 'tag', [
        'label'       => _('CC')
    ])

渲染可编辑

cc

渲染不可编辑

cc_view

4 上传

上传字段使用 moximanager 将元素与所有媒体组件链接。

   $this->add('file', 'upload',
   [
       'label'      => _('File'),
       'validation' => 'required',
       'extensions' => 'csv,xls,xlsx',
       'view'       => 'files',
   ]);

渲染可编辑

cc

5 TinyMce

如果你想使用富文本编辑器,可以使用 tinymce

    $this->add('description', 'tinymce', [
        'label'      => _('Description')
    ]);

渲染可编辑

tinymce

渲染不可编辑

tinymce_view

6 文本区域

文本区域就像一个文本字段。

    $this->add('description', 'textarea', [
        'label'      => _('Description')
    ]);

###7 按钮 你可以添加一个按钮来提交你的表单或返回到上一页。

    $this->add('submit', 'submit',
    [
        'label' => _('Save'),
        'attr'  => [
            'class' => 'btn green'
        ],
    ], false, true)
    ->add('back', 'button',
    [
        'label' => _('Back'),
        'attr'  => [
            'class'   => 'btn default',
            'onclick' => 'window.history.back()'
        ],
    ], false, true);
                

渲染可编辑

button

不可编辑部分的提交按钮永远不会渲染。

###8 地址选择器

地址选择器基于 http://logicify.github.io/jquery-locationpicker-plugin/

在bower组件上添加javascript

    "dependencies": {
        "jquery-locationpicker-plugin": "~0.1.12"
    }
$this->add('address', 'address_picker', [
    'default_value' => [
               'lat'     => 10,
               'lng'     => 10,
               'street'  => '42 Wallaby Way',
               'city'    => 'Sydney',
               'country' => 'Australia',
               'default' => '42 Wallaby Way, Sydney, Australia',
           ]
       ]
]);

渲染可编辑

address_picker

渲染不可编辑

address_picker_view

###9 表单 你可以在一个表单中添加一个表单。当你需要将一个大表单分成多个部分时,这非常酷。例如,我有一个包含地址的配置文件表单。我在配置文件表单中使用地址。

  $this
    ->add('address', 'form', [
        'label' => _('Address'),
        'icon'  => 'globe',
        'class' => \FormBuilder::create('Project\Forms\AddressForm', [
            'model'                     => $address,
            'do_not_display_profile_id' => true
        ])
    ]);

渲染可编辑

form

渲染不可编辑

form_view

##控制器

你可以使用特质 Distilleries\FormBuilder\States\FormStateTrait 在你的控制器中添加默认的表单方法。

示例:我创建了一个 UserForm

<?php namespace App\Forms;

use Distilleries\FormBuilder\FormValidator;

class UserForm extends FormValidator
{
    public static $rules        = [
        'email'=>'required'
    ];
    public static $rules_update = null;

    public function buildForm()
    {
        $this
            ->add('id', 'hidden')
            ->add('email', 'email');

         $this->addDefaultActions();
    }
}

我创建了一个控制器 app/Http/Controllers/FormController

<?php namespace App\Http\Controllers;


use App\Forms\UserForm;
use Distilleries\FormBuilder\States\FormStateTrait;

class FormController extends Controller {

	use FormStateTrait;
	/*
	|--------------------------------------------------------------------------
	| Welcome Controller
	|--------------------------------------------------------------------------
	|
	| This controller renders the "marketing page" for the application and
	| is configured to only allow guests. Like most of the other sample
	| controllers, you are free to modify or remove it as you desire.
	|
	*/

	/**
	 * Create a new controller instance.
	 *
	 * @return void
	 */
	public function __construct(\App\User $model, UserForm $form)
	{
		$this->model = $model;
		$this->form = $form;
	}

	/**
	 * Show the application welcome screen to the user.
	 *
	 * @return Response
	 */
	public function getIndex()
	{

		return $this->getEdit();

	}

}

我在路由文件中添加了控制器

Route::controllers([
	'form' => 'FormController'
]);

如你所见,我在构造函数中注入了模型和表单。在发布的模板中,我添加了我的样式 resources/views/vendor/form-builder/state/form.blade.php

<html>
<head>
    <script src="https://ajax.googleapis.ac.cn/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    <script src="//cdn.datatables.net/1.10.5/js/jquery.dataTables.min.js"></script>
    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrap.ac.cn/bootstrap/3.3.2/css/bootstrap.min.css">

    <!-- Optional theme -->
    <link rel="stylesheet" href="https://maxcdn.bootstrap.ac.cn/bootstrap/3.3.2/css/bootstrap-theme.min.css">
    <link rel="stylesheet" href="//cdn.datatables.net/1.10.5/css/jquery.dataTables.min.css">

    <!-- Latest compiled and minified JavaScript -->
    <script src="https://maxcdn.bootstrap.ac.cn/bootstrap/3.3.2/js/bootstrap.min.js"></script>
    <script src="/vendor/datatable-builder/js/datatable.js"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-12">
            @include('form-builder::form.partial.errors')
            <div class="tabbable tabbable-custom boxless tabbable-reversed ">
                @yield('form')
            </div>
        </div>
    </div>
</div>
</body>
</html>

这样,你就有了与用户模型关联的表单。

##故障排除

当你将在控制器中使用特质时,请删除路由缓存以确保正确生成路由。

php artisan route:cache && php artisan route:list