Hi there! I just thought it would be cool/helpful to have som kind of help text popping up upon hover (on bigger screens).
I haven't found it with nubuilder but the idea i take from some other (low-code) platforms (say dataexpress[ru], rei3[de]).
My rough imagination's (screenshot attached) an icon on the opposite end from the label, hovering on which short help/hint text pops up.
Welcome to the nuBuilder Forums!
Register and log in to access exclusive forums and content available only to registered users.
Register and log in to access exclusive forums and content available only to registered users.
Help popup text
-
- nuBuilder Team
- Posts: 4416
- Joined: Sun Oct 14, 2018 6:43 pm
- Has thanked: 74 times
- Been thanked: 472 times
- Contact:
Re: Help popup text
That’s a great idea!
We could also place the icon on the right side of the object.
This way, it won’t interfere with the label when the label is positioned differently (for example, right-aligned, which is the default in nuBuilder).
It might look like this (with an HTML tooltip appearing on mouse-over):
We could also place the icon on the right side of the object.
This way, it won’t interfere with the label when the label is positioned differently (for example, right-aligned, which is the default in nuBuilder).
It might look like this (with an HTML tooltip appearing on mouse-over):
You do not have the required permissions to view the files attached to this post.
-
- nuBuilder Team
- Posts: 4416
- Joined: Sun Oct 14, 2018 6:43 pm
- Has thanked: 74 times
- Been thanked: 472 times
- Contact:
Re: Help popup text
The following function adds a “?” button to all objects that have a nu-help-text attribute.
Alternatively, add the help text by code, just before calling nuAttachHelpIconsToObjects()
Example:
And here is an example to set the nu-help-text attribute:
Could you try it out on your end?
Alternatively, add the help text by code, just before calling nuAttachHelpIconsToObjects()
Example:
Code: Select all
$('#sus_first_name').attr('nu-help-text', `
Enter your <b>legal first name</b> as it appears on official documents.<br>
✨ This will be used for identity verification and correspondence.<br>
<i>Example:</i> John, Maria, Somchai
`.trim());
nuAttachHelpIconsToObjects({
gapRight: 8,
iconSize: 32
});
And here is an example to set the nu-help-text attribute:
Code: Select all
nu-help-text="This is a sample <b>hint</b><br>line 2..."
Code: Select all
function nuAttachHelpIconsToObjects({
selector = 'input[nu-help-text], textarea[nu-help-text], select[nu-help-text]',
gapRight = 8, // px gap outside right edge
iconSize = 16, // px
zIndex = 50,
iconClasses = 'fa-solid fa-circle-question', // FA6
fallbackIconClasses = 'fa fa-question-circle', // FA4/5
onClick = null, // optional: (el, helpHTML) => {}
} = {}) {
// Tooltip container (created once)
let tooltip = document.getElementById('nu-help-tooltip');
if (!tooltip) {
tooltip = document.createElement('div');
tooltip.id = 'nu-help-tooltip';
tooltip.style.position = 'absolute';
tooltip.style.background = 'rgba(50,50,50,0.95)';
tooltip.style.color = '#fff';
tooltip.style.padding = '6px 8px';
tooltip.style.borderRadius = '4px';
tooltip.style.fontSize = '13px';
tooltip.style.maxWidth = '250px';
tooltip.style.zIndex = String(zIndex + 1);
tooltip.style.pointerEvents = 'none';
tooltip.style.display = 'none';
tooltip.style.boxShadow = '0 2px 4px rgba(0,0,0,0.3)';
document.body.appendChild(tooltip);
}
// Overlay for icons
let overlay = document.getElementById('nu-help-overlay');
if (!overlay) {
overlay = document.createElement('div');
overlay.id = 'nu-help-overlay';
overlay.style.position = 'absolute';
overlay.style.left = '0';
overlay.style.top = '0';
overlay.style.width = '0';
overlay.style.height = '0';
overlay.style.zIndex = String(zIndex);
overlay.style.pointerEvents = 'none';
document.body.appendChild(overlay);
}
const faLoaded = !!document.querySelector(
'link[href*="fontawesome"], link[href*="font-awesome"], script[src*="fontawesome"], script[src*="font-awesome"]'
);
const ICONS = nuAttachHelpIconsToObjects._icons || new Map();
nuAttachHelpIconsToObjects._icons = ICONS;
const fields = Array.from(document.querySelectorAll(selector))
.filter(el => el.hasAttribute('nu-help-text'));
const current = new Set(fields);
fields.forEach((el) => {
let rec = ICONS.get(el);
if (!rec) {
const icon = document.createElement('i');
icon.className = (faLoaded ? iconClasses : fallbackIconClasses);
icon.style.position = 'absolute';
icon.style.fontSize = iconSize + 'px';
icon.style.lineHeight = '1';
icon.style.pointerEvents = 'auto';
icon.style.opacity = '0.95';
icon.style.cursor = onClick ? 'pointer' : 'help';
icon.style.color = '#53a1c4'; // icon color
// Custom HTML tooltip events
icon.addEventListener('mouseenter', () => {
tooltip.innerHTML = el.getAttribute('nu-help-text') || '';
tooltip.style.display = 'block';
const r = icon.getBoundingClientRect();
const pageX = window.pageXOffset;
const pageY = window.pageYOffset;
tooltip.style.left = (r.left + pageX) + 'px';
tooltip.style.top = (r.bottom + pageY + 4) + 'px';
});
icon.addEventListener('mouseleave', () => {
tooltip.style.display = 'none';
});
if (typeof onClick === 'function') {
icon.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
onClick(el, el.getAttribute('nu-help-text') || '');
});
}
overlay.appendChild(icon);
const ro = new ResizeObserver(() => positionIcon(el, icon));
ro.observe(el);
const mo = new MutationObserver(() => {});
mo.observe(el, { attributes: true, attributeFilter: ['nu-help-text'] });
rec = { icon, ro, mo };
ICONS.set(el, rec);
}
positionIcon(el, rec.icon);
});
// Remove old icons
ICONS.forEach((rec, el) => {
if (!current.has(el) || !document.body.contains(el)) {
try { rec.ro.disconnect(); } catch {}
try { rec.mo.disconnect(); } catch {}
if (rec.icon.parentNode === overlay) overlay.removeChild(rec.icon);
ICONS.delete(el);
}
});
if (!nuAttachHelpIconsToObjects._bound) {
const refreshAll = () => {
ICONS.forEach(({ icon }, el) => positionIcon(el, icon));
};
window.addEventListener('scroll', refreshAll, { passive: true });
window.addEventListener('resize', refreshAll);
nuAttachHelpIconsToObjects._bound = true;
}
nuAttachHelpIconsToObjects.refresh = () => {
ICONS.forEach(({ icon }, el) => positionIcon(el, icon));
};
function positionIcon(el, icon) {
const r = el.getBoundingClientRect();
const pageX = window.pageXOffset;
const pageY = window.pageYOffset;
icon.style.left = (r.right + gapRight + pageX) + 'px';
icon.style.top = (r.top + pageY + Math.round(r.height / 2) - Math.round(iconSize / 2)) + 'px';
}
}
// Example call
nuAttachHelpIconsToObjects({
gapRight: 8,
iconSize: 16
});
Could you try it out on your end?
You do not have the required permissions to view the files attached to this post.
-
- nuBuilder Team
- Posts: 4416
- Joined: Sun Oct 14, 2018 6:43 pm
- Has thanked: 74 times
- Been thanked: 472 times
- Contact:
Re: Help popup text
Documentation nuAttachHelpIconsToObjects()
Add small “help” icons next to form fields that have a nu-help-text attribute. Hover shows a tooltip with your help text; you can also handle clicks.
Good for
Call the helper after the fields are in the DOM (e.g. in the form's Custom Code section:
Basic usage with options
Options (explained)
Refreshing (dynamic forms)
If you add or remove fields later, call:
What to put in nu-help-text
Styling notes
Add small “help” icons next to form fields that have a nu-help-text attribute. Hover shows a tooltip with your help text; you can also handle clicks.
Good for
- Quickly adding inline help to inputs, textareas, and selects
- Keeping forms clean while still offering guidance
- You add a nu-help-text attribute to any form object.
- Call nuAttachHelpIconsToObjects() once after the fields exist in the DOM.
- An icon appears to the right; hover to see a custom tooltip. (Click support is optional.)
Call the helper after the fields are in the DOM (e.g. in the form's Custom Code section:
Code: Select all
nuAttachHelpIconsToObjects(); // use defaults
Code: Select all
nuAttachHelpIconsToObjects({
selector: 'input[nu-help-text], textarea[nu-help-text], select[nu-help-text]', // what to scan
gapRight: 8, // px gap from the field’s right edge
iconSize: 16, // px
zIndex: 50, // stacking order (icons under tooltip)
iconClasses: 'fa-solid fa-circle-question', // Font Awesome 6 (if loaded)
fallbackIconClasses: 'fa fa-question-circle', // FA4/FA5 fallback (if FA not detected)
onClick: null // optional: function(el, helpHTML) {}
});
- selector: CSS selector to find fields. Only elements with nu-help-text actually get icons. Default targets input/textarea/select.
- gapRight: Pixels to place the icon to the right of the field. Default: 8.
- iconSize: Icon size in pixels. Default: 16.
- zIndex: Base stacking context for the overlay (tooltip is +1). Default: 50.
- iconClasses: Classes for Font Awesome 6 icons (used if FA is detected).
- fallbackIconClasses: Classes for older FA versions (or when FA isn’t detected).
- onClick: Optional handler to run when the icon is clicked. Receives:
- el: the field element
- helpHTML: the help text (inner HTML from nu-help-text)
Code: Select all
nuAttachHelpIconsToObjects({
onClick: function (el, helpHTML) {
// You could open a modal, log usage, or focus the field
alert(helpHTML);
el.focus();
}
});
If you add or remove fields later, call:
Code: Select all
nuAttachHelpIconsToObjects(); // to attach to any new fields
nuAttachHelpIconsToObjects.refresh(); // to reposition existing icons
- Short, actionable guidance (HTML allowed).
- Keep it concise; the tooltip wraps at \~250px width.
Code: Select all
<input nu-help-text="<b>Username</b>: 4–20 chars, letters & digits only.">
- Icon color defaults to #53a1c4. Override via CSS on #nu-help-overlay i.
- Tooltip is a lightweight custom element (#nu-help-tooltip) with a dark theme; override with CSS.
- The overlay (#nu-help-overlay) and tooltip are created once per page.
- Icons automatically reposition on window scroll and resize.
- Each field is watched with ResizeObserver to keep alignment accurate.
- Changing nu-help-text updates the tooltip content on next hover.
- Removing a field cleans up its observers and icon automatically.
- Works with or without Font Awesome. If FA is present, uses iconClasses; otherwise uses fallbackIconClasses.
- Run after your form elements exist (e.g., after page load or after rendering in nuBuilder).
- Icon overlaps another element: increase gapRight or adjust CSS for #nu-help-overlay i.
- Icon hidden behind other UI: raise zIndex.
- Icons not showing: make sure your fields actually have nu-help-text. Check your selector if you customized it.
Re: Help popup text
Pretty good/big job !:)
I think it works on per-form basis, the base function (nuAttachHelpIconsToObjects) should be inserted in the form where we want nu-help-text field attribute working.
But Is it possible to place it some place (say) in the application setup header once and then use "nu-help-text" in all desired field ?
Feeling like i forgot much of web-dev stuff i used to know years ago when actually kept learning))
I think it works on per-form basis, the base function (nuAttachHelpIconsToObjects) should be inserted in the form where we want nu-help-text field attribute working.
But Is it possible to place it some place (say) in the application setup header once and then use "nu-help-text" in all desired field ?
Feeling like i forgot much of web-dev stuff i used to know years ago when actually kept learning))
-
- nuBuilder Team
- Posts: 4416
- Joined: Sun Oct 14, 2018 6:43 pm
- Has thanked: 74 times
- Been thanked: 472 times
- Contact:
Re: Help popup text
The function will be built directly into nuBuilder's core files, so in most cases, you won’t need to call it manually.
However, if you want to use different settings (such as icon size, spacing, etc.), you will have the option to customise them.
Once the integration is complete, I will post more information here.
However, if you want to use different settings (such as icon size, spacing, etc.), you will have the option to customise them.
Once the integration is complete, I will post more information here.