We routinely configure sites to use make use of Composer to create new pages, often with lots of attributes that get used on custom page and block templates. This then makes it really easy for our clients to manage pages on their sites with structured content, and we can programatically control output.
One minor but recurring problem with this approach is that a Composer form can get pretty long, especially if you’re using lots of individual attributes that aren’t always used. We had a client the other day ask whether it was possible to make some of their long composer forms a bit more condensed, as one of their forms had 30 fields in a row that they sometimes use. And they weren’t fields we could condense down into new attribute types, they had to stay as seperate fields.
With the Composer page/form being core behaviour, I wanted to find a way to override this, but in a fairly lightweight way, and something I could remove easily if my override caused an issue with future upgrades. I came up with something quite simple, admittedly a bit hacky (and using jQuery), but I thought it was worth sharing. It’s an easy one to drop into a site.
What you would do is drop the following code, into a file at /application/elements/page_types/composer/form/output/form.php
<?php
defined('C5_EXECUTE') or die("Access Denied.");
include_once(DIR_BASE_CORE .'/elements/page_types/composer/form/output/form.php'); ?>
<script>
$("fieldset legend:contains('+')").each(function(index) {
$(this).text( $(this).text().replace('+', ''));
let fieldset = $(this).closest('fieldset');
fieldset.attr('id', 'composer-fieldset-' + index);
let fields = fieldset.find('.form-group');
$(this).append('<button class="btn btn-sm btn-info pull-right float-end expand-fields" aria-expanded="false" data-label="<?= t('View Fields');?> (' + fields.length + ')" aria-controls="composer-fieldset-' + index + '" href=""><?= t('View Fields');?> (' + fields.length + ')</button>');
fields.hide();
});
$('.expand-fields').click(function(event){
event.preventDefault();
$(this).closest('fieldset').find('.form-group').toggle();
if ($(this).attr('aria-expanded') === 'false') {
$(this).text('<?=t('Hide Fields'); ?>');
$(this).attr('aria-expanded', 'true');
} else {
$(this).text($(this).data('label'));
$(this).attr('aria-expanded', 'false');
}
})
</script>
All this does is inject a bit of extra Javascript into the Composer page, the core page itself gets loaded as is. This same code works on V8 and V9.
Then what you do is just add + character to field set Name. When the script runs, it strips this character from the label, but it knows to make that section collapsable.
Then this happens:
On V8:
The only thing I wasn’t 100% sure of was the correct way to load the original elements file, in particular when there’s an upgrade core folder in use. I’ve used the constant DIR_BASE_CORE, but there might be a better way to do that (I always upgrade sites by replacing the core). I have no doubt the Javascript could be improved.
Just thought I’d share in case this is found to be handy, or it prompts some further ideas on Composer forms in general.