nickwest/eloquent-forms

直接从Eloquent模型和集合创建兼容Bulma的表单和表格

v10.0.0 2023-11-09 22:07 UTC

README

Build Status Latest Stable Version License StyleCI Maintainability codecov

EloquentForms v9.0.x

EloquentForms由Nicky West创建并维护。它的创建目的是为了最小化从Eloquent模型生成简单HTML表单所需的时间和精力,以支持CRUD功能。

EloquentForms包括一个Eloquent模型特型,可以用来根据底层表结构自动生成基于Eloquent模型的表单视图。这样创建的表单可以完全自定义。包括基本的验证,并且可以轻松扩展。

EloquentForms可以轻松地主题化,以支持各种前端CSS/JS框架,并包括必要的blade模板,以支持开箱即用的Bulma框架。

安装

EloquentForms需要PHP 8.0^。这个特定版本支持Laravel 9.x。要在早期版本的Laravel上安装,请使用EloquentForms的X.Y.z版本,其中X.Y或X.0(Laravel的版本方案已更改)与您使用的Laravel版本相匹配。

要获取最新版本,您只需通过Composer要求该包。

Composer require nickwest/EloquentForms

EloquentForms支持Laravel自动发现。在Laravel 5.5^中,这可能不是必需的,但为了手动添加包,您应该在config/app.php中添加以下提供者:

Nickwest\EloquentForms\EloquentFormsServiceProvider::class,
Nickwest\EloquentForms\Themes\bulma\EloquentFormsBulmaThemeServiceProvider::class

用法

向Eloquent模型添加功能

use Nickwest\EloquentForms\FormTrait;

class Sample extends Model{
    use FormTrait;

    protected $table = 'sample';

    // Options for setting up the form:

    // OPTION 1: Create a method in the model that will be called by the controller

    // The method name doesn't matter, it's up to you.
    public function prepareForm()
    {
        // Set a default Form Field label postfix
        $this->label_suffix = ':';

        // This comes from the FormTrait. It generates form field data by looking at
        // the model's table columns
        $this->generateFormData();

        // Use a custom theme for the generated markup
        $this->Form()->setTheme(new \Nickwest\EloquentForms\Themes\bulma\Theme());

        // By Default all fields will be displayed

        // We can set specific fields to be displayed by the form.
        // The order here dictates the order the fields will show on the form
        // $this->Form()->setDisplayFields( array(
        //     'email',
        //     'attendance_date',
        //     'placard_color',
        //     'photograph',
        //     'phone_number',
        //     'link_to_website',
        //     'meal_choice',
        //     'fruits_they_like',
        //     'plus_one',
        // ));

        // Or we can remove only selected display fields and the rest will
        // display in the same order they appear in the underlying table.
        $this->Form()->removeDisplayFields([
            'id',
            'created_at',
            'updated_at',
        ]);

        // Set field types for fields that aren't just default types
        $this->Form()->setTypes([
            'email' => 'email',
            'attendance_date' => 'date',
            'placard_color' => 'color',
            'photograph' => 'file',
            'phone_number' => 'tel',
            'link_to_website' => 'url',
            'meal_choice' => 'select',
            'fruits_they_like' => 'checkbox',
            'plus_one' => 'radio', // Yes/No enum in database
        ]);

        // Fields set up as Enums in the database will automatically have enum
        // options available, but enums are not requires for multiple choice fields

        $this->Form()->fruits_they_like->options->setOptions([
            'banana' => 'Banana',
            'strawberry' => 'Strawberry',
            'apple' => 'Apple',
            'mango' => 'Mango',
            'passion Fruit' => 'Passion Fruit',
            'orange' => 'Orange',
            'kiwi' => 'Kiwi',
            'pear' => 'Pear',
            'pineapple' => 'Pineapple'
        ]);

        $this->Form()->meal_choice->options->setOptions([
            'cheap_meal' => 'Chicken',
            'average_meal' => 'Beef',
            'expensive_meal' => 'Lobster',
        ]);

        // Make it a multi-select field
        $this->Form()->meal_choice->multiple = true;

        // Set examples to show up below the field
        $this->Form()->setExamples([
            'email' => 'ex: example@example.com',
        ]);

        // Set a pattern (used to add pattern="" attribute to field)
        $this->Form()->phone_number->attributes->pattern = '\\d{3}[\\-]\\d{3}[\\-]\\d{4}';

        // Set a placeholder (similar to example, but uses placeholder attribute)
        $this->Form()->phone_number->attributes->placeholder = '123-456-7890';

        // Set some validation (This uses Laravel's Validator facade:
        // https://laravel.net.cn/docs/5.5/validation
        $this->validation_rules = [
            'email' => 'email|max:256',
            'fruits_they_like' => 'in:'.implode(',', array_keys($this->Form()->fruits_they_like->options->getOptions()),
            'meal_choice' => 'in:'.implode(',', array_keys($this->Form()->meal_choice->options->getOptions())),
            // you can add an validation rules you want here.
        ];

        // Include a delete button?
        $this->Form()->allow_delete = false;

        // Set an arbitrary attribute on the field (This example adds a Vue.js attribute)
        $this->Form()->first_name->attributes->{'v-if'} = 'seen';

    }

    // OPTION 2: Do all of this in the controller. You would choose this
    // method if your form is likely to look different at different routes.
    // If it will always be the same having a method to call is less repetition.
    // You can also modify the form after calling the method above, so a mix of
    // the two works as well.

    // NON-OPTION 3: Do this in the constructor. I would advise against doing this
    // in the constructor since generateFormData() runs a query to the get the
    // table structure. As such doing this in the construstor will result in a
    // query being executed every time the model is instatiated (really bad)

}

控制器

use Excel;

use Nickwest\EloquentForms\TableTrait;

class myController extends Controller
{
    use TableTrait;

    // Make a form, and display it extending another blade template
    public function myGetFormMethod(Request $request, int $id=0)
    {
        $blade_data = [
            'page_title' => 'Sample Form',
            'whatever_else' => 'Any data your base view need can be passed through',
        ];

        // Find the Model if an ID is passed in, otherwise start a new one.
        $Sample = Sample::findOrNew($id);

        // prepare the form as described in the Model method above
        $Sample->prepareForm();

        // This is a FormMaker trait method. It populates form values based on
        // data in the current Model and by defaults and other settings
        // configured in the step before.
        $Sample->setAllFormValues();

        // If there's old request data, set it.
        if($request->old())
        {
            $Sample->setPostValues($request->old());
        }

        // Make a view that extends 'base_layout'
        return $Sample->getFormView($blade_data, 'base_layout', 'content');
    }

    // Make a listing view (table output)
    public function myGetListingMethod()
    {
        // Use the bulma theme
        $this->Table()->setTheme(new \Nickwest\EloquentForms\Themes\bulma\Theme());

        // Set some extra bulma classes onto the table
        $this->Table()->attributes->addClasses(['is-bordered', 'is-striped', 'is-narrow', 'is-fullwidth']);

        // Column headings
        $this->Table()->setLabels([
            'phone_number' => 'Calling digits',
        ]);

        // Make it so this field links to somewhere
        $this->Table()->addLinkingPattern('last_name', '/sample/form/{id}');
        $this->Table()->addLinkingPattern('email', 'mailto:{email}');

        // Get the collection
        $Samples = Sample::all();

        // Return just the table, but this can also extend another view just like Forms (see TableTrait::getTableView() for details)
        return $this->getTableView($Samples);
    }

    public functionn myExportMethod()
    {
        // Get some data
        $Samples = Sample::all();

        // Set the data (It'll take any collection)
        $this->Table()->setData($Samples);

        // Export to excel
        return Excel::download($this->Table()->Exporter, 'filename.xlsx');
    }
}

提交按钮

提交按钮可以有重复的名称,提交按钮数组以$name.$value为键。默认情况下,表单将添加一个提交按钮。其名称为submit_button,值为Submit。它可以通过以下方式访问。使用这些方法添加的表单将显示在表单的末尾。按钮类型字段也可以作为正常字段添加到表单的任何位置。

    // Remove a submit button
    $Form->removeSubmitButton('submit_button', 'Submit);

    // Add a submit button
    $Form->addSubmitButton('submit_button', 'Submit');

    // Get a submit button
    $Form->getSubmitButton('submit_button', 'Submit);

    // Edit a submit button
    $Form->getSubmitButton('submit_button', 'Submit')->attributes->addClass = 'is-success';

    // Rename a submit button (you can do this through attributes, but this will re-key it in the Form and let you access it with the new name)
    $Form->renameSubmitButton('submit_button', 'Submit', 'save_button', 'Save');

其他

EloquentForms不需要使用特型。Form和Field类也可以单独使用。它们不会自动生成表单字段,而需要手动声明。