Skip to content

Clickables

This document lists all clickable/interactive elements in the application and explains how they work, how events are triggered, and how to implement role-based access control (RBAC) for them.


  • ID Pattern: id="clickable_*" (e.g., clickable_language, clickable_admin)
  • Registration: Automatically detected and registered by load_clickable() function during page load
  • Event Trigger: Uses data-click attribute containing JSON operation details
  • Event Flow:
    1. User clicks element
    2. click_object("clickable", elementId) is called
    3. checkRolePermission(elementId) is checked (RBAC check)
    4. If permission granted → process_operation(operation_details) executes
<a href="#"
id="clickable_language"
data-click='{"operation": "show_menu", "menu_name": "menu_language", "reset": true, "locked": false}'>
<i class="fas fa-language"></i>
</a>
  • Registration: internal.jsload_clickable() (line ~4519)
  • Event Handler: internal.jsclick_object() (line ~5144)
  • RBAC Check: internal.jscheckRolePermission() (line ~5257)
  • Found in 118 HTML files with pattern id="clickable_*"

  • ID Pattern: id="button_*" (e.g., button_login, button_submit)
  • Registration: Automatically detected and registered by load_button() function during page load
  • Event Trigger: Uses data-click attribute containing JSON operation details
  • Event Flow:
    1. User clicks button
    2. click_object("button", elementId) is called
    3. checkRolePermission(elementId) is checked (RBAC check)
    4. If permission granted → process_operation(operation_details) executes
<a href="#"
id="button_login"
class="btn btn-m ankur_btn_1"
data-click='{"operation": "show_menu", "menu_name": "menu_number", "reset": true, "locked": false}'>
Login
</a>
  • Registration: internal.jsload_button() (line ~4340)
  • Event Handler: internal.jsclick_object() (line ~5144)
  • RBAC Check: internal.jscheckRolePermission() (line ~5257)
  • Found in 118 HTML files with pattern id="button_*"

3. Elements with text_ Prefix (Clickable Text)

Section titled “3. Elements with text_ Prefix (Clickable Text)”
  • ID Pattern: id="text_*" (e.g., text_nursery, text_header)
  • Registration: Automatically detected and registered by load_text() function during page load
  • Event Trigger: Uses data-click attribute containing JSON operation details
  • Event Flow:
    1. User clicks text element
    2. click_object("text", elementId) is called
    3. checkRolePermission(elementId) is checked (RBAC check)
    4. If permission granted → process_operation(operation_details) executes
<h1 id="text_nursery"
data-click='{"operation": "link", "page_name": "dashboard", "parameters": {}, "history": true}'>
Nursery
</h1>
  • Registration: internal.jsload_text() (line ~4262)
  • Event Handler: internal.jsclick_object() (line ~5144)
  • RBAC Check: internal.jscheckRolePermission() (line ~5257)
  • Found in 118 HTML files with pattern id="text_*"

4. Menu Buttons (Alert/Processing/Calendar Dialogs)

Section titled “4. Menu Buttons (Alert/Processing/Calendar Dialogs)”
  • ID Pattern:
    • system_menu_alert_button_1, system_menu_alert_button_2, system_menu_alert_button_3
    • system_menu_processing_button_1, system_menu_processing_button_2, system_menu_processing_button_3
    • system_menu_calendar_button_1, system_menu_calendar_button_2, system_menu_calendar_button_3
  • Registration: These are hardcoded HTML elements in the base HTML structure
  • Event Trigger: Uses onclick="click_menu('button_1')" or onclick="click_menu('button_2')" or onclick="click_menu('button_3')"
  • Event Flow:
    1. User clicks menu button
    2. click_menu(location) is called (location = “button_1”, “button_2”, “button_3”, or “outside”)
    3. Function reads from global variables:
      • SYSTEM_menu_button_1_click
      • SYSTEM_menu_button_2_click
      • SYSTEM_menu_button_3_click
      • SYSTEM_menu_outside_click
    4. Executes the operation stored in the global variable (no RBAC check currently)
<div id="system_menu_alert" class="menu">
<div class="menu-title">
<h1 id="system_menu_alert_header">Error</h1>
</div>
<div class="menu-content">
<p id="system_menu_alert_text">Something went wrong</p>
<a href="#" class="btn" onclick="click_menu('button_1')" id="system_menu_alert_button_1">OK</a>
<a href="#" class="btn" onclick="click_menu('button_2')" id="system_menu_alert_button_2">Cancel</a>
<a href="#" class="btn" onclick="click_menu('button_3')" id="system_menu_alert_button_3">Close</a>
</div>
</div>

When show_alert(), show_processing(), or open_calendar() is called, you pass button_click parameter:

show_alert(
"Error",
"Something went wrong",
["fas", "fa-exclamation-triangle"],
["red", "dark"],
false, // locked
true, // language
{ operation: "close" }, // outside_click
[
{ operation: "function", function_name: "myFunction", parameters: {} }, // button_1
{ operation: "close" }, // button_2
{ operation: "link", page_name: "dashboard" } // button_3
]
);
  • Event Handler: internal.jsclick_menu() (line ~2154)
  • Menu Display: internal.jsshow_menu() (line ~2000)
  • Alert Display: internal.jsshow_alert() (line ~2226)
  • Processing Display: internal.jsshow_processing() (line ~2200)
  • NO RBAC CHECK: Menu buttons currently do NOT go through checkRolePermission()
  • Global Variables: Actions are stored in global variables when menu is shown
  • Menu Outside Click: Clicking outside menu triggers click_menu("outside") which uses SYSTEM_menu_outside_click

  • ID Pattern: id="dropdown_*" (e.g., dropdown_language, dropdown_category)
  • Registration: Automatically detected and registered by load_dropdown() function during page load
  • Event Trigger: Uses data-change attribute containing JSON operation details
  • Event Flow:
    1. User changes dropdown selection
    2. change event fires
    3. change_object("dropdown", elementId) is called
    4. process_operation(operation_details) executes (NO RBAC check currently)
<select id="dropdown_language"
data-change='{"operation": "function", "function_name": "changeLanguage", "parameters": {}}'>
<option value="en">English</option>
<option value="hi">Hindi</option>
</select>
  • Registration: internal.jsload_dropdown() (line ~4682)
  • Event Handler: internal.jschange_object() (line ~5097)
  • Change Processing: internal.jsprocess_operation() (line ~5338)
  • NO RBAC CHECK: Dropdowns currently do NOT go through checkRolePermission()
  • Uses data-change instead of data-click

  • ID Pattern: id="checkbox_*" (e.g., checkbox_agree, checkbox_notify)
  • Registration: Automatically detected and registered by load_checkbox() function during page load
  • Event Trigger: Can use data-click attribute containing JSON operation details
  • Event Flow:
    1. User checks/unchecks checkbox
    2. change event fires
    3. click_object("checkbox", elementId) is called
    4. checkRolePermission(elementId) is checked (RBAC check)
    5. If permission granted → process_operation(operation_details) executes
<input type="checkbox"
id="checkbox_agree"
data-click='{"operation": "function", "function_name": "handleAgreement", "parameters": {}}'>
  • Registration: internal.jsload_checkbox() (line ~4470)
  • Event Handler: internal.jsclick_object() (line ~5144)
  • RBAC Check: internal.jscheckRolePermission() (line ~5257)

  • ID Pattern: id="radio_*" (e.g., radio_option1, radio_option2)
  • Registration: Automatically detected and registered by load_radio() function during page load
  • Event Trigger: Can use data-click attribute containing JSON operation details
  • Event Flow:
    1. User selects radio button
    2. change event fires
    3. click_object("radio", elementId) is called
    4. checkRolePermission(elementId) is checked (RBAC check)
    5. If permission granted → process_operation(operation_details) executes
<input type="radio"
id="radio_option1"
name="options"
data-click='{"operation": "function", "function_name": "handleOption", "parameters": {}}'>
  • Registration: internal.jsload_radio() (line ~4421)
  • Event Handler: internal.jsclick_object() (line ~5144)
  • RBAC Check: internal.jscheckRolePermission() (line ~5257)

8. Operation Types in data-click / data-change

Section titled “8. Operation Types in data-click / data-change”

All operations support these types:

{
"operation": "show_menu",
"menu_name": "menu_language",
"reset": true,
"locked": false
}
{
"operation": "hide_menu",
"open_last": true,
"reset": false
}
{
"operation": "link",
"page_name": "dashboard",
"parameters": {"batch_id": 1},
"history": true
}
{
"operation": "function",
"function_name": "myFunction",
"parameters": {"param1": "value1"}
}
{
"operation": "alert"
}
{
"operation": "toast"
}

9. How to Implement Role-Based Access Control (RBAC)

Section titled “9. How to Implement Role-Based Access Control (RBAC)”

RBAC is implemented in checkRolePermission(clickableId) function in internal.js (line ~5257).

  1. Mapping: Define clickable IDs and their required roles in CLICKABLE_ROLES_MAPPING constant
  2. Check: When a clickable element is clicked, checkRolePermission() is called
  3. Validation: Function compares user roles (from global("user_roles")) with required roles
  4. Result: Returns true if user has required role, false otherwise
  5. Action: If false, process_operation() is NOT called
// internal.js line ~5247
const CLICKABLE_ROLES_MAPPING = {
// Example entries (to be populated in future):
// "clickable_admin": ["Nursery_Owner"],
// "clickable_manager": [1, 2], // role_ids
// "clickable_specific": [{"role_id": 1, "role_name": "Nursery_Owner"}]
};
const CLICKABLE_ROLES_MAPPING = {
"clickable_admin": ["Nursery_Owner"],
"clickable_manager": ["Nursery_Manager"],
"clickable_worker": ["Nursery_Worker"]
};
const CLICKABLE_ROLES_MAPPING = {
"clickable_admin": [1], // role_id = 1
"clickable_manager": [2, 3], // role_id = 2 or 3
};
const CLICKABLE_ROLES_MAPPING = {
"clickable_admin": [
{"role_id": 1, "role_name": "Nursery_Owner"},
{"role_id": 2, "role_name": "Nursery_Manager"}
]
};
const CLICKABLE_ROLES_MAPPING = {
"button_delete": ["Nursery_Owner"],
"button_edit": ["Nursery_Owner", "Nursery_Manager"],
"button_view": ["Nursery_Owner", "Nursery_Manager", "Nursery_Worker"]
};
const CLICKABLE_ROLES_MAPPING = {
"text_admin_panel": ["Nursery_Owner"],
"text_settings": ["Nursery_Owner", "Nursery_Manager"]
};

User roles are stored in global("user_roles") as a JSON string. Example:

[
{
"role_id": 1,
"role_name": "Nursery_Owner",
"role_description": null,
"role_category": "NURSERY"
}
]

The checkRolePermission() function matches roles by:

  • role_id (number)
  • role_name (string)
  • role_category (string)

If any of these match between user roles and required roles, access is granted.


10. Elements That Currently DON’T Have RBAC

Section titled “10. Elements That Currently DON’T Have RBAC”

These elements do NOT go through checkRolePermission():

  1. Menu Buttons (system_menu_alert_button_1, etc.)

    • Use click_menu() function
    • Actions are stored in global variables
    • To add RBAC: Modify click_menu() function to check roles before executing
  2. Dropdown Elements (dropdown_*)

    • Use change_object() function
    • To add RBAC: Modify change_object() function to check roles before process_operation()
  3. Input Elements (input_*)

    • Use data-change attribute
    • To add RBAC: Modify change_object() function (if inputs use it)

Element TypeID PatternRegistration FunctionEvent HandlerRBAC CheckNotes
Clickableclickable_*load_clickable()click_object()✅ YesUses data-click
Buttonbutton_*load_button()click_object()✅ YesUses data-click
Texttext_*load_text()click_object()✅ YesUses data-click
Checkboxcheckbox_*load_checkbox()click_object()✅ YesUses data-click
Radioradio_*load_radio()click_object()✅ YesUses data-click
Menu Buttonssystem_menu_*_button_*Hardcoded HTMLclick_menu()❌ NoUses onclick attribute
Dropdowndropdown_*load_dropdown()change_object()❌ NoUses data-change
Inputinput_*load_input()change_object()❌ NoUses data-change

12. How to Find All Clickable Elements in Your Project

Section titled “12. How to Find All Clickable Elements in Your Project”
Terminal window
# Find all clickable_ elements
grep -r 'id="clickable_' www/
# Find all button_ elements
grep -r 'id="button_' www/
# Find all text_ elements with data-click
grep -r 'id="text_.*data-click' www/
Terminal window
# Find all data-click attributes
grep -r 'data-click' www/
# Find all data-change attributes
grep -r 'data-change' www/
  1. Open browser DevTools (F12)
  2. Run in console:
// Find all clickable elements
document.querySelectorAll('[id^="clickable_"]').forEach(el => console.log(el.id));
// Find all button elements
document.querySelectorAll('[id^="button_"]').forEach(el => console.log(el.id));
// Find all elements with data-click
document.querySelectorAll('[data-click]').forEach(el => console.log(el.id, el.getAttribute('data-click')));

  1. Modify click_menu() function to accept role requirements
  2. Store role requirements in menu configuration
  3. Check roles before executing menu button actions
  1. Modify change_object() function to check roles
  2. Add role mapping for dropdowns similar to CLICKABLE_ROLES_MAPPING
  3. Create DROPDOWN_ROLES_MAPPING constant
  1. Similar to dropdowns, modify change_object() function
  2. Add INPUT_ROLES_MAPPING constant if needed

// In internal.js, add to CLICKABLE_ROLES_MAPPING:
const CLICKABLE_ROLES_MAPPING = {
// Admin only
"clickable_delete_batch": ["Nursery_Owner"],
"button_delete": ["Nursery_Owner"],
// Admin and Manager
"clickable_edit_batch": ["Nursery_Owner", "Nursery_Manager"],
"button_edit": ["Nursery_Owner", "Nursery_Manager"],
// All roles
"clickable_view_batch": ["Nursery_Owner", "Nursery_Manager", "Nursery_Worker"],
"button_view": ["Nursery_Owner", "Nursery_Manager", "Nursery_Worker"],
// By role ID
"clickable_special": [1, 2], // role_id 1 or 2
// By role object
"clickable_premium": [
{"role_id": 1, "role_name": "Nursery_Owner"},
{"role_category": "ADMIN"}
]
};