octobercmsoctobercms-pluginsoctobercms-widgets

OctoberCMS: how to set repeater widget autoload / populate value for new records


can i set the repeater widget to auto load when the form open?

it has max item property, can it auto load to max item number

so user dont need to hit the prompt button

re-updated

this my fields.yaml

fields:
nowarta:
    label: 'No. Warta'
    oc.commentPosition: ''
    span: auto
    placeholder: 'format penulisan ''No. 34 Tahun XIX'''
    type: text
tanggal:
    label: Tanggal
    oc.commentPosition: ''
    mode: date
    format: 'd - F - Y'
    span: right
    type: datepicker
    ignoreTimezone: false
renungan:
    label: 'Renungan Mingguan'
    oc.commentPosition: ''
    span: full
    type: section
renungan[judul]:
    label: 'Judul Renungan'
    oc.commentPosition: ''
    span: storm
    type: text
    cssClass: 'col-sm-6 col-sm-push-0'
renungan[bahanbaca]:
    label: 'Bahan Bacaan'
    oc.commentPosition: ''
    span: storm
    type: text
    cssClass: col-sm-6
renungan[isi]:
    label: Renungan
    oc.commentPosition: ''
    span: storm
    cssClass: 'col-sm-12 col-sm-push-0'
    type: richeditor
    size: huge
tabs:
fields:
    temakebum:
        label: 'Kebaktian Umum'
        oc.commentPosition: ''
        span: full
        type: section
        tab: 'Kebaktian Umum & Komisi'
    temakebum[tema]:
        tab: 'Kebaktian Umum & Komisi'
        label: Tema
        oc.commentPosition: ''
        span: storm
        cssClass: col-sm-11
        type: text
    temakebum[bacaan]:
        label: 'Bahan Bacaan'
        oc.commentPosition: ''
        span: storm
        cssClass: col-sm-6
        type: text
        tab: 'Kebaktian Umum & Komisi'
    temakebum[pujian]:
        label: Pujian
        oc.commentPosition: ''
        span: storm
        cssClass: col-sm-6
        type: text
        tab: 'Kebaktian Umum & Komisi'
    kebum:
        label: ''
        oc.commentPosition: ''
        prompt: 'Tambah Data'
        maxItems: '3'
        span: full
        type: repeater
        tab: 'Kebaktian Umum & Komisi'
        form:
            fields:
                jeniskeb:
                    label: 'Jenis Kebaktian'
                    oc.commentPosition: ''
                    span: storm
                    cssClass: col-sm-4
                    type: dropdown
                    options: jenisKeb
                khotbah:
                    label: Pengkhotbah
                    oc.commentPosition: ''
                    span: storm
                    cssClass: col-sm-4
                    placeholder: ''
                    type: text
              

dd($form->fields)

array:6 [▼
  "nowarta" => array:5 [▶]
  "tanggal" => array:7 [▶]
  "renungan" => array:4 [▶]
  "renungan[judul]" => array:5 [▶]
  "renungan[bahanbaca]" => array:5 [▶]
  "renungan[isi]" => array:6 [▶]
]

and this what i have done in controller as you want it to be..

class WartaRutin extends Controller
{
    public $implement = ['Backend\Behaviors\ListController','Backend\Behaviors\FormController','Backend\Behaviors\ReorderController'    ];
    
    public $listConfig = 'config_list.yaml';
    public $formConfig = 'config_form.yaml';
    public $reorderConfig = 'config_reorder.yaml';

    public function __construct()
    {
        parent::__construct();
        BackendMenu::setContext('Mismaiti.MyWarta', 'main-menu-item', 'side-menu-rutin');
    }

    public function formExtendFieldsBefore($form) {    
    // we are checking we are creating record or updating
    // or even we can use $form->context here but I used $model->id
    // if $form->context == 'update'
    // if $form->context == 'create'
        if(is_null($form->model->id)) {
            // create time
            $iteration = $form->fields['kebum']['maxItems'];

            if(is_numeric($iteration) && $iteration > 0) {
                $emptyFields = [];
                while($iteration > 0) {                        
                    $emptyFields[] = ['jeniskeb' => ''];
                    $iteration--;
                }
                $form->model->kebum = $emptyFields;
            }

        }
        
    }
}

and it return an error when i tried to execute-- i have replace all repeater_data to kebum

"Undefined index: kebum" on line 30 of C:\xampp\htdocs\mywarta\plugins\mismaiti\mywarta\controllers\WartaRutin.php

am i missing something here..?


Solution

  • hmm, we can use one trick, that as you may only need this at create time or may be you can extend it at update time as well,

    I used field repeater_data you can replace it with your field field

    fields.yaml

    fields:
    
        ... other fields ...
    
        repeater_data:
            label: Repeater
            oc.commentPosition: ''
            prompt: 'Add new item'
            maxItems: '5'
            span: auto
            type: repeater
            form:
                fields:
                    title:
                        label: Text
                        oc.commentPosition: ''
                        span: auto
                        type: text
                    category:
                        label: Dropdown
                        oc.commentPosition: ''
                        options:
                            1: 'Item 1'
                            2: 'Item 2'
                        span: auto
                        type: dropdown
    

    controller

    inside your controller you need to add this method and code

    public function formExtendFieldsBefore($form) {
    
        // we are checking we are creating record or updating
        // or even we can use $form->context here but I used $model->id
        // if $form->context == 'update'
        // if $form->context == 'create'
        if(is_null($form->model->id)) {
    
            // create time **logic**
            $iteration = $form->fields['repeater_data']['maxItems'];
            if(is_numeric($iteration) && $iteration > 0) {
                $emptyFields = [];
                while($iteration > 0) {
    
                    // here you need to provide at least one field 
                    // which you used in repeater I used `title`
                    // and let it be empty or may be some default value 
                    $emptyFields[] = ['title' => ''];
                    $iteration--;
                }
                // dummy fields assignment to current form model
                $form->model->repeater_data = $emptyFields;
            }
            // **logic**
    
        }
        else {
    
            // if you need to adjust data in update time
            // you need to find difference and then need to add
            // additional dummy data as we are adding above
        }
    }
    

    There is 2 scenarios create time and update time

    Create time

    When user is creating record we will add dummy fields so repeater will show them as they are already there and it is done using maxItems property of that field so its fully dynamic, now user don't need to press that button.

    Update time ( Suppose maxItems=5)

    Now for 2nd scenario we have else condition if you wish you can add some logic and do your stuff there, Suppose user may add only 2 records at a time so next time we need to add 3 dummy fields (2 filled + 3 dummy = total 5 as maxItem) so you can calculate there and add it from else part.

    I hope this will help you, If you find any difficulties please comment.