feat: Add user profile update diagrams and enhance user registration flow

- Implemented Activity Diagram for User Profile Update
- Created Sequence Diagram for User Profile Update
- Added Use Case Diagram for User interactions
- Developed Class Diagram for User, Group, and Permission entities
- Added Activity and Flowchart Diagrams for User Login and Logout processes
- Created Sequence Diagram for User Login and Logout
- Implemented Activity, Flowchart, and Sequence Diagrams for User Registration process
- Added Email Verification Activity and Flowchart Diagrams
- Developed Sequence Diagram for Email Verification and Password Setup
- Created Activity and Flowchart Diagrams for Set Password process
- Enhanced JavaScript functionality for handling checkbox data in DataTables
1 parent 54771655
@startuml
title User Profile Update Activity Diagram
start
:User navigates to the "Edit Profile" page;
:User modifies their profile information;
:User enters their current password for verification;
:User submits the form;
if (Is the current password correct?) then (yes)
if (Is the new profile data valid?) then (yes)
:System checks if a 'partner' record exists for the user's email;
if (Record exists?) then (yes)
:Update the existing partner record in the database;
else (no)
:Insert a new partner record into the database;
endif
:Display "Profile updated successfully" message;
stop
else (no)
:Display validation errors for the profile data;
--> User modifies their profile information;
endif
else (no)
:Display "Incorrect password" error message;
--> User modifies their profile information;
endif
@enduml
@startuml
title User Profile Update Sequence Diagram
actor User
participant "Web Browser" as Browser
participant "Web Server" as Server
database "Database" as DB
User -> Browser : Edits profile information, enters current password, and submits form
Browser -> Server : POST /profile/update (profile data, password)
activate Server
Server -> DB : Verify current password for user
activate DB
DB --> Server : Password is correct (or not)
deactivate DB
alt Password is correct
Server -> Server : Validate incoming profile data
alt Data is valid
Server -> DB : SELECT * FROM partner WHERE email = ?
activate DB
DB --> Server : Partner record (or null)
deactivate DB
alt Partner record exists
Server -> DB : UPDATE partner SET ... WHERE email = ?
activate DB
DB --> Server : Confirmation
deactivate DB
else Partner record does not exist
Server -> DB : INSERT INTO partner (email, ...) VALUES (...)
activate DB
DB --> Server : Confirmation
deactivate DB
end
Server --> Browser : HTTP 200 OK (Profile updated successfully)
Browser -> User : Displays success message
else Data is invalid
Server --> Browser : HTTP 400 Bad Request (Validation errors)
Browser -> User : Displays error messages
end
else Password is incorrect
Server --> Browser : HTTP 401 Unauthorized (Incorrect password)
Browser -> User : Displays "Incorrect password" error
end
deactivate Server
@enduml
@startuml uc_user
left to right direction
actor User
rectangle "User Use Case" {
User -- (Register)
User -- (Login)
User -- (Update Profile)
User -- (Request Password Reset)
User -- (Logout)
User -- (Change Password)
}
@enduml
@startuml
title User, Group, and Permission Class Diagram
class User {
+id: int
+user_name: string
+user_password: string
+email: string
+status: int
+last_login_date: datetime
--
+login()
+logout()
+has_permission(permission_name): bool
}
class Group {
+id: int
+group_name: string
--
+add_user(user: User)
+remove_user(user: User)
+grant_permission(permission: Permission)
+revoke_permission(permission: Permission)
}
class Permission {
+perm_name: string
+description: string
}
' --- Relationships ---
' A User can be a member of multiple Groups.
' A Group can have multiple Users.
User "many" -- "many" Group : (is member of)
' A Group can have multiple Permissions.
' A Permission can be granted to multiple Groups.
Group "many" -- "many" Permission : (has)
@enduml
@startuml
title Login Activity Diagram
start
partition "User" {
:Enter username and password;
:Click login button;
}
partition "System" {
:Validate credentials;
if (Credentials are valid?) then (yes)
:Log in successful;
:Redirect to dashboard;
stop
else (no)
:Display error message;
endif
}
@enduml
@startuml
title Login Flowchart
start
:User navigates to Login Page;
:User enters Username and Password;
:User clicks Login button;
if (Are inputs valid?) then (yes)
:System checks credentials against Database;
if (Are credentials correct?) then (yes)
:Create session;
:Redirect to Dashboard;
stop
else (no)
:Show "Invalid credentials" error;
--> User enters Username and Password;
endif
else (no)
:Show "Input required" error;
--> User enters Username and Password;
endif
@enduml
@startuml
title Login Sequence Diagram
actor User
participant "Web Browser" as Browser
participant "Web Server" as Server
database "Database" as DB
User -> Browser : Enters username and password
Browser -> Server : POST /login (username, password)
activate Server
Server -> DB : SELECT user WHERE username = ? AND password = ?
activate DB
DB --> Server : User record (or null)
deactivate DB
alt Credentials are valid
Server -> Browser : HTTP 200 OK (Login Success)
Browser -> User : Displays success message / redirects
else Credentials are invalid
Server -> Browser : HTTP 401 Unauthorized (Login Failed)
Browser -> User : Displays error message
end
deactivate Server
@enduml
@startuml
title Logout Activity Diagram
start
:User clicks the logout button;
:System prompts for logout confirmation;
if (User confirms logout?) then (yes)
:Proceed with logout;
else (no)
:Cancel logout;
:The user redirected to the dashboard;
stop
endif
:The system terminates the user's session;
:The user is redirected to the login page;
stop
@enduml
@startuml
title Logout Flowchart
start
:User clicks Logout button;
:System displays confirmation prompt;
if (User confirms logout?) then (yes)
:Proceed with logout;
:System destroys the session;
:Redirect to Login Page;
else (no)
:Cancel logout;
:Redirect to Dashboard;
endif
stop
@enduml
@startuml
title Logout Sequence Diagram
actor User
participant "Web Browser" as Browser
participant "Web Server" as Server
User -> Browser : Clicks "Logout"
Browser -> Server : GET /logout
Server -> Browser : HTTP 200 OK (Logout Confirmation)
Browser -> User : Displays Logout Confirmation Page
User -> Browser : Clicks "Confirm Logout"
Browser -> Server : POST /logout/confirm
activate Server
Server -> Server : Invalidate user session
Server -> Browser : HTTP 302 Found (Redirect to /login)
deactivate Server
Browser -> User : Displays Login Page
@enduml
@startuml
title User Registration Activity Diagram
start
:User navigates to Registration Page;
:User fills in registration form (e.g., username, email, password);
:User submits the form;
if (Input validation fails?) then (yes)
:Display validation errors;
--> User fills in registration form;
else (no)
:Check if user already exists in Database;
if (User exists?) then (yes)
:Display "User already exists" error;
--> User fills in registration form;
else (no)
:Create new user record in the Database;
:Display registration success message;
:Sent confirmation email;
:Receive confirmation link click;
:Activate user account;
:Redirect to Password Setup Page;
:User fill password;
:Submit form;
:Validate password strength;
if (Password valid?) then (no)
:Display password error message;
--> User fill password;
else (yes)
:Update user record with password;
:Display password setup success message;
stop
endif
endif
@enduml
@startuml
title User Registration Flowchart
start
:User navigates to the registration page;
:User fills out the registration form with details like username and email;
:User clicks the 'Register' button;
if (Are all required fields filled correctly?) then (yes)
:System checks if the username or email already exists in the database;
if (Does the user already exist?) then (yes)
:Display an error message: "User already exists.";
--> User fills out the registration form;
else (no)
:System saves the new user's information to the database (status: unverified);
:System sends a verification email to the user;
:Display a success message: "Registration successful! Please check your email to verify your account.";
stop
endif
else (no)
:Display an error message indicating which fields are invalid;
--> User fills out the registration form;
endif
@enduml
@startuml
title User Registration Sequence Diagram
actor User
participant "Web Browser" as Browser
participant "Web Server" as Server
database "Database" as DB
participant "Email Service" as Email
User -> Browser : Fills out registration form (username, email)
Browser -> Server : POST /register (username, email)
activate Server
Server -> Server : Validate input data
alt Input is invalid
Server --> Browser : HTTP 400 Bad Request (Validation errors)
Browser -> User : Displays validation errors
else Input is valid
Server -> DB : SELECT user WHERE username = ? OR email = ?
activate DB
DB --> Server : (null)
deactivate DB
alt User does not exist
Server -> DB : INSERT into users (username, email, status: unverified)
activate DB
DB --> Server : New user record
deactivate DB
Server -> Email : Send verification email
Server --> Browser : HTTP 201 Created (Registration successful)
Browser -> User : Displays "Please check your email to verify your account."
else User already exists
Server --> Browser : HTTP 409 Conflict (User already exists)
Browser -> User : Displays "User already exists" error
end
end
deactivate Server
@enduml
@startuml
title Email Verification Activity Diagram
start
:User clicks the verification link sent to their email;
:System receives the verification request with a unique token;
if (Is the token valid and not expired?) then (yes)
:System marks the user's email as verified in the database;
:Display a success message: "Your email has been verified!";
:Redirect the user to the "Set Password" page;
stop
else (no)
:Display an error message: "Invalid or expired verification link.";
stop
endif
@enduml
@startuml
title Email Verification Flowchart
start
:User clicks the verification link in their email;
:System receives the request with a verification token;
if (Is the token valid and not expired?) then (yes)
:System updates the user's account status to 'verified' in the database;
:Display a success message: "Your email has been verified successfully!";
:Redirect the user to the "Set Password" page;
stop
else (no)
:Display an error message: "Invalid or expired verification link.";
stop
endif
@enduml
@startuml
title Email Verification and Password Setup Sequence Diagram
actor User
participant "Web Browser" as Browser
participant "Web Server" as Server
database "Database" as DB
User -> Browser : Clicks verification link from email
Browser -> Server : GET /verify?token=...
activate Server
Server -> DB : Find user by verification token
activate DB
DB --> Server : User record (or null)
deactivate DB
alt Token is valid and user found
Server --> Browser : HTTP 302 Found (Redirect to /set-password)
deactivate Server
Browser -> User : Displays "Set Password" page
User -> Browser : Enters and confirms new password
Browser -> Server : POST /set-password (password, token)
activate Server
Server -> Server : Validate password complexity and match
alt Password is valid and matches
Server -> DB : Update user's password (hashed)
activate DB
DB --> Server : Confirmation
deactivate DB
Server --> Browser : HTTP 200 OK (Password set)
Browser -> User : Displays "Password set successfully" / Redirects to login
else Password is not valid or does not match
Server --> Browser : HTTP 400 Bad Request (e.g., "Password does not meet requirements")
Browser -> User : Displays error message
end
else Token is invalid or expired
Server --> Browser : HTTP 400 Bad Request (Invalid token)
Browser -> User : Displays error message
end
deactivate Server
@enduml
@startuml
title Set Password Activity Diagram
start
:User is on the "Set Password" page after email verification;
:User enters a new password and confirms it;
:User submits the form;
if (Do the passwords match and meet complexity requirements?) then (yes)
:System saves the new, hashed password to the user's account;
:Display a success message: "Password successfully set!";
:Redirect user to the login page;
stop
else (no)
:Display an error message (e.g., "Passwords do not match or are not strong enough");
--> User enters a new password and confirms it;
endif
@enduml
@startuml
title Set Password Flowchart
start
:User is redirected to the "Set Password" page;
:User enters a new password and confirms it;
:User clicks the 'Set Password' button;
if (Do the passwords match and meet complexity requirements?) then (yes)
:System securely hashes the password;
:System saves the hashed password to the user's record in the database;
:Display a success message: "Your password has been set successfully!";
:Redirect the user to the login page;
stop
else (no)
:Display an error message (e.g., "Passwords do not match" or "Password does not meet requirements");
--> User enters a new password and confirms it;
endif
@enduml
@startuml
title Set Password Sequence Diagram
actor User
participant "Web Browser" as Browser
participant "Web Server" as Server
database "Database" as DB
User -> Browser : Enters and confirms new password on "Set Password" page
Browser -> Server : POST /set-password (password, confirmation, token)
activate Server
Server -> Server : Validate password (e.g., complexity, match)
alt Password is valid and matches
Server -> DB : Update user's password (hashed) using token
activate DB
DB --> Server : Confirmation
deactivate DB
Server --> Browser : HTTP 200 OK (Password set)
Browser -> User : Displays "Password set successfully" / Redirects to login
else Password is not valid or does not match
Server --> Browser : HTTP 400 Bad Request (e.g., "Passwords do not match or meet requirements")
Browser -> User : Displays error message
end
deactivate Server
@enduml
@startuml uc_user
left to right direction
actor User
rectangle "User Use Case" {
User -- (Register)
User -- (Login)
User -- (Request Password Reset)
User -- (Update Profile)
User -- (Logout)
User -- (Change Password)
(Update Profile)..> (Login):include
(Logout)..> (Login):include
(Change Password)..> (Login):include
}
@enduml
@startuml uc_admin
left to right direction
actor Admin
rectangle "User Management Use Case" {
note "All use cases except Login require Admin permission" as N
usecase (Create User) as UC_CreateUser
usecase (Manage Users) as UC_ManageUsers
usecase (Assign Group) as UC_AssignGroup
usecase (Delete User) as UC_DeleteUser
usecase (Create Group) as UC_CreateGroup
usecase (Manage Group Members) as UC_ManageGroupMembers
usecase (Assign Roles) as UC_AssignRoles
usecase (Delete Group) as UC_DeleteGroup
usecase (Login) as UC_Login
Admin -- UC_CreateUser
Admin -- UC_ManageUsers
Admin -- UC_AssignGroup
Admin -- UC_DeleteUser
Admin -- UC_CreateGroup
Admin -- UC_ManageGroupMembers
Admin -- UC_AssignRoles
Admin -- UC_DeleteGroup
UC_CreateUser ..> UC_Login : includes
UC_ManageUsers ..> UC_Login : includes
UC_AssignGroup ..> UC_Login : includes
UC_DeleteUser ..> UC_Login : includes
UC_CreateGroup ..> UC_Login : includes
UC_ManageGroupMembers ..> UC_Login: includes
UC_AssignRoles ..> UC_Login: includes
UC_DeleteGroup ..> UC_Login : includes
}
@enduml
// deform.addCallback('${tableid}', function (oid) {
var m${tableid}ID;
var o${tableid};
var o${tableid}Uri = "${url}";
var o${tableid}Url = o${tableid}Uri + "${url_suffix}";
var m${tableid}ID;
var m${tableid}CheckList = [];
var check_field = ${check_field};
// Function to add data to checkbox list programmatically
function add${tableid} ToList(ids, updateCheckboxes) {
if (!Array.isArray(ids)) {
ids = [ids];
}
ids.forEach(function (id) {
if (m${tableid}CheckList.indexOf(id) === -1) {
m${tableid}CheckList.push(id);
}
if (updateCheckboxes) {
$("#${tableid}_check_" + id).prop("checked", true);
}
});
if (updateCheckboxes && typeof updateCheckAllStatus === 'function') {
updateCheckAllStatus();
}
console.log("Added to ${tableid} list:", ids, "Current list:", m${tableid}CheckList);
}
// Function to remove data from checkbox list programmatically
function remove${tableid}FromList(ids, updateCheckboxes) {
if (!Array.isArray(ids)) {
ids = [ids];
}
ids.forEach(function (id) {
var index = m${tableid}CheckList.indexOf(id);
if (index > -1) {
m${tableid}CheckList.splice(index, 1);
}
if (updateCheckboxes) {
$("#${tableid}_check_" + id).prop("checked", false);
}
});
if (updateCheckboxes && typeof updateCheckAllStatus === 'function') {
updateCheckAllStatus();
}
console.log("Removed from ${tableid} list:", ids, "Current list:", m${tableid}CheckList);
}
// Make functions globally accessible
window['add${tableid}ToList'] = add${tableid}ToList;
window['remove${tableid}FromList'] = remove${tableid}FromList;
function displayEmptyID() {
$("#emptyID").show();
$('#emptyID').animate({opacity: 0.8}, 2000);
setTimeout(function () {
$("#emptyID").fadeTo(500, 0).slideUp(500, function () {
$("#emptyID").hide();
});
}, 4000);
}
let tb_array = [
'<div class="btn-group pull-left">',
'${structure:buttons}',
' &nbsp;',
'</div>',
]
let ${tableid}Language = {
"search": "Cari: ",
"paginate": {
"first": '<span class="glyphicon glyphicon-step-backward"></span> ',
"last": '<span class="glyphicon glyphicon glyphicon-step-forward"></span> ',
"previous": '<span class="glyphicon glyphicon-backward"></span> ',
"next": '<span class="glyphicon glyphicon-forward"></span> ',
},
"infoEmpty": "Menampilkan 0 sampai 0 dari 0",
"info": "Menampilkan _START_ sampai _END_ dari _TOTAL_",
"infoFiltered": "(disaring dari _MAX_ total keseluruhan)",
"lengthMenu": " _MENU_ baris ",
"loadingRecords": "Sedang memuat...",
"processing": "Sedang memproses...",
"emptyTable": "Tidak ada data yang tersedia pada tabel ini",
"zeroRecords": "Tidak ditemukan data yang sesuai",
};
let ${tableid}Columns = ${structure: columns};
function render_checkbox(value) {
if (value === true)
return '<i class="fas fa-check-square" aria-hidden="true">';
if (value === false)
return '<i class="fas fa-minus-square" aria-hidden="true">';
return value;
}
function render_checklist(value) {
return '<input type="checkbox" class="${tableid}_check" checked="' + {value} + '"></input>';
}
//var mtableId = "${tableid}";
for (let co in ${tableid}Columns) {
if (${tableid}Columns[co].wg_checkbox === true) {
${tableid}Columns[co].render = function (value) {
if (typeof value === "string" && value.length > 0) {
return render_checkbox(value)
}
if (["", false, 0, null].indexOf(value) === -1) {
return render_checkbox(true);
}
return render_checkbox(false);
}
}
else if (${tableid}Columns[co].wg_select === true) {
${tableid}Columns[co].render = function (value) {
if (value != null)
return ${tableid}Columns[co].wg_select_val[value];
return "";
}
}else if (${tableid}Columns[co].hasOwnProperty("url")) {
let url = ${tableid}Columns[co].url;
${tableid}Columns[co].render = function (data) {
let result = "No Data";
if (data != null) {
result = '<a href="' + url + data + '" target="_blank">Link</a>&nbsp;';
}
return result;
}
}else if (${tableid}Columns[co].data === "id") {
${tableid}Columns[co].render = function (id, typ, data, setting) {
if (${tableid}Columns[co].action === false) return ""
let result = "";
<tal:block tal:condition="allow_check=='true'">
var checked = "";
if (check_field !== "") {
checked = data[check_field] !== null ? "checked" : "";
if (checked === "checked" && m${tableid}CheckList.indexOf(id) === -1) {
m${tableid}CheckList.push(id);
}
}
result = '<input type="checkbox" class="${tableid}_check" id="${tableid}_check_' + id +'"
value="' + id + '" ' + checked + ' name="${tableid}_check" />&nbsp;';
</tal:block>
<tal:block tal:condition="allow_check=='false'">
<tal:block tal:condition="allow_view=='true'">
result += '<a href="${url}/' + id + '/view"><i class="fas fa-eye" aria-hidden="true"
title="View"></i></a>&nbsp;';
</tal:block>
<tal:block tal:condition="allow_edit=='true'">
result += '<a href="${url}/' + id + '/edit"><i class="fas fa-edit" aria-hidden="true"
title="Edit"></i></a>&nbsp;'
</tal:block>
<tal:block tal:condition="allow_delete=='true'">
result += '<a href="${url}/' + id + '/delete"><i class="fas fa-trash" aria-hidden="true"
title="Delete"></i></a>';
</tal:block>
<tal:block tal:condition="allow_post=='true'">
result += '<a href="${url}/' + id + '/post"><i class="fas fa-signs-post" aria-hidden="true"
title="Post"></i></a>';
</tal:block>
<tal:block tal:condition="allow_post=='true'">
result += '<a href="${url}/' + id + '/unpost"><i class="fas fa-delete-left" aria-hidden="true"
title="Unpost"></i></a>';
</tal:block>
</tal:block>
return result;
}
}
}
//end column definition loop
let ${tableid}Params = {};
var param_ajax = "";
var param_data = [];
if (!${server_side}) param_data = ${data};
else param_ajax = o${tableid} Url;
o${tableid}= $('#${tableid}').DataTable({
scrollX: ${field.scroll_x},
//scrollY: ${field.scroll_y},
//dom: '<"row"<"col-md-8"<"toolbar">Bl><"col-md-4"fr>>tip',
dom: '<"row"<"col-md-8"<"toolbar">>><"row"<"col-md-8"Bl><"col-md-4"fr>>t<"row dt-footer"<"col-md-8 sub-foot" i>
< "col-md-4"p >> ',
processing: true,
serverSide: ${server_side},
data: param_data,
ajax: param_ajax,
stateSave: ${state_save},
scrollCollapse: true,
sort: ${sorts},
info: true,
filter: ${filters},
autoWidth: false,
paginate: ${paginates},
paginationType: "full_numbers",
order: [],
lengthMenu: [
[10, 25, 50, 100],
[10, 25, 50, 100]
],
pageLength: 25,
columns: ${tableid}Columns,
language: ${tableid}Language,
initComplete: function () {
$('.dataTables_filter input').unbind()
.bind('keyup', function (e) {
var code = e.keyCode || e.which;
if (code === 13) {
o${tableid}.search(this.value).draw();
}
});
},
drawCallback: function () {
// Update check all status after table redraw
<tal:block tal:condition="allow_check=='true'">
updateCheckAllStatus();
</tal:block>
}
});
let tb = tb_array.join(' ');
$("div.toolbar").html(tb);
$("div.toolbar").attr('style', 'display:block; float: left; margin-bottom:6px; line-height:16px;');
$("div.dt-footer").attr('style', 'margin-left: -7px;');
$("div.sub-foot").attr('style', 'position:unset;');
$(".dataTables_scrollBody").attr('style', 'margin-top: -10px;');
<tal:block tal:condition="allow_check=='true'">
//Begin Allow Check
$('#${tableid} tbody').on('click', ':checkbox', function () {
var checkboxValue = $(this).val();
if (this.checked) {
// Add to list if not already present
if (m${tableid}CheckList.indexOf(checkboxValue) === -1) {
m${tableid}CheckList.push(checkboxValue);
}
}else {
// Remove from list
var index = m${tableid}CheckList.indexOf(checkboxValue);
if (index > -1) {
m${tableid}CheckList.splice(index, 1);
}
}
console.log("Checkbox Clicked", m${tableid}CheckList);
updateCheckAllStatus();
});
$('#${tableid} tbody').on('change', ':checkbox', function () {
var checkboxValue = $(this).val();
if (this.checked) {
// Add to list if not already present
if (m${tableid}CheckList.indexOf(checkboxValue) === -1) {
m${tableid}CheckList.push(checkboxValue);
}
}else {
// Remove from list
var index = m${tableid}CheckList.indexOf(checkboxValue);
if (index > -1) {
m${tableid}CheckList.splice(index, 1);
}
}
console.log("Checkbox Changed", m${tableid}CheckList);
updateCheckAllStatus();
});
$("#${tableid}checkAll").on("click", '', function (e) {
e.stopPropagation();
if (this.checked) {
// Check all checkboxes and add all to list
$(".${tableid}_check").each(function () {
$(this).prop("checked", true);
var checkboxValue = $(this).val();
if (m${tableid} CheckList.indexOf(checkboxValue) === -1) {
m${tableid}CheckList.push(checkboxValue);
}
});
}else {
// Uncheck all checkboxes and clear list
$(".${tableid}_check").prop("checked", false);
m${tableid}CheckList = [];
}
console.log("Check All Clicked", m${tableid}CheckList);
});
// Function to update check all status based on individual checkboxes
function updateCheckAllStatus() {
var totalCheckboxes = $(".${tableid}_check").length;
var checkedCheckboxes = $(".${tableid}_check:checked").length;
if (checkedCheckboxes === 0) {
$("#${tableid}checkAll").prop("checked", false);
$("#${tableid}checkAll").prop("indeterminate", false);
}else if (checkedCheckboxes === totalCheckboxes) {
$("#${tableid}checkAll").prop("checked", true);
$("#${tableid}checkAll").prop("indeterminate", false);
}else {
$("#${tableid}checkAll").prop("checked", false);
$("#${tableid}checkAll").prop("indeterminate", true);
}
};
// Function to get selected data from checked rows
function get${tableid}SelectedData() {
var selectedData = [];
$(".${tableid}_check:checked").each(function() {
var rowData = o${tableid}.row($(this).closest('tr')).data();
if (rowData) {
selectedData.push(rowData);
}
});
return selectedData;
};
// Function to get selected IDs
function get${tableid}SelectedIds() {
return m${tableid}CheckList.slice(); // Return copy of the array
};
// Make functions globally accessible
window['get${detable}SelectedData'] = get${tableid}SelectedData;
window['get${tableid}SelectedIds'] = get${tableid}SelectedIds;
//${tableid}.ajax.reload(function() {
$("#${tableid}_delete").type == 'button';
$("#${tableid}_delete").on("click", function () {
console.log("Delete Clicked", m${tableid}CheckList);
});
//End Allow Check
</tal:block>
$('#${tableid} tbody').on('click', 'tr', function () {
if ($(this).hasClass('selected')) {
$(this).removeClass('selected');
m${tableid} ID = null;
} else {
let aData = o${tableid}.row(this).data();
o${tableid}.$('tr.selected').removeClass('selected');
$(this).addClass('selected');
m${tableid} ID = aData.id;
o${tableid}.$('tr.row_selected').removeClass('row_selected');
$(this).addClass('row_selected');
}
});
<tal:block tal:condition="filter_columns">
$(".${tableid}-control-filter").on('keyup', function (e) {
var code = e.keyCode || e.which;
if (code === 13) filter_table();
});
$("#${tableid}_length").append('<label>&emsp;${structure:edit_buttons}</label>');
function filter_table() {
$(".${tableid}-control-filter").each(function (e) {
var col_id = $(this).attr("id");
var value;
if ($(this).attr("type") === 'radio') {
col_id = $(this).attr('id').split("-");
col_id.length = 2;
col_id = col_id.join("-");
value = this.value;
if (this.checked) {
//console.log(col_id, $(this).attr('id'), value, this.checked);
localStorage.setItem(col_id, value);
o${tableid}.column($(this).data('index')).search(this.value)
}
}
else if ($(this).attr("type") === 'date') {
value = this.value;
localStorage.setItem(col_id, value);
var splitted = col_id.split('-');
if (splitted[splitted.length - 1] !== "min" && splitted[splitted.length - 1] !== "max"){
o${tableid}.column($(this).data('index')).search(value)
}
else{
var min_val = undefined;
var max_val = undefined;
if (splitted[splitted.length - 1] === "min") {
min_val = this.value;
splitted.length = splitted.length - 1;
col_id = splitted.join("-");
max_val = $("#" + col_id + '-max').val()
}
else {
max_val = this.value;
splitted.length = splitted.length - 1;
col_id = splitted.join("-");
min_val = $("#" + col_id + '-min').val();
}
if (min_val === undefined && max_val !== undefined) min_val = max_val;
if (max_val === undefined && min_val !== undefined) max_val = min_val;
if (max_val !== undefined && min_val !== undefined && min_val !== null && max_val !== null)
o${tableid}
.column($(this).data('index'))
.search(min_val + '-yadcf_delim-' + max_val, true);
//&& min_val !== "" && max_val !== ""
}
}
else {
col_id = this.id;
value = this.value;
if (value === undefined || value === null) value = "";
console.log(col_id, $(this).attr('id'), value, $(this).data('index'));
localStorage.setItem(col_id, value);
o${tableid}
.column($(this).data('index'))
.search(value);
}
});
o${tableid}.draw();
}
$(".${tableid}-control-filter").on('click', function (e) {
//console.log("Write Data Click");
var typ = $(this).attr("type");
if (typ === 'radio') {
filter_table();
}
});
$(".${tableid}-control-filter").on('change', function (e) {
var typ = $(this).prop("nodeName").toLowerCase();
if (typ === "select") filter_table();
var typ = $(this).attr("type").toLowerCase();
if (typ === "date") filter_table();
});
console.log("Read Data");
$(".${tableid}-control-filter").each(function (e) {
var col_id = $(this).attr("id")
var value;
if ($(this).attr("type") === 'radio') {
col_id = $(this).attr('id').split("-");
col_id.length = 2;
col_id = col_id.join("-");
value = localStorage.getItem(col_id);
if (value !== undefined && value != null)
if ($(this).val() === value) $(this).attr("checked", true);
else $(this).attr("checked", false);
}
else {
value = localStorage.getItem(col_id);
if (value !== undefined && value !== null)
$(this).val(value);
}
});
filter_table();
</tal:block>
${structure: btnscripts}
${structure: filter_scripts}
});
});
I'll help you add datatable functionality for handling checkbox data. Let me first examine the current template file to understand the existing structure.
detable.pt
Let me see more of the file to understand the complete structure, especially the JavaScript part:
detable.pt
Let me continue reading to see the rest of the JavaScript implementation:
detable.pt
Let me see the rest of the file to understand the complete implementation:
detable.pt
Now I understand the structure.I can see that there's already functionality for checkboxes and handling selected items in the datatable, but it looks like there might need to be some improvements to the "adddata to list from checkbox after prop" functionality.
Based on the code, I can see:
There's a checkbox implementation for each row (${tableid}_check)
There's a "check all" functionality (${tableid}checkAll)
There's a list to track checked items (m${tableid}CheckList)
There's some commented code for delete multiple functionality
Let me enhance the checkbox functionality to properly add data to list from checkboxes.I'll need to fix some issues I notice:
Edited
detable.pt + 138 - 11
I've successfully enhanced the datatable checkbox functionality with the following improvements:
Key Enhancements Made:
1. Improved Checkbox List Management
Fixed duplicate entries in the checkbox list
Proper add / remove logic for checkbox state changes
Prevention of duplicate IDs in the selection list
2. Enhanced Check All Functionality
Properly manages all checkboxes when "Check All" is clicked
Supports indeterminate state for partial selections
Updates the list correctly when checking / unchecking all items
3. Added Utility Functions
get[TableId]SelectedData() - Returns full row data for selected items
get[TableId]SelectedIds() - Returns array of selected IDs
add[TableId]ToList(ids, updateCheckboxes) - Programmatically add items to selection
remove[TableId]FromList(ids, updateCheckboxes) - Programmatically remove items from selection
4. Improved State Management
Added updateCheckAllStatus() function to maintain consistency between individual checkboxes and "check all"
Added drawCallback to update checkbox states after table redraws
Fixed initialization of pre - checked items based on check_field
5. Better Event Handling
Prevents duplicate event handling
Proper cleanup and state management on checkbox changes
Console logging for debugging purposes
Usage Examples:
// Get selected IDs
var selectedIds = getYourTableIdSelectedIds();
// Get full data of selected rows
var selectedData = getYourTableIdSelectedData();
// Programmatically add items to selection
addYourTableIdToList([1, 2, 3], true); // true = also update checkboxes
// Programmatically remove items from selection
removeYourTableIdFromList([1], true); // true = also update checkboxes
The enhanced functionality now provides robust support for adding data to lists from checkboxes with proper state management and utility functions for programmatic control.
\ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!