Express Forms, templating as-documented is insufficient (presentation/UX)

Whether it’s v8.x or v9.x, the Concrete Developer Documentation (and seemingly how this “works”) is really insufficient for the styling angle of Express Forms: https://documentation.concretecms.org/9-x/developers/express/form-theming

Now, the documentation is seemingly identical between v8.x and v9.x. I also want to add there is a LOT that I still don’t know here. But after reading the documentation, and contrasting it with my past “janky-ish” methods to style forms, I find myself wanting.

From a form logic, validation, etc, perspective, that seems to be fine (documentation).

But from styling ala CSS, the documentation is completely absent, and some aspects that would make this way easier are substantially absent too.

In my typical use-cases I just want to do CSS styling for certain form elements, and that’s it. I don’t need any validation/logic changes whatsoever, no PHP/JS changes. just CSS.

So in the past I’ll create a view.php and view.css template as one normally would for “any block” except in the CSS files use methods like:

.ccm-block-express-form input[type=text] {
	margin:0px;
	height:30px;
}

or

.ccm-block-express-form fieldset:nth-of-type(1) {
	width:20%;
	padding-bottom:14px;
}
.ccm-block-express-form fieldset:nth-of-type(2) {
}
.ccm-block-express-form fieldset:nth-of-type(3) {
	padding-bottom:7px;
}
.ccm-block-express-form fieldset:nth-of-type(4) {
	padding-bottom:32px;
}

While I have so much more to learn, always, to me this seems “janky” as I’m based on count of rendering of an item on a page, instead of explicitly referencing to an aspect by name.

What I think would really fit the bill is a way to actually add class/id’s/tags to aspects of Forms within the Express Dashboard component that you define a Form via the webGUI and also the programmatical methods for defining Forms. As it stands now, I can only change the label for a field, as in the text presented to the user that is the “name” of that field. I want the class/id’s/tags to be non-visible to the user, as I could definitely see using not-nice-to-read strings.

This way in my view.css template I could apply styling to precisely specific fields and elements. Instead of doing nth-of-type kind of stuff, only to forget about it, and accidentally break a form on a page in the future if I add another form to that page.

Honestly the whole basic styling of forms (as in, no change to logic, etc) really needs a much more simplistic method. Contexts have value if you want to do your own API, extend input validation/logic, etc, but if you’re only doing presentation they are an extremely time-costly and highly-complex method that also really pushes developers away from wanting to use Concrete CMS for something as basic as CSS styling.

Not sure what more to add, but I’m going to create a github Feature Request on the matter and link it below. Would love to have discussion on this matter, but I really do think I’m reading the “tea leaves” correctly here.

GitHub Feature Request for this: Express Forms, templating as-documented is insufficient (presentation/UX) · Issue #11987 · concretecms/concretecms · GitHub

If you agree, or not, would appreciate anyone reading this to also chime-in in the GitHub linked Issue. Thanks! :slight_smile:

I’ve added the field label as a class to the form-group wrapper to help with this problem.


<?php
defined('C5_EXECUTE') or die("Access Denied.");

$text = \Core::make('helper/text');

if ($view->supportsLabel()) {
    $labelClass = $text->urlify($view->getLabel());
} ?>

<div class="form-group custom-form-group <?= ($labelClass ?? '') ?>">
    <?php if ($view->supportsLabel()) { ?>
        <label class="control-label" for="<?=$view->getControlID()?>"><?=$view->getLabel()?></label>
    <?php } ?>

    <?php if ($view->isRequired()) { ?>
        <span class="text-muted small required-label"><?=t('Required')?></span>
    <?php } ?>

    <?php $view->renderControl()?>
</div>