What is an Uitype?

Definition

An uitype is a graphical element used to represent a form field and format its value according to a context.

Uccello allows you to create forms made up of fields of different types. Each field type corresponds to a uitype.

Each uitype is autonomous, independent and able to format data:

  • In a database

  • In a vue

  • In table cells

  • In the response to an API call

Similarly, each uitype is able to generate a form field to display on an edit page.

Flexible

Thanks to the high flexibility of uccello, it is possible to create simplistic uitypes (a simple value) as well as complex uitypes (display using external libraries).

For example, the text uitype only displays plain text while the entity uitype is able to link one data to another that may be located in a different module. The date uitype allows you to select a date from a calendar.

Configurable

The configuration of a uitype is done at several levels.

  • migration file: Type of the column in the database and type of field used in the form

  • php class: Formatting the value when saving and displaying

  • blade files : Displaying the form field and defining a layout in a view

Let's take the example of the text uitype:

Migration file

// Creation of the table
Schema::create('people', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name'); // This column will be link to a text uitype
    $table->timestamps();
});

...

// Creation of the field
$field = Field::create([
    'name' => 'name',
    'uitype_id' => uitype('text')->id, // Use of the text uitype
    'displaytype_id' => displaytype('everywhere')->id,
    'sequence' => 0,
    'block_id' => $block->id,
    'module_id' => $module->id
]);

$table->string('name') : Creta a column namedname with type VARCHAR(255)

'uitype_id' => uitype('text')->id : The field uses the text uitype

Php class

The text uitype is defined in the file app/Fields/Uitype/Text.php. Here is a summary after integration of the traits used.

namespace Uccello\Core\Fields\Uitype;

use Uccello\Core\Contracts\Field\Uitype;
use Uccello\Core\Fields\Traits\DefaultUitype;
use Uccello\Core\Fields\Traits\UccelloUitype;
use Uccello\Core\Models\Field;
use Uccello\Core\Models\Module;
use Uccello\Core\Models\Domain;

class Text implements Uitype
{
    /**
     * Name of the package in which the uitype is located
     * Useful for Blade to find the associated template files
     */
    public $package = 'uccello';

    /**
     * Field type used by Form builder
     */
    public function getFormType(): string
    {
        return 'text';
    }

    /**
     * Field options used by Form Builder
     */
    public function getFormOptions($record, Field $field, Module $module): array
    {
        return [];
    }

    /**
     * Default database column name
     */
    public function getDefaultDatabaseColumn(Field $field) : string
    {
        return $field->name;
    }

    /**
     * Default icon to use in the form field
     */
    public function getDefaultIcon() : ?string
    {
        return null;
    }

    /**
     * Formatting the value for a display in a view or in an API response
     */
    public function getFormattedValueToDisplay(Field $field, $record) : string
    {
        return $record->{$field->column} ?? '';
    }

    /**
     * Formatting the value before saving it in the database
     */
    public function getFormattedValueToSave(Request $request, Field $field, $value, $record = null, ?Domain $domain = null, ?Module $module = null) : ?string
    {
        return $value;
    }
    
    /**
     * Returns formatted value to save with config.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Uccello\Core\Models\Field $field
     * @param mixed|null $value
     * @param mixed|null $record
     * @param \Uccello\Core\Models\Domain|null $domain
     * @param \Uccello\Core\Models\Module|null $module
     * @return string|null
     */
    public function getFormattedValueToSaveWithConfig(Request $request, Field $field, $value, $config, $record = null, ?Domain $domain = null, ?Module $module = null) : ?string
    {
        return $this->getFormattedValueToSave($request, $field, $value, $record, $domain, $module);
    }

    /**
     * Formatting the value before searching the database.
     * By default adds % at the beginning end the ending to make a 'like' query.
     */
    public function getFormattedValueToSearch($value)
    {
        $formattedValue = $value;

        if ($formattedValue) {
            $formattedValue = "%$value%";
        }

        return $formattedValue;
    }

    /**
     * Adding the condition in the SQL query
     */
    public function addConditionToSearchQuery(Builder $query, Field $field, $value) : Builder
    {
        if (!$this->isEmptyOrNotEmptySearchQuery($query, $field, $value)) {
            $formattedValue = $this->getFormattedValueToSearch($value);
            $query = $query->where($field->column, 'like', $formattedValue);
        }

        return $query;
    }
    
   /**
    * Returns true if the search value is 'Null' or 'NotNull'
    */
    protected function isEmptyOrNotEmptySearchQuery(Builder &$query, Field $field, $value): bool
    {
        if ($value === uctrans('filter.search_flag.empty', $field->module)) {
            $query->where(function ($q) use ($field) {
                $q->whereNull($field->column)
                    ->orWhere($field->column, '=', '');
            });
            return true;
        } elseif ($value === uctrans('filter.search_flag.not_empty', $field->module)) {
            $query = $query->whereNotNull($field->column)
                            ->where($field->column, '!=', '');
            return true;
        }

        return false;
    }
    
    /**
     * Ask the user some specific options relative to a field.
     * Useful with Module Designer.
     */
    public function askFieldOptions(\StdClass &$module, \StdClass &$field, InputInterface $input, OutputInterface $output)
    {
        $repeated = $output->confirm('Would you like to repeat this field (for confirmation)?', false);

        if ($repeated) {
            $field->data->repeated = true;
        }
    }
    
    /**
     * Way to create the column into the database.
     * Useful for Module Designer.
     */
    public function createFieldColumn(Field $field, Blueprint $table) : Fluent
    {
        return $table->string($this->getDefaultDatabaseColumn($field));
    }
    
    /**
     * Text to add into the module migration.*
     * Useful for Module Designer.
     */
    public function createFieldColumnStr(Field $field) : string
    {
        $column = $this->getDefaultDatabaseColumn($field);
        return "\$table->string('$column')";
    }
}

Blade files

There are at least four blade files per uitype. One for the layout of the form field in the edit view, one for displaying the field value in the detail view, one for searching from the list view and one for displaying the field value in the list view.

By default, the text uitype uses blade files:

  • resources/views/modules/default/uitypes/edit/text.blade.php

  • resources/views/modules/default/uitypes/detail/text.blade.php

  • resources/views/modules/default/uitypes/list/text.blade.php

  • resources/views/modules/default/uitypes/search/text.blade.php

Here is the content of the file resources/views/modules/default/uitypes/detail/text.blade.php.

<?php $isLarge = $forceLarge ?? $field->data->large ?? false; ?>
<div class="col m2 s5 field-label">
    <?php $label = uctrans($field->label, $module); ?>
    <b title="{{ $label }}">{{ $label }}</b>
</div>
<div class="col {{ $isLarge ? 's7 m10' : 's7 m4' }}">
    <?php
        $value = uitype($field->uitype_id)->getFormattedValueToDisplay($field, $record);
    ?>
    @if ($value)
        <div class="truncate">
            {{ $value }}
        </div>
    @else
        &nbsp;
    @endif
</div>

Notice the use of the method getFormattedValueToDisplay(Field $field, $record) defined in thephp class.

Expandable

Thanks to the fact that each uitype is autonomous and independent, it is possible to create new ones and share them with the uccello community.

Default Uitypes

Uccello's default uitypes are found in the directory vendor/uccello/uccello/app/Fields/Uitype.

To get an overview of all native uitypes, you can go to the Default Uitypes page.

Last updated