octobercmsoctobercms-backend

Octobercms show title and image of a gallery in backend


I have 2 tables, "Actuality" and "Gallery", with Many to Many relationships, and I included attach Many relationships to Gallery table. Now when doing the relations in Octobercms backend, I want to show the images of the gallery with the title when creating an actuality.

Gallery table


relation

List-view


list-view

How can I achieve Below layout for relation form field ?


requestd-output


Solution

  • Original Post here : https://tutorialmeta.com/october-cms/customizing-form-field-widget-markup

    Result Output

    final-output

    Relation

    // Hardik\Demo\Models\Collection <- model 
    public $belongsToMany = [
        'galleries' => [
            'Hardik\Demo\Models\Gallery',
            'table' => 'hardik_demo_collection_gallery'
        ]
    ];
    

    Field configuration

    fields:
        galleries:
            label: Galaries
            nameFrom: title
            descriptionFrom: description
            span: left
            type: relation
    

    Lets override relation widget partial

    use System\Classes\PluginBase;
    use Hardik\Demo\Controllers\Collection;
    use Hardik\Demo\Models\Collection as CollectionModel;
    
    class Plugin extends PluginBase
    {
        public function boot() {
    
            // we only want to happen on Collection controller
    
            Collection::extendFormFields(function($form, $model, $context) {
    
                // and when model is CollectionModel     
                if (!$model instanceof CollectionModel) {
                 return;
                }
    
                // we add path for our own partial file
                \Backend\FormWidgets\Relation::extend(function($widget) {
                    $widget->addViewPath(
                       \File::symbolizePath('~/plugins/hardik/demo/field_partials')
                    );
              });
          });
        }
    
        // ....  other code  
    }
    

    Now, lets create our own _realtion.htm file with our own markup which will override default partial file. plugins/hardik/demo/field_partials/_relation.htm

    I added marks which things I added manually with // WE ADDED THIS - start and // WE ADDED THIS - start comments.

    <div class="relation-widget" id="<?= $this->getId() ?>">
    <?php
    // We added this condition exclusivly for our gallery relation
    // we also know its many to many and we will do only
    // for this field 'Collection[galleries]' else it will render normally
    if($field->getName() != 'Collection[galleries]') {
        // for other relation fields we do normal partial as it is
        // modules/backend/formwidgets/relation/partials/_relation.htm
        echo $this->makePartial('~/modules/backend/widgets/form/partials/_field_'.$field->type.'.htm', ['field' => $field]);
    } else {
        // for our 'Collection[galleries]' field
        // we used this _field_checkboxlist's content
        // modules/backend/widgets/form/partials/_field_checkboxlist.htm
        $fieldOptions = $field->options();
        $checkedValues = (array) $field->value;
        $isScrollable = count($fieldOptions) > 10;
        $readOnly = $this->previewMode || $field->readOnly || $field->disabled;
        $quickselectEnabled = $field->getConfig('quickselect', $isScrollable);
    
        // WE ADDED THIS - start
        list($model, $attribute) = $this->resolveModelAttribute($this->valueFrom);
        $relationType = $model->getRelationType($attribute);
        $relationModel = $model->makeRelation($attribute);
        // WE ADDED THIS - end
        ?>
        <!-- Checkbox List -->
        <?php if ($readOnly && $field->value): ?>
    
            <div class="field-checkboxlist">
                <?php $index = 0; foreach ($fieldOptions as $value => $option): ?>
                    <?php
                        $index++;
                        $checkboxId = 'checkbox_'.$field->getId().'_'.$index;
                        if (!in_array($value, $checkedValues)) continue;
                        if (is_string($option)) $option = [$option];
                    ?>
                    <div class="checkbox custom-checkbox">
                        <input
                            type="checkbox"
                            id="<?= $checkboxId ?>"
                            name="<?= $field->getName() ?>[]"
                            value="<?= e($value) ?>"
                            disabled="disabled"
                            checked="checked">
    
                        <label for="<?= $checkboxId ?>">
                            <?= e(trans($option[0])) ?>
                        </label>
                        <?php if (isset($option[1])): ?>
                            <p class="help-block"><?= e(trans($option[1])) ?></p>
                        <?php endif ?>
                    </div>
                <?php endforeach ?>
            </div>
    
        <?php elseif (!$readOnly && count($fieldOptions)): ?>
    
            <div class="field-checkboxlist <?= $isScrollable ? 'is-scrollable' : '' ?>">
                <?php if ($quickselectEnabled): ?>
                    <!-- Quick selection -->
                    <div class="checkboxlist-controls">
                        <div>
                            <a href="javascript:;" data-field-checkboxlist-all>
                                <i class="icon-check-square"></i> <?= e(trans('backend::lang.form.select_all')) ?>
                            </a>
                        </div>
                        <div>
                            <a href="javascript:;" data-field-checkboxlist-none>
                                <i class="icon-eraser"></i> <?= e(trans('backend::lang.form.select_none')) ?>
                            </a>
                        </div>
                    </div>
                <?php endif ?>
    
                <div class="field-checkboxlist-inner">
    
                    <?php if ($isScrollable): ?>
                        <!-- Scrollable Checkbox list -->
                        <div class="field-checkboxlist-scrollable">
                            <div class="control-scrollbar" data-control="scrollbar">
                    <?php endif ?>
    
                    <input
                        type="hidden"
                        name="<?= $field->getName() ?>"
                        value="0" />
    
                    <?php $index = 0; foreach ($fieldOptions as $value => $option): ?>
                        <?php
                            $index++;
                            $checkboxId = 'checkbox_'.$field->getId().'_'.$index;
                            if (is_string($option)) $option = [$option];
                            $gallery = $relationModel::find($value);
                        ?>
                        <div class="checkbox custom-checkbox">
                            <input
                                type="checkbox"
                                id="<?= $checkboxId ?>"
                                name="<?= $field->getName() ?>[]"
                                value="<?= e($value) ?>"
                                <?= in_array($value, $checkedValues) ? 'checked="checked"' : '' ?>>
    
                            <label for="<?= $checkboxId ?>">
                                <?= e(trans($option[0])) ?>
                            </label>
                            <div>
                              <?php
                                // WE ADDED THIS - start
                                $style = 'height:80px;width:100px;margin-right:1rem;';
                                foreach ($gallery->photos as $photo) {
                                  echo "<img style='{$style}' src='{$photo->getPath()}' />";
                                }
                                // WE ADDED THIS - end
                              ?>
                            </div>
                            <?php if (isset($option[1])): ?>
                                <p class="help-block"><?= e(trans($option[1])) ?></p>
                            <?php endif ?>
                        </div>
                    <?php endforeach ?>
    
                    <?php if ($isScrollable): ?>
                            </div>
                        </div>
                    <?php endif ?>
    
                </div>
    
            </div>
    
        <?php else: ?>
    
            <!-- No options specified -->
            <?php if ($field->placeholder): ?>
                <p><?= e(trans($field->placeholder)) ?></p>
            <?php endif ?>
    
        <?php endif ?>
    <?php } ?>
    </div>
    

    Result Output

    final-output