Management of form fields

Extending custom components

It is recommended to use the Dcat.init method to listen and initialize the JS code of the form component, otherwise it may not be compatible with dynamically generated fields such as Form::hasMany and Form::array. Form Type.

Integrated rich text editor wangEditor

wangEditor is an excellent domestic lightweight rich text editor, if dcat-admin comes with ckeditor based editor components have issues working, you can integrate it and override the default editor by following the steps below `.

For the convenience of demonstration, CDN link is used directly in the example. In actual development, you need to download the front-end library file wangEditor to the server first and unzip it to the directory public/vendor/wangEditor-4.7.1.

Create a new component class app/Admin/Extensions/Form/WangEditor.php.

  1. <?php
  2. namespace App\Admin\Extensions\Form;
  3. use Dcat\Admin\Form\Field;
  4. class WangEditor extends Field
  5. {
  6. protected $view = 'admin.wang-editor';
  7. }

New view file resources/views/admin/wang-editor.blade.php

  1. <div class="{{$viewClass['form-group']}}">
  2. <label class="{{$viewClass['label']}} control-label">{{$label}}</label>
  3. <div class="{{$viewClass['field']}}">
  4. @include('admin::form.error')
  5. <div {!! $attributes !!} style="width: 100%; height: 100%;">
  6. <p>{!! $value !!}</p>
  7. </div>
  8. <input type="hidden" name="{{$name}}" value="{{ old($column, $value) }}" />
  9. @include('admin::form.help-block')
  10. </div>
  11. </div>
  12. <!-- script tags with the "init" attribute will automatically listen dynamically for element generation using the Dcat.init() method -->
  13. <script require="@wang-editor" init="{!! $selector !!}">
  14. var E = window.wangEditor
  15. // The id variable is automatically generated by Dcat.init() and is a unique random string
  16. var editor = new E('#' + id);
  17. editor.config.zIndex = 0
  18. editor.config.uploadImgShowBase64 = true
  19. editor.config.onchange = function (html) {
  20. $this.parents('.form-field').find('input[type="hidden"]').val(html);
  21. }
  22. editor.create()
  23. </script>

Then register into dcat-admin and add the following code to app/Admin/bootstrap.php.

  1. <?php
  2. use App\Admin\Extensions\Form\WangEditor;
  3. use Dcat\Admin\Form;
  4. // Register front-end component aliases
  5. Admin::asset()->alias('@wang-editor', [
  6. // To facilitate the demonstration effect, here directly loaded CDN link, the actual development can be downloaded to the server to load
  7. 'js' => ['https://cdn.jsdelivr.net/npm/wangeditor@4.7.1/dist/wangEditor.min.js'],
  8. ]);
  9. Form::extend('editor', WangEditor::class);

Calling:

  1. $form->editor('body');

Integrated rich text editor ckeditor

Download ckeditor and extract it to the /public directory, e.g. put it in /public/packages/.

Then create a new extension file app/Admin/Extensions/Form/CKEditor.php:

  1. <?php
  2. namespace App\Admin\Extensions\Form;
  3. use Dcat\Admin\Form\Field;
  4. class CKEditor extends Field
  5. {
  6. protected $view = 'admin.ckeditor';
  7. }

New view resources/views/admin/ckeditor.blade.php:

  1. <div class="{{$viewClass['form-group']}}">
  2. <label class="{{$viewClass['label']}} control-label">{{$label}}</label>
  3. <div class="{{$viewClass['field']}}">
  4. @include('admin::form.error')
  5. <textarea name="{{ $name}}" placeholder="{{ $placeholder }}" {!! $attributes !!} >{!! $value !!}</textarea>
  6. @include('admin::form.help-block')
  7. </div>
  8. </div>
  9. <script require="@ckeditor" init="{!! $selector !!}">
  10. $this.ckeditor();
  11. </script>

Then in app/Admin/bootstrap.php, import the extension:

  1. use App\Admin\Extensions\Form\CKEditor;
  2. use Dcat\Admin\Form;
  3. // Register front-end component aliases
  4. Admin::asset()->alias('@ckeditor', [
  5. 'js' => [
  6. '/packages/ckeditor/ckeditor.js',
  7. '/packages/ckeditor/adapters/jquery.js',
  8. ],
  9. ]);
  10. Form::extend('ckeditor', CKEditor::class);

Then you can use it in a form:

  1. $form->ckeditor('content');

Integrated PHP editor

Extend a PHP code editor based on codemirror by following the steps below, with reference to PHP mode.

Download and extract the codemirror library to a front-end resource directory, such as public/packages/codemirror-5.20.2.

Create a new component class app/Admin/Extensions/Form/PHPEditor.php:

  1. <?php
  2. namespace App\Admin\Extensions\Form;
  3. use Dcat\Admin\Form\Field;
  4. class PHPEditor extends Field
  5. {
  6. protected $view = 'admin.php-editor';
  7. }

{tip} Static resources in the class can also be brought in from outside, see Editor.php

Creating View resources/views/admin/php-editor.blade.php:

  1. <div class="{{$viewClass['form-group']}}">
  2. <label class="{{$viewClass['label']}} control-label">{{$label}}</label>
  3. <div class="{{$viewClass['field']}}">
  4. @include('admin::form.error')
  5. <textarea class="{{ $class }}" {!! $attributes !!} >{!! $value !!}</textarea>
  6. <input type="hidden" name="{{$name}}" value="{{ old($column, $value) }}" />
  7. @include('admin::form.help-block')
  8. </div>
  9. </div>
  10. <script require="@phpeditor" init="{!! $selector !!}">
  11. var Editor = CodeMirror.fromTextArea(document.getElementById(id), {
  12. lineNumbers: true,
  13. mode: "text/x-php",
  14. extraKeys: {
  15. "Tab": function(cm){
  16. cm.replaceSelection(" " , "end");
  17. }
  18. }
  19. });
  20. Editor.on("change", function (Editor, changes) {
  21. let val = Editor.getValue();
  22. //console.log(val);
  23. $this.parents('.form-field').find('input[type="hidden"]').val(val);
  24. });
  25. </script>

Finally find the file app/Admin/bootstrap.php, if the file does not exist, please update dcat-admin, then create the file, add the following code:

  1. <?php
  2. use App\Admin\Extensions\Form\PHPEditor;
  3. use Dcat\Admin\Form;
  4. Admin::asset()->alias('@phpeditor', [
  5. 'js' => [
  6. '/packages/codemirror-5.20.2/lib/codemirror.js',
  7. '/packages/codemirror-5.20.2/addon/edit/matchbrackets.js',
  8. '/packages/codemirror-5.20.2/mode/htmlmixed/htmlmixed.js',
  9. '/packages/codemirror-5.20.2/mode/xml/xml.js',
  10. '/packages/codemirror-5.20.2/mode/javascript/javascript.js',
  11. '/packages/codemirror-5.20.2/mode/css/css.js',
  12. '/packages/codemirror-5.20.2/mode/clike/clike.js',
  13. '/packages/codemirror-5.20.2/mode/php/php.js',
  14. ],
  15. 'css' => '/packages/codemirror-5.20.2/lib/codemirror.css',
  16. ]);
  17. Form::extend('php', PHPEditor::class);

This will allow you to use the PHP editor in model-form:

  1. $form->php('code');

In this way, you can add as many form components as you want.

Common methods

The form component is the most complex component in Dcat Admin, the following is a list of methods that may be needed to extend the form component

Process user-entered form values (prepareInputValue)

The prepareInputValue method processes the form values entered by the user and does not do any processing by default. This method is executed after the Form form’s saving event is fired and before the saving method of the form field.

{tip} This is similar to the mutator in the Laravel model.

  1. class PHPEditor extends Field
  2. {
  3. ...
  4. // Converts user-entered form values into string format for saving to database
  5. protected function prepareInputValue($value)
  6. {
  7. return (string) $value;
  8. }
  9. }

Process the value of the field to be displayed (formatFieldData)

The formatFieldData method is used to process the value of the field to be displayed. This method is executed before the customFormat method of the form field.

{tip} This function is similar to the accessor in the Laravel model.

  1. class PHPEditor extends Field
  2. {
  3. ...
  4. // Convert field values to array format.
  5. // $data is the edit data of the current form, the data format is array
  6. protected function formatFieldData($data)
  7. {
  8. // Get the current field value
  9. $value = parent::formatFieldData($data);
  10. // Processing field values
  11. ...
  12. return $value;
  13. }
  14. }

Get the element CSS selector (getElementClassSelector)

When the form component class is instantiated, it generates a css class according to the field name, which is then passed to the template.

Template

  1. <div class="{{$viewClass['form-group']}}">
  2. <div class="{{ $viewClass['label'] }} control-label">
  3. <span>{!! $label !!}</span>
  4. </div>
  5. <div class="{{$viewClass['field']}}">
  6. @include('admin::form.error')
  7. <input type="hidden" name="{{$name}}"/>
  8. <select style="width: 100%;" name="{{$name}}" {!! $attributes !!} >
  9. <option value=""></option>
  10. @foreach($options as $select => $option)
  11. <option value="{{$select}}" {{ Dcat\Admin\Support\Helper::equal($select, $value) ?'selected':'' }}>{{$option}}</option>
  12. @endforeach
  13. </select>
  14. @include('admin::form.help-block')
  15. </div>
  16. </div>
  17. <script require="..." init="{!! $selector !!}">
  18. // where $selector is the css selector for the current field.
  19. $this.select2($configs);

JS code

In order for the extended form component to be compatible with HasMany, array and Table forms, we must use the dynamic listening element generation (init) feature

  1. <div class="{{$viewClass['form-group']}}">
  2. ...
  3. </div>
  4. <script require="..." init="{!! $selector !!}">
  5. $this.select2($configs);
  6. </script>