MilkActions - JSON Action Response System
MilkActions is a structured JSON response system that allows backend PHP code to control frontend components via AJAX responses. It provides a unified way to manipulate the DOM, show modals, display notifications, and much more, without writing custom JavaScript.
data-fetch="get" or data-fetch="post",
and forms with .js-needs-validation class.
Features
Modal Management
Complete control of modal sizes, loading states, and content
Toast Notifications
Success, error, warning, and info notifications
Form Management
Reset, set values, and display validation errors
DOM Manipulation
Show/hide, update content, modify classes, styles, and attributes
Scroll Control
Scroll to top or specific elements
JavaScript Hooks
Execute custom JavaScript functions from the server
Basic Usage
Backend (PHP)
use App\Response;
#[RequestAction('myAction')]
public function myAction() {
Response::json([
'success' => true,
'modal' => [
'title' => 'Hello',
'body' => '<p>This is a modal</p>'
],
'toast' => [
'message' => 'Operation completed',
'type' => 'success'
]
]);
}
Frontend (HTML)
<!-- Links with data-fetch automatically use MilkActions -->
<a href="?page=myModule&action=myAction" data-fetch="get" class="btn btn-primary">
Click Me
</a>
1. Modal
Complete control of Bootstrap modals with management of sizes, content, and loading states.
JSON Example
{
"modal": {
"size": "lg", // sm, lg, xl, fullscreen, or default
"action": "show", // show, hide, loading_show, loading_hide
"title": "My Title",
"body": "<p>Content</p>",
"footer": "<button>OK</button>"
}
}
Available Methods
show- Display modalhide- Close modalloading_show- Show with loading spinnerloading_hide- Hide loading spinner
Sizes
sm- Small modallg- Large modalxl- Extra large modalfullscreen- Fullscreen modal- (empty) - Default size
Response::json([
'modal' => [
'size' => 'lg',
'action' => 'loading_show',
'title' => 'Loading...',
'body' => '<p>Please wait...</p>'
]
]);
2. Toast Notifications
Toast notifications for immediate user feedback.
JSON Example
{
"toast": {
"message": "Success!",
"type": "success", // success, danger, warning, primary
"action": "show" // show or hide
}
}
Default Support
MilkActions also supports a simplified format:
{
"msg": "Message here",
"success": true // true = success, false = danger
}
Response::json([
'toast' => [
'message' => 'Data saved successfully',
'type' => 'success'
]
]);
3. Form Management
Complete form management: reset, set values, and display validation errors.
JSON Example
{
"form": {
"action": "reset", // reset form
"id": "myFormId",
"fields": { // set field values
"field_name": "value",
"email": "test@example.com"
},
"errors": { // show validation errors
"field_name": "Error message",
"email": "Invalid email"
}
}
}
Reset Form
Response::json([
'form' => [
'action' => 'reset',
'id' => 'myFormId'
]
]);
Validation Errors
Response::json([
'success' => false,
'form' => [
'errors' => [
'username' => 'Username is required',
'email' => 'Invalid email format',
'password' => 'Password must be at least 8 characters'
]
],
'toast' => [
'message' => 'Please fix the errors',
'type' => 'danger'
]
]);
4. Element Manipulation
Complete DOM manipulation with support for single elements or multiple groups.
Single Element
{
"element": {
"selector": "#myElement",
"action": "show", // show, hide, remove, toggle
"innerHTML": "<p>New content</p>",
"innerText": "Text only",
"value": "Input value",
"addClass": "highlight active",
"removeClass": "old-class",
"toggleClass": "active",
"attributes": {
"data-id": "123",
"title": "My title"
},
"removeAttributes": ["disabled", "readonly"],
"style": {
"color": "red",
"backgroundColor": "#f0f0f0"
},
"append": "<div>Append this</div>",
"prepend": "<div>Prepend this</div>",
"before": "<div>Insert before</div>",
"after": "<div>Insert after</div>"
}
}
Multiple Elements
{
"elements": [
{
"selector": "#element1",
"innerHTML": "Content 1",
"addClass": "active"
},
{
"selector": "#element2",
"innerHTML": "Content 2",
"addClass": "highlight"
}
]
}
Available Properties
| Property | Type | Description |
|---|---|---|
selector |
string | CSS selector (required) |
action |
string | show, hide, remove, toggle |
innerHTML |
string | Set HTML content |
innerText |
string | Set text content (escapes HTML) |
value |
string | Set input value |
addClass |
string/array | Add CSS classes |
removeClass |
string/array | Remove CSS classes |
toggleClass |
string/array | Toggle CSS classes |
attributes |
object | Set attributes |
removeAttributes |
array | Remove attributes |
style |
object | Set inline styles |
append |
string | Append HTML at end |
prepend |
string | Prepend HTML at start |
before |
string | Insert HTML before element |
after |
string | Insert HTML after element |
Response::json([
'element' => [
'selector' => '#productCard',
'innerHTML' => '<h3>Product Name</h3><p>$99.99</p>',
'addClass' => 'featured highlight',
'removeClass' => 'out-of-stock',
'attributes' => [
'data-product-id' => '12345',
'data-price' => '99.99'
],
'style' => [
'border' => '2px solid gold'
]
]
]);
5. Scroll Actions
Control page scrolling to top or specific elements.
Scroll to Top
{
"scroll": {
"to": "top", // scroll to top
"behavior": "smooth" // smooth or auto
}
}
Scroll to Element
{
"scroll": {
"selector": "#targetElement",
"behavior": "smooth", // smooth or auto
"block": "center" // start, center, end, nearest
}
}
Response::json([
'scroll' => [
'selector' => '#errorSection',
'behavior' => 'smooth',
'block' => 'start'
]
]);
6. JavaScript Hooks
Execute custom JavaScript functions registered with registerHook() directly from server responses.
Single Hook
{
"hook": {
"name": "my_custom_hook",
"args": ["arg1", "arg2", "arg3"],
"debug": true // Optional: log to console
}
}
Multiple Hooks
{
"hooks": [
{
"name": "hook_one",
"args": ["data"]
},
{
"name": "hook_two",
"args": [123, "test"]
}
]
}
Registering Hooks (JavaScript)
// Register a hook in your JavaScript
registerHook('my_custom_hook', function(arg1, arg2, arg3) {
console.log('Hook called with:', arg1, arg2, arg3);
// Your custom logic here
return 'result';
});
Hook Chaining
Multiple callbacks can be registered for the same hook name. They execute in order, with each receiving the result of the previous one.
registerHook('process_data', function(data) {
data.step1 = true;
return data;
});
registerHook('process_data', function(data) {
data.step2 = true;
return data;
});
Response::json([
'hook' => [
'name' => 'update_dashboard',
'args' => [
['users' => 150, 'posts' => 523, 'comments' => 1247]
]
],
'toast' => [
'message' => 'Dashboard updated',
'type' => 'success'
]
]);
Other Actions
Reload list (Table, list, calendar)
{
"list": {
"id": "myListId",
"action": "reload"
}
}
Redirect
Optional delay in milliseconds with redirect_delay.
{
"redirect": "/path/to/page",
"redirect_delay": 1500
}
Window Reload
Reload the current page after a delay in milliseconds.
{
"window_reload": 1000
}
HTML Replacement
Note: Replaces the container that initiated the request.
{
"html": "<div>New HTML</div>"
}
Offcanvas
{
"offcanvas_end": {
"size": "xl", // 'xl', 'l', or default
"action": "show",
"title": "Edit Item",
"body": "<form>...</form>"
}
}
Combined Example
Execute multiple actions in a single response:
Response::json([
'success' => true,
// Update multiple elements
'elements' => [
[
'selector' => '#counter',
'innerHTML' => '<strong>5</strong>'
],
[
'selector' => '#status',
'addClass' => 'badge-success',
'removeClass' => 'badge-warning'
]
],
// Show modal
'modal' => [
'size' => 'lg',
'title' => 'Operation Complete',
'body' => '<p>All items have been processed.</p>',
'footer' => '<button class="btn btn-primary" data-bs-dismiss="modal">OK</button>'
],
// Show toast
'toast' => [
'message' => 'Successfully updated!',
'type' => 'success'
],
// Scroll to top
'scroll' => [
'to' => 'top'
],
// Reload table
'table' => [
'id' => 'dataTable',
'action' => 'reload'
]
]);
Integration
Manual Fetch Call
fetch('?page=myModule&action=myAction')
.then(response => response.json())
.then(data => {
jsonAction(data); // Process MilkActions response
});
With FormData
const formData = new FormData(myForm);
fetch('?page=myModule&action=submit', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
jsonAction(data);
});
Best Practices
-
1. Always set success: Include
"success": trueor"success": falsein responses - 2. User feedback: Always provide toast notification for user actions
- 3. Combine actions: Use multiple actions in one response when appropriate
-
4. Error handling: Return
"success": falsewith appropriate error messages - 5. Validate selectors: Ensure DOM selectors exist before referencing them
Error Handling Pattern
try {
// Your operation
Response::json([
'success' => true,
'toast' => ['message' => 'Success!', 'type' => 'success']
]);
} catch (Exception $e) {
Response::json([
'success' => false,
'toast' => ['message' => $e->getMessage(), 'type' => 'danger']
]);
}
Architecture
Files
ajax-handler.js- ContainsjsonAction()andmilkActionsProcessElement()functionstheme.js- ContainsModal,Toasts,Offcanvas_endclassesMilkActionsModule.php- Test module with examplestest_page.php- Interactive test interface
Key Functions
jsonAction(data, container)- Main processor for MilkActions responsesmilkActionsProcessElement(elementData)- Process single element manipulationwindow.modal- Global Modal instancewindow.toasts- Global Toasts instancewindow.offcanvasEnd- Global Offcanvas instance
Quick Reference
| Action | Purpose | Example Keys |
|---|---|---|
modal |
Control modal dialogs | modal.title, modal.body, modal.action |
offcanvas_end |
Control offcanvas panel | offcanvas_end.action, offcanvas_end.size |
toast |
Show notifications | toast.message, toast.type |
form |
Manage forms | form.action, form.fields, form.errors |
element |
Single element manipulation | element.selector, element.innerHTML |
elements |
Multiple elements | Array of element objects |
scroll |
Control scrolling | scroll.to, scroll.selector |
table |
Table operations | table.id, table.action |
hook |
Call JavaScript hook | hook.name, hook.args |
hooks |
Call multiple hooks | Array of hook objects |
redirect |
Navigate to page | redirect, redirect_delay |
window_reload |
Reload current page | Delay in milliseconds |
html |
Replace container | HTML string |
Testing
Open MilkActions Test Page
The test page includes interactive examples for:
- All modal sizes and states
- Toast notifications (success, error, warning, info)
- Form management
- Element manipulation
- Scroll actions
- JavaScript hooks
- Combined operations
Browser Compatibility
MilkActions uses modern JavaScript features:
- Fetch API
- Promises
- ES6 Classes
- Template Literals
Supported browsers:
- Chrome 60+
- Firefox 55+
- Safari 11+
- Edge 79+
Version: 1.0.0
Last Updated: 2025-01-22