📚 pbMessage — Universal Message Display
pbMessage is a small, general-purpose class that displays success or error messages after pbFetch requests or any async operations of your own. It also handles the confirmation dialog shown before a request.
✅ Why Use It?
- Lets you automatically display messages from JSON responses like
{ success: true|false, message: "..." }. - Works out of the box together with
pbFetch— no manual handling required. - Controlled via the custom
pb:successandpb:errorevents — you can cancel the automatic display. - Gives you a single place to change how messages look across the whole site: plug in your own handler and plain text inside a block becomes toasts or modals.
- Makes it easy to configure the CSS classes, where the message is inserted, and how it is cleared.
⚙️ How It Works
🚦 Core Logic
pbMessage.success(ctx, message)
pbMessage.error(ctx, message)
pbMessage.clear(ctx)ctxis a DOM element inside which the output container is looked up. Usually it's a form or the element frompb-target.pbMessage.success()looks for[pb-success-message], and falls back to[pb-message]if it isn't found.pbMessage.error()looks for[pb-error-message], and falls back to the same[pb-message].- If no container is found, nothing happens.
ctx is required, and it fails silently
All three methods simply return when ctx is empty: no message, no console error. This is exactly what the most common "pbMessage doesn't work" looks like — there is nowhere to put the message. pbFetch uses the element's form as the context, and if there is no form, the element from pb-target; when there is neither, ctx is null.
🏷️ HTML Markup
1️⃣ A single universal container
<div pb-message class="d-none"></div>2️⃣ Separate containers for success and error
<div pb-success-message class="d-none"></div>
<div pb-error-message class="d-none"></div>✔️ It's best to place these containers inside the form or inside the target, so that pbMessage is sure to find them by context.
📌 Form Markup Example
<form id="my-form">
<input type="text" name="name">
<button
type="submit"
pb-post="/api/submit"
pb-expect="json"
pb-include="#my-form input"
>
Submit
</button>
<!-- Better inside the form -->
<p pb-success-message class="text-success d-none"></p>
<p pb-error-message class="text-danger d-none"></p>
</form>The text is inserted via innerHTML — the server can send simple markup (<b>, <a>) right inside message. Which also means escaping user input is the server's job.
🧩 Auto-Integration with pbFetch
A message is displayed when three conditions are met:
- the request was made with
pb-expect="json"(there are no messages at all forhtml); - the response contains a non-empty
data.message; - the corresponding event was not cancelled.
// on response.ok
pbMessage.success(ctx, data.message)
// on an HTTP error
pbMessage.error(ctx, data.message)You can cancel the automatic display by adding this to your handler:
document.addEventListener('pb:success', (e) => {
e.preventDefault(); // the message won't be shown automatically
// your logic
});preventDefault() on pb:success disables more than just the message
On a successful response this event guards the entire JSON handling: the message, the redirect via data.redirect, and the markup replacement from data.html. By cancelling the message you take on the rest as well. On pb:error only the message is cancelled.
❓ Action Confirmation
The pb-confirm attribute of pbFetch calls pbMessage.confirmHandler(el, message) and sends the request only if it returned a truthy value:
<button pb-delete="/cargo/12" pb-expect="json" pb-confirm="Delete the order?">
Delete
</button>The default handler is the browser's confirm(). Here's how to replace it with your own:
pbMessage.setConfirmHandler(async (el, message) => {
const result = await Swal.fire({
title: message,
icon: 'question',
showCancelButton: true,
confirmButtonText: 'Yes, delete it'
});
return result.isConfirmed;
});The handler may be async — it will be awaited. It must return true for the request to go out; an exception thrown inside the handler cancels the request and is logged to the console.
🎨 Configuring Classes via Config and System Settings
By default the message classes come from system settings:
pageblocks_msg_success— classes for a success messagepageblocks_msg_error— classes for errorspageblocks_hidden_class— the class that hides the message container (for example,d-none)
Sample setting values:
pageblocks_msg_success = "text-success"
pageblocks_msg_error = "text-danger,text-error"
pageblocks_hidden_class = "d-none"They are applied not by the pb.message.v300.js file itself, but by the component: with the pageblocks_load_scripts setting enabled, the OnWebPageInit event appends a setConfig() call with these values to the page. The class itself only hardcodes the fallbacks:
pbMessage.config = {
successClasses: ['text-success'],
errorClasses: ['text-error', 'text-danger'],
hiddenClass: 'd-none'
};The classes are Bootstrap ones; PageBlocks ships no styles of its own for them. On a theme without Bootstrap, set your own values in the settings.
You can also override them manually via setConfig():
pbMessage.setConfig({
successClasses: ['alert', 'alert-success'],
errorClasses: ['alert', 'alert-danger'],
hiddenClass: 'hidden' // a TailwindCSS class, for example
});When showing a message, pbMessage removes the hidden class and the classes of the opposite type, then adds the required ones. That's why a single [pb-message] container switches happily from error to success and back.
🧹 Clearing Messages
If you need to remove a message and reset the classes:
pbMessage.clear(form);
// or pbMessage.clear(targetElement);The method walks all three attributes — [pb-success-message], [pb-error-message], [pb-message] — clears the text, puts the hidden class back, and removes the success and error classes.
🔥 Full API
| Method | Description |
|---|---|
pbMessage.success(ctx, message) | Show a success message |
pbMessage.error(ctx, message) | Show an error |
pbMessage.clear(ctx) | Clear all messages and reset the added classes |
pbMessage.setSuccessHandler(fn) | Override the success handler |
pbMessage.setErrorHandler(fn) | Override the error handler |
pbMessage.setConfirmHandler(fn) | Override the confirmation dialog (pb-confirm) |
pbMessage.setConfig({...}) | Set the CSS classes for success/error (class arrays) |
All three set*Handler() methods throw a TypeError if you pass anything other than a function.
✔️ SweetAlert2 Integration
pbMessage.setSuccessHandler((ctx, message) => {
Swal.fire({
icon: 'success',
title: 'Success!',
text: message
});
});
pbMessage.setErrorHandler((ctx, message) => {
Swal.fire({
icon: 'error',
title: 'Error!',
text: message
});
});Your own handler is free to ignore ctx entirely — toasts and modals live on top of the page, and that makes the "there is no message container in the context" problem disappear.