Soft Limit Function on a Craft CMS Text Field Using a Module
A short tutorial showing how to add a soft limit on characters for a Craft CMS text field. We use a module to achieve this functionally without using a plugin. A module is a great way to include website/client-centric logic in Craft CMS.
Set up module structure
Inside your Craft CMS project's root create the following directory structure for the new module, along with the main module class SiteModule.php
.
modules
├─── Module.php
└─── sitemodule/
└─── src/
├─── SiteModule.php
└─── assets/
├─── SiteAssets.php
└─── js/
└─── site.js
Set up class autoloading
Tell Composer how to find your module’s classes by setting the autoload
field in your project’s composer.json
file.
"autoload": {
"psr-4": {
"modules\\sitemodule\\": "modules/sitemodule/src/"
}
},
With that in place, go to your project’s directory in your terminal, and run the following command:
composer dump-autoload -a
That will tell Composer to update its class autoloader script based on your new autoload
mapping.
Update the application config
We can then add the module to your project’s application configuration by listing it in the modules and bootstrap arrays. This can be done by editing the project's config/app.php
file:
<?php
use craft\helpers\App;
return [
'id' => App::env('APP_ID') ?: 'CraftCMS',
'modules' => [
'site-module' => \modules\sitemodule\SiteModule::class,
],
'bootstrap' => ['site-module'],
];
The main module class
The SiteModule.php
file is your module’s entry point for the system. Its init()
method is the best place to register event listeners, and any other steps it needs to take to initialize itself. Add the following code to your SiteModule.php
file.
<?php
namespace modules\sitemodule;
use modules\sitemodule\assets\SiteAssets;
use Craft;
use craft\events\TemplateEvent;
use craft\web\View;
use yii\base\Event;
use yii\base\Module;
class SiteModule extends Module
{
public function init(): void
{
parent::init();
Craft::setAlias('@sitemodule', __DIR__);
if (Craft::$app->getRequest()->getIsCpRequest()) {
Event::on(
View::class,
View::EVENT_BEFORE_RENDER_TEMPLATE,
function (TemplateEvent $event) {
Craft::$app->getView()->registerAssetBundle(SiteAssets::class);
}
);
}
}
}
Create an Asset Bundle
We then create an Asset Bundle so we can register specific CSS and JS files Add the following asset bundle to your SiteAssets.php
file.
<?php
namespace modules\sitemodule\assets;
use craft\web\AssetBundle;
use craft\web\assets\cp\CpAsset;
class SiteAssets extends AssetBundle
{
public function init(): void
{
$this->sourcePath = '@sitemodule/assets';
$this->depends = [
CpAsset::class,
];
$this->js = [
'js/site.js',
];
parent::init();
}
}
Soft Limit JavaScript
So inside of the site.js
is where we add our JavaScript for our soft limit functionality. We specifically target field-summary
in my example. summary
being the handle of the text field we are limiting. Original CodePen https://codepen.io/stamd/pen/B...
let textArea = document.getElementById("fields-summary");
let characterCounter = document.createElement('span');
characterCounter.textContent = '250/250';
const maxNumOfChars = 250;
function insertAfter(referenceNode, newNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
if (textArea) {
insertAfter(textArea, characterCounter);
const countCharacters = () => {
let numOfEnteredChars = textArea.value.length;
let counter = maxNumOfChars - numOfEnteredChars;
characterCounter.textContent = counter + "/250";
if (counter < 0) {
characterCounter.style.color = "red";
} else if (counter < 20) {
characterCounter.style.color = "orange";
} else {
characterCounter.style.color = "black";
}
};
window.addEventListener('load', countCharacters, false);
textArea.addEventListener("input", countCharacters, false);
}
Resources
- https://craftcms.com/docs/4.x/...
- https://craftquest.io/courses/my-first-craft-cms-module
- https://doublesecretagency.github.io/craft-businesslogic/
- https://nystudio107.com/blog/enhancing-a-craft-cms-3-website-with-a-custom-module
- https://verbb.io/blog/everything-you-need-to-know-about-modules
- https://johnhenry.ie/articles/...
- https://codepen.io/stamd/pen/B...