themeum/kirki

Multiple Select fields in a Repeater field don't appear correctly

irisinteractive opened this issue · 0 comments

Issue description:

The Repeater control's initSelect method does not work correctly when instantiating multiple Select fields

Version used:

4.2.0

Using theme_mods or options?

options

PHP error messages that might be related

Nothing

JS error messages that might be related

Nothing

Code to reproduce the issue (config + field(s))

<?php

use Kirki\Panel;
use Kirki\Section;

new Panel('panel', [
    'priority'    => 10,
    'title'       => __( 'My panel', DOMAIN ),
    'description' => __( 'Description of my panel', DOMAIN ),
]);

new Section('section', [
    'title' => 'My section',
    'panel' => 'panel'
]);

new \Kirki\Field\Repeater(
    [
        'settings' => 'repeater_setting',
        'label'    => esc_html__( 'Repeater Control', 'domain' ),
        'section'  => 'section',
        'priority' => 10,
        'default'  => [
            [
                'link_text'   => esc_html__( 'Kirki Site', 'domain' ),
                'link_url'    => 'https://kirki.org/',
                'link_target' => '_self',
                'link_target_2' => '_blank2',
                'checkbox'    => false,
            ],
            [
                'link_text'   => esc_html__( 'Kirki WP', 'domain' ),
                'link_url'    => 'https://wordpress.org/plugins/kirki/',
                'link_target' => '_blank',
                'link_target_2' => '_other',
                'checkbox'    => true,
            ],
        ],
        'fields'   => [
            'link_text'   => [
                'type'        => 'text',
                'label'       => esc_html__( 'Link Text', 'domain' ),
                'description' => esc_html__( 'Description', 'kirki' ),
                'default'     => '',
            ],
            'link_url'    => [
                'type'        => 'text',
                'label'       => esc_html__( 'Link URL', 'domain' ),
                'description' => esc_html__( 'Description', 'domain' ),
                'default'     => '',
            ],
            'link_target' => [
                'type'        => 'select',
                'label'       => esc_html__( 'Link Target', 'domain' ),
                'description' => esc_html__( 'Description', 'domain' ),
                'default'     => '_self',
                'choices'     => [
                    '_blank' => esc_html__( 'New Window', 'domain' ),
                    '_self'  => esc_html__( 'Same Frame', 'domain' ),
                ],
            ],
            'checkbox'    => [
                'type'    => 'checkbox',
                'label'   => esc_html__( 'Checkbox', 'domain' ),
                'default' => false,
            ],
            'link_target_2' => [
                'type'        => 'select',
                'label'       => esc_html__( 'Link Target 2', 'domain' ),
                'description' => esc_html__( 'Description', 'domain' ),
                'default'     => '_other',
                'choices'     => [
                    '_blank2' => esc_html__( 'New Window', 'domain' ),
                    '_self2'  => esc_html__( 'Same Frame', 'domain' ),
                    '_other'  => esc_html__( 'Other Frame', 'domain' ),
                ],
            ],
        ],
    ]
);

In the initSelect method of the kirki-packages/control-repeater/src/control.js file, I tested looping over the dropdown array, and that fixes the problem.

  initSelect: function (theNewRow, data) {
    var control = this,
      // Change dropdown by dropdowns
      dropdowns = theNewRow.container.find(".repeater-field select"),
      dataField;

    if (0 === dropdowns.length) {
      return;
    }

    // Loop over dropdowns
    _.each(dropdowns, (dropdown) => {
      dropdown = jQuery(dropdown);

      dataField = dropdown.data("field");
      multiple = jQuery(dropdown).data("multiple");

      data = data || {};
      data[dataField] = data[dataField] || "";

      jQuery(dropdown).val(data[dataField] || jQuery(dropdown).val());

      this.container.on("change", ".repeater-field select", function (event) {
        var currentDropdown = jQuery(event.target),
          row = currentDropdown.closest(".repeater-row"),
          rowIndex = row.data("row"),
          currentSettings = control.getValue();

        currentSettings[rowIndex][currentDropdown.data("field")] =
          jQuery(this).val();
        control.setValue(currentSettings);
      });
    })

  },

Looking forward to a resolution, thank you!