Skip to content

[6.1] Subform Grid layout, an alternative for unresponsive Table layout #3672

@jgerman-bot

Description

@jgerman-bot

New language relevant PR in upstream repo: joomla/joomla-cms#42347 Here are the upstream changes:

Click to expand the diff!
diff --git a/administrator/components/com_users/config.xml b/administrator/components/com_users/config.xml
index 1985f666fad2..652a307306e2 100644
--- a/administrator/components/com_users/config.xml
+++ b/administrator/components/com_users/config.xml
@@ -124,7 +124,7 @@
 			label="COM_USERS_CONFIG_FIELD_DOMAINS_LABEL"
 			hiddenLabel="true"
 			multiple="true"
-			layout="joomla.form.field.subform.repeatable-table"
+			layout="joomla.form.field.subform.repeatable-grid"
 			formsource="administrator/components/com_users/forms/config_domain.xml"
 		/>
 	</fieldset>
diff --git a/administrator/language/en-GB/plg_fields_subform.ini b/administrator/language/en-GB/plg_fields_subform.ini
index e920859e598e..72d787eeee66 100644
--- a/administrator/language/en-GB/plg_fields_subform.ini
+++ b/administrator/language/en-GB/plg_fields_subform.ini
@@ -7,6 +7,7 @@ PLG_FIELDS_SUBFORM="Fields - Subform"
 PLG_FIELDS_SUBFORM_LABEL="Subform (%s)"
 PLG_FIELDS_SUBFORM_PARAMS_CUSTOMFIELD_LABEL="Field"
 PLG_FIELDS_SUBFORM_PARAMS_EDIT_LAYOUT_OPTION_REPEATABLE_FORM_LABEL="Form"
+PLG_FIELDS_SUBFORM_PARAMS_EDIT_LAYOUT_OPTION_REPEATABLE_GRID_LABEL="Form Grid"
 PLG_FIELDS_SUBFORM_PARAMS_EDIT_LAYOUT_OPTION_REPEATABLE_TABLE_LABEL="Table"
 PLG_FIELDS_SUBFORM_PARAMS_MAX_ROWS_LABEL="Maximum Rows"
 PLG_FIELDS_SUBFORM_PARAMS_OPTIONS_LABEL="Fields"
diff --git a/build/media_source/templates/administrator/atum/scss/blocks/_form.scss b/build/media_source/templates/administrator/atum/scss/blocks/_form.scss
index 4f50b115fd0c..aa65e32b7c49 100644
--- a/build/media_source/templates/administrator/atum/scss/blocks/_form.scss
+++ b/build/media_source/templates/administrator/atum/scss/blocks/_form.scss
@@ -240,6 +240,41 @@ div.subform-repeatable-group {
   }
 }
 
+// Subform Grid layout
+.subform-repeatable-grid>.subform-repeatable-group {
+  padding-top: 16px;
+}
+.subform-grid-row {
+  display: flex;
+  flex-flow: row wrap;
+  column-gap: 1rem;
+
+  > .control-group {
+    flex: 1 1 220px;
+    flex-flow: column;
+
+    > .control-label {
+      width: 100%;
+    }
+
+    > .controls {
+      width: 100%;
+      min-width: unset;
+    }
+  }
+
+  // For groupByFieldset="true"
+  > fieldset {
+    flex: 1 1 220px;
+
+    > .control-group {
+      > .control-label {
+        width: 100%;
+      }
+    }
+  }
+}
+
 // Highlight draggable section
 .subform-repeatable-group[draggable="true"] {
   // For non table layout
diff --git a/build/media_source/templates/site/cassiopeia/scss/blocks/_form.scss b/build/media_source/templates/site/cassiopeia/scss/blocks/_form.scss
index 41fa174ae191..6a8d1a1a9d05 100644
--- a/build/media_source/templates/site/cassiopeia/scss/blocks/_form.scss
+++ b/build/media_source/templates/site/cassiopeia/scss/blocks/_form.scss
@@ -212,6 +212,41 @@ div.subform-repeatable-group {
   }
 }
 
+// Subform Grid layout
+.subform-repeatable-grid>.subform-repeatable-group {
+  padding-top: 16px;
+}
+.subform-grid-row {
+  display: flex;
+  flex-flow: row wrap;
+  column-gap: 1rem;
+
+  > .control-group {
+    flex: 1 1 220px;
+    flex-flow: column;
+
+    > .control-label {
+      width: 100%;
+    }
+
+    > .controls {
+      width: 100%;
+      min-width: unset;
+    }
+  }
+
+  // For groupByFieldset="true"
+  > fieldset {
+    flex: 1 1 220px;
+
+    > .control-group {
+      > .control-label {
+        width: 100%;
+      }
+    }
+  }
+}
+
 // Highlight draggable section
 .subform-repeatable-group[draggable="true"] {
   // For non table layout
diff --git a/layouts/joomla/form/field/subform/repeatable-grid.php b/layouts/joomla/form/field/subform/repeatable-grid.php
new file mode 100644
index 000000000000..73056dfad5d4
--- /dev/null
+++ b/layouts/joomla/form/field/subform/repeatable-grid.php
@@ -0,0 +1,74 @@
+<?php
+
+/**
+ * @package     Joomla.Site
+ * @subpackage  Layout
+ *
+ * @copyright   (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
+ * @license     GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Factory;
+use Joomla\CMS\Form\Form;
+use Joomla\CMS\Language\Text;
+
+extract($displayData);
+
+/**
+ * Layout variables
+ * -----------------
+ * @var   Form    $tmpl             The Empty form for template
+ * @var   array   $forms            Array of JForm instances for render the rows
+ * @var   bool    $multiple         The multiple state for the form field
+ * @var   int     $min              Count of minimum repeating in multiple mode
+ * @var   int     $max              Count of maximum repeating in multiple mode
+ * @var   string  $name             Name of the input field.
+ * @var   string  $fieldname        The field name
+ * @var   string  $fieldId          The field ID
+ * @var   string  $control          The forms control
+ * @var   string  $label            The field label
+ * @var   string  $description      The field description
+ * @var   string  $class            Classes for the container
+ * @var   array   $buttons          Array of the buttons that will be rendered
+ * @var   bool    $groupByFieldset  Whether group the subform fields by it`s fieldset
+ */
+if ($multiple) {
+    // Add script
+    Factory::getApplication()
+        ->getDocument()
+        ->getWebAssetManager()
+        ->useScript('webcomponent.field-subform');
+}
+
+$class = $class ? ' ' . $class : '';
+
+$sublayout = empty($groupByFieldset) ? 'section' : 'section-byfieldsets';
+?>
+
+<div class="subform-repeatable-wrapper subform-layout-grid">
+    <joomla-field-subform class="subform-repeatable<?php echo $class; ?> subform-repeatable-grid" name="<?php echo $name; ?>"
+        button-add=".group-add" button-remove=".group-remove" button-move="<?php echo empty($buttons['move']) ? '' : '.group-move' ?>"
+        repeatable-element=".subform-repeatable-group" minimum="<?php echo $min; ?>" maximum="<?php echo $max; ?>">
+        <?php if (!empty($buttons['add'])) : ?>
+        <div class="btn-toolbar">
+            <div class="btn-group">
+                <button type="button" class="group-add btn btn-sm button btn-success" aria-label="<?php echo Text::_('JGLOBAL_FIELD_ADD'); ?>">
+                    <span class="icon-plus icon-white" aria-hidden="true"></span>
+                </button>
+            </div>
+        </div>
+        <?php endif; ?>
+    <?php
+    foreach ($forms as $k => $form) :
+        echo $this->sublayout($sublayout, ['form' => $form, 'basegroup' => $fieldname, 'group' => $fieldname . $k, 'buttons' => $buttons]);
+    endforeach;
+    ?>
+    <?php if ($multiple) : ?>
+    <template class="subform-repeatable-template-section hidden"><?php
+        echo trim($this->sublayout($sublayout, ['form' => $tmpl, 'basegroup' => $fieldname, 'group' => $fieldname . 'X', 'buttons' => $buttons]));
+    ?></template>
+    <?php endif; ?>
+    </joomla-field-subform>
+</div>
diff --git a/layouts/joomla/form/field/subform/repeatable-grid/section-byfieldsets.php b/layouts/joomla/form/field/subform/repeatable-grid/section-byfieldsets.php
new file mode 100644
index 000000000000..210b8c6a7bb3
--- /dev/null
+++ b/layouts/joomla/form/field/subform/repeatable-grid/section-byfieldsets.php
@@ -0,0 +1,56 @@
+<?php
+
+/**
+ * @package     Joomla.Site
+ * @subpackage  Layout
+ *
+ * @copyright   (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
+ * @license     GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Form\Form;
+use Joomla\CMS\Language\Text;
+
+extract($displayData);
+
+/**
+ * Layout variables
+ * -----------------
+ * @var   Form    $form       The form instance for render the section
+ * @var   string  $basegroup  The base group name
+ * @var   string  $group      Current group name
+ * @var   array   $buttons    Array of the buttons that will be rendered
+ */
+?>
+
+<div class="subform-repeatable-group" data-base-name="<?php echo $basegroup; ?>" data-group="<?php echo $group; ?>">
+    <?php if (!empty($buttons)) : ?>
+    <div class="btn-toolbar text-end">
+        <div class="btn-group">
+            <?php if (!empty($buttons['add'])) :
+                ?><button type="button" class="group-add btn btn-sm btn-success" aria-label="<?php echo Text::_('JGLOBAL_FIELD_ADD'); ?>"><span class="icon-plus icon-white" aria-hidden="true"></span> </button><?php
+            endif; ?>
+            <?php if (!empty($buttons['remove'])) :
+                ?><button type="button" class="group-remove btn btn-sm btn-danger" aria-label="<?php echo Text::_('JGLOBAL_FIELD_REMOVE'); ?>"><span class="icon-minus icon-white" aria-hidden="true"></span> </button><?php
+            endif; ?>
+            <?php if (!empty($buttons['move'])) :
+                ?><button type="button" class="group-move btn btn-sm btn-primary" aria-label="<?php echo Text::_('JGLOBAL_FIELD_MOVE'); ?>"><span class="icon-arrows-alt icon-white" aria-hidden="true"></span> </button><?php
+            endif; ?>
+        </div>
+    </div>
+    <?php endif; ?>
+    <div class="subform-grid-row">
+    <?php foreach ($form->getFieldsets() as $fieldset) : ?>
+    <fieldset class="<?php echo !empty($fieldset->class) ? $this->escape($fieldset->class) : ''; ?>">
+        <?php if (!empty($fieldset->label)) : ?>
+            <legend><?php echo Text::_($fieldset->label); ?></legend>
+        <?php endif; ?>
+        <?php foreach ($form->getFieldset($fieldset->name) as $field) : ?>
+            <?php echo $field->renderField(); ?>
+        <?php endforeach; ?>
+    </fieldset>
+    <?php endforeach; ?>
+    </div>
+</div>
diff --git a/layouts/joomla/form/field/subform/repeatable-grid/section.php b/layouts/joomla/form/field/subform/repeatable-grid/section.php
new file mode 100644
index 000000000000..fbd2c10b4019
--- /dev/null
+++ b/layouts/joomla/form/field/subform/repeatable-grid/section.php
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * @package     Joomla.Site
+ * @subpackage  Layout
+ *
+ * @copyright   (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
+ * @license     GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Form\Form;
+use Joomla\CMS\Language\Text;
+
+extract($displayData);
+
+/**
+ * Layout variables
+ * -----------------
+ * @var   Form    $form       The form instance for render the section
+ * @var   string  $basegroup  The base group name
+ * @var   string  $group      Current group name
+ * @var   array   $buttons    Array of the buttons that will be rendered
+ */
+?>
+
+<div class="subform-repeatable-group" data-base-name="<?php echo $basegroup; ?>" data-group="<?php echo $group; ?>">
+    <?php if (!empty($buttons)) : ?>
+    <div class="btn-toolbar text-end">
+        <div class="btn-group">
+            <?php if (!empty($buttons['add'])) :
+                ?><button type="button" class="group-add btn btn-sm btn-success" aria-label="<?php echo Text::_('JGLOBAL_FIELD_ADD'); ?>"><span class="icon-plus icon-white" aria-hidden="true"></span> </button><?php
+            endif; ?>
+            <?php if (!empty($buttons['remove'])) :
+                ?><button type="button" class="group-remove btn btn-sm btn-danger" aria-label="<?php echo Text::_('JGLOBAL_FIELD_REMOVE'); ?>"><span class="icon-minus icon-white" aria-hidden="true"></span> </button><?php
+            endif; ?>
+            <?php if (!empty($buttons['move'])) :
+                ?><button type="button" class="group-move btn btn-sm btn-primary" aria-label="<?php echo Text::_('JGLOBAL_FIELD_MOVE'); ?>"><span class="icon-arrows-alt icon-white" aria-hidden="true"></span> </button><?php
+            endif; ?>
+        </div>
+    </div>
+    <?php endif; ?>
+    <div class="subform-grid-row">
+    <?php foreach ($form->getGroup('') as $field) : ?>
+        <?php echo $field->renderField(); ?>
+    <?php endforeach; ?>
+    </div>
+</div>
diff --git a/layouts/joomla/form/field/subform/repeatable-table.php b/layouts/joomla/form/field/subform/repeatable-table.php
index 8490ea3f1ec8..6596a10a876c 100644
--- a/layouts/joomla/form/field/subform/repeatable-table.php
+++ b/layouts/joomla/form/field/subform/repeatable-table.php
@@ -82,12 +82,12 @@
 ?>
 
 <div class="subform-repeatable-wrapper subform-table-layout subform-table-sublayout-<?php echo $sublayout; ?>">
-    <joomla-field-subform class="subform-repeatable<?php echo $class; ?>" name="<?php echo $name; ?>"
+    <joomla-field-subform class="subform-repeatable<?php echo $class; ?> subform-repeatable-table" name="<?php echo $name; ?>"
         button-add=".group-add" button-remove=".group-remove" button-move="<?php echo empty($buttons['move']) ? '' : '.group-move' ?>"
         repeatable-element=".subform-repeatable-group"
         rows-container="tbody.subform-repeatable-container" minimum="<?php echo $min; ?>" maximum="<?php echo $max; ?>">
         <div class="table-responsive">
-            <table class="table" id="subfieldList_<?php echo $fieldId; ?>">
+            <table class="table table-bordered" id="subfieldList_<?php echo $fieldId; ?>">
                 <caption class="visually-hidden">
                     <?php echo Text::_('JGLOBAL_REPEATABLE_FIELDS_TABLE_CAPTION'); ?>
                 </caption>
diff --git a/layouts/joomla/form/field/subform/repeatable/section-byfieldsets.php b/layouts/joomla/form/field/subform/repeatable/section-byfieldsets.php
index 4713233ba9b6..ab462169eba0 100644
--- a/layouts/joomla/form/field/subform/repeatable/section-byfieldsets.php
+++ b/layouts/joomla/form/field/subform/repeatable/section-byfieldsets.php
@@ -45,9 +45,7 @@
     <?php endif; ?>
     <div class="row">
         <?php foreach ($form->getFieldsets() as $fieldset) : ?>
-        <fieldset class="<?php if (!empty($fieldset->class)) {
-            echo $fieldset->class;
-                         } ?>">
+        <fieldset class="<?php echo !empty($fieldset->class) ? $this->escape($fieldset->class) : ''; ?>"
             <?php if (!empty($fieldset->label)) : ?>
                 <legend><?php echo Text::_($fieldset->label); ?></legend>
             <?php endif; ?>
diff --git a/plugins/fields/list/params/list.xml b/plugins/fields/list/params/list.xml
index 4e21dcdef3aa..ae1f6b45c897 100644
--- a/plugins/fields/list/params/list.xml
+++ b/plugins/fields/list/params/list.xml
@@ -26,11 +26,11 @@
 				name="options"
 				type="subform"
 				label="PLG_FIELDS_LIST_PARAMS_OPTIONS_LABEL"
-				layout="joomla.form.field.subform.repeatable-table"
+				layout="joomla.form.field.subform.repeatable-grid"
 				icon="list"
 				multiple="true"
 				>
-				<form hidden="true" name="list_templates_modal" repeat="true">
+				<form>
 					<field
 						name="name"
 						type="text"
diff --git a/plugins/fields/subform/params/subform.xml b/plugins/fields/subform/params/subform.xml
index de8264800355..6b744c633fc3 100644
--- a/plugins/fields/subform/params/subform.xml
+++ b/plugins/fields/subform/params/subform.xml
@@ -31,7 +31,7 @@
 				type="subform"
 				label="PLG_FIELDS_SUBFORM_PARAMS_OPTIONS_LABEL"
 				icon="list"
-				layout="joomla.form.field.subform.repeatable-table"
+				layout="joomla.form.field.subform.repeatable-grid"
 				min="1"
 				multiple="true"
 				>
@@ -73,8 +73,9 @@
 					showon="repeat:1"
 					>
 					<option value="">JDEFAULT</option>
-					<option value="joomla.form.field.subform.repeatable-table">PLG_FIELDS_SUBFORM_PARAMS_EDIT_LAYOUT_OPTION_REPEATABLE_TABLE_LABEL</option>
 					<option value="joomla.form.field.subform.repeatable">PLG_FIELDS_SUBFORM_PARAMS_EDIT_LAYOUT_OPTION_REPEATABLE_FORM_LABEL</option>
+					<option value="joomla.form.field.subform.repeatable-grid">PLG_FIELDS_SUBFORM_PARAMS_EDIT_LAYOUT_OPTION_REPEATABLE_GRID_LABEL</option>
+					<option value="joomla.form.field.subform.repeatable-table">PLG_FIELDS_SUBFORM_PARAMS_EDIT_LAYOUT_OPTION_REPEATABLE_TABLE_LABEL</option>
 				</field>
 			</fieldset>
 		</fieldset>

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions