Milk Admin
Theme JavaScript
ItoSortableList
const myList = document.getElementById('mylst');
const myPaginator = new ItoSortableList(myList, {
handleSelector: '.drag-handle',
onUpdate: (newOrder) => {
console.log('New order:', newOrder.map(el => el.textContent.trim()));
}
});
Sortable List Example
First element
Second element
Third element
Fetch and Response Management with Permissions
1. Client Side (JavaScript)
The system uses a custom version of fetch that automatically handles JSON responses and permission denied cases through ajax-handler.js.
Fetch Call Example
// Example fetch to save data
fetch(milk_url + '?page=reports&action=json-related-tables-save', {
method: 'POST',
credentials: 'same-origin',
body: formData
}).then(response => response.json())
.then(data => {
// Use the centralized handler to manage permission errors and other responses
if (!window.handleAjaxResponse(data)) {
return; // Stop processing if there's an error or permissions denied
}
// Success handling
if (data.success) {
window.toasts.show('Operation completed successfully', 'success');
}
}).catch(error => {
console.error('Error during fetch:', error);
});
2. Centralized Management (ajax-handler.js)
The ajax-handler.js file overwrites the native fetch function to add automatic permission handling:
// Centralized AJAX response handling in ajax-handler.js
window.handleAjaxResponse = function(response) {
if (!response) return;
if (response.permission_denied === true) {
window.toasts.show(`Permission denied: ${response.msg}`, 'danger');
return false;
}
if (!response.success) {
window.toasts.show(response.msg || 'An error occurred', 'danger');
return false;
}
return true;
};
3. Server Side (PHP)
In the PHP router file (e.g., reports.router.php), permission denied handling is implemented through the json_permission_denied method:
protected function jsonPermissionDenied( $custom_message = ''): void {
http_response_code(403); // Set HTTP 403 Forbidden status code
$message = $custom_message ?: "You don't have permissions for this action";
$response = [
'success' => false,
'msg' => $message,
'permission_denied' => true,
'code' => 403
];
Response::json($response);
exit;
}
4. Controller Usage Example
In the router, when a permission issue occurs in an action:
protected function actionJsonRelatedTablesSave() {
// Permission check
Permissions::checkJson('my_class.edit');
header('Content-Type: application/json');
// Rest of the code to handle the action...
}
5. Complete Flow
- Client makes a fetch request
- PHP router checks permissions
- If permissions are denied,
jsonPermissionDenied()is called - JSON response is intercepted by
ajax-handler.js - An error message is shown to the user via toast
Note: This system ensures uniform permission error handling throughout the application, improving both security and user experience.
Other functions
getFormData(queryString)
Utility function to transform a query string into a FormData object
getComponentname(id)
Return a component name by DOM element Id
getComponent(id)
Find a component by id
toggleEl(el, el_form, compare_value)
Show or hide an element
elHide(el, fn)
Hide an element with fade animation
elShow(el, fn)
Show an element with fade animation
callHook / registerHook
Call or register a hook
removeIsInvalid
Function to remove the error message from a field
__(key, params = {})
Translation function
Loading...