// JQuery Entry $(() => { // Checks if user chose to have dark mode enabled or disabled throughout the website and enables it const checkDarkmode = () => { if (sessionStorage.getItem("darkmode") == 1) { $('body').addClass('darkMode'); $('#employeeList').css('box-shadow', 'none'); $('button.list-group-item').addClass('bg-dark'); $('#heading').css('background-color', 'black'); $('div.h4').css('background-color', 'black'); $('#status').addClass('bg-dark'); $("#logo").attr("src", "img/logolight.png"); $('#lightSwitch').prop('checked', true); } } //Initial check to make page dark before loading list checkDarkmode(); // Retrieves a list of Employees and Departments const getAll = async (msg) => { try { $("#employeeList").text("Finding employee Information..."); // Get Employee data let response = await fetch(`api/employee`); if (response.ok) { // This returns a Promise let payload = await response.json(); buildemployeeList(payload); msg === "" ? $("#status").text("employees Loaded") : $("#status").text(`${msg} - employees Loaded`); } //Probably Client Side Error else if (response.status !== 404) { let problemJson = await response.json(); errorRtn(problemJson, response.status); } //404 Not Found else { $("#status").text("no such path on server"); } // Get Department data response = await fetch(`api/department`); if (response.ok) { // This returns a Promise let divs = await response.json(); sessionStorage.setItem("allDepartments", JSON.stringify(divs)); } //Probably Client Side Error else if (response.status !== 404) { let problemJson = await response.json(); errorRtn(problemJson, response.status); } //404 Not Found else { $("#status").text("no such path on server"); } } catch (error) { $("#status").text(error.message); } }; //Sets up the modal to update a specific employee const setupForUpdate = (id, data) => { //Changes what the buttons and Titles say $("#actionbutton").val("update"); $("#actionbutton").prop("disabled", false); $("#modaltitle").html("<h4>update employee</h4>"); //Clears the Modal from any prior information clearModalFields(); //Finding employee and setting their information inside the text boxes data.forEach(employee => { if (employee.id === parseInt(id)) { $("#TextBoxTitle").val(employee.title); $("#TextBoxFirstname").val(employee.firstname); $("#TextBoxLastname").val(employee.lastname); $("#TextBoxPhone").val(employee.phoneno); $("#TextBoxEmail").val(employee.email); $("#ImageHolder").html(`<img height="120" width="110" src="data:img/png;base64,${employee.staffPicture64}" />`); console.log(employee.staffPicture64); sessionStorage.setItem("id", employee.id); sessionStorage.setItem("departmentId", employee.departmentId); sessionStorage.setItem("timer", employee.timer); sessionStorage.setItem("picture", employee.staffPicture64); //Sets the status $("#modalstatus").text("update data"); $("#myModal").modal("toggle"); $("#myModalLabel").text("Update"); //Hides the delete alert from prior $('#deletealert').hide(); //Shows the delete button $('#deleteprompt').show(); loadDepartmentDDL(employee.departmentId); } }); }; // Setup Modal for Adding an Employee const setupForAdd = () => { //Changes what the buttons and Titles say $("#actionbutton").val("add"); $("#actionbutton").prop("disabled", true); $("#modaltitle").html("<h4>add employee</h4>"); $("#theModal").modal("toggle"); //Sets the status $("#modalstatus").text("add new employee"); $("#myModalLabel").text("Add"); //Hides the delete alert and delete prompt since we don't need them when adding $('#deletealert').hide(); $('#deleteprompt').hide(); //Clears modal fields from prior information clearModalFields(); }; // Clears all Modal Fields and Removes Items from session storage const clearModalFields = () => { loadDepartmentDDL(-1); $("#TextBoxTitle").val(""); $("#TextBoxFirstname").val(""); $("#TextBoxLastname").val(""); $("#TextBoxPhone").val(""); $("#TextBoxEmail").val(""); $("#ImageHolder").html('<img height="1" width="1" src="data:img/png;base64,/>') $("#modalstatus").attr("class", "text-warning"); sessionStorage.removeItem("id"); sessionStorage.removeItem("departmentId"); sessionStorage.removeItem("timer"); sessionStorage.removeItem("picture"); $("#myModal").modal("toggle"); let validator = $("#EmployeeModalForm").validate(); validator.resetForm(); }; //Adds an employee to the DB const add = async () => { try { //Creating employee object and assigning it values from modal fields emp = new Object(); emp.title = $("#TextBoxTitle").val(); emp.firstname = $("#TextBoxFirstname").val(); emp.lastname = $("#TextBoxLastname").val(); emp.phoneno = $("#TextBoxPhone").val(); emp.email = $("#TextBoxEmail").val(); emp.departmentId = parseInt($("#ddlDepartments").val()); emp.id = -1; emp.timer = null; sessionStorage.getItem("picture") ? emp.staffPicture64 = sessionStorage.getItem("picture") : emp.staffPicture64 = null; // Sends employee information to the server asynchronously using POST let response = await fetch("api/employee", { method: "POST", headers: { "Content-Type": "application/json; charset=utf-8" }, body: JSON.stringify(emp) }); //Checks if response status is ok if (response.ok) { let data = await response.json(); getAll(data.msg); } //Probably Client Side Error else if (response.status !== 404) { let problemJson = await response.json(); errorRtn(problemJson, response.status); } //404 Not Found else { $("#status").text("no such path on server"); } } catch (error) { $("#status").text(error.message); } $("#myModal").modal("toggle"); }; // Deletes an Employee from the DB const _delete = async () => { try { let response = await fetch(`api/employee/${sessionStorage.getItem('id')}`, { method: 'DELETE', headers: { 'Content-Type': 'application/json; charset=utf-8' } }); //Checks if response status is ok if (response.ok) { let data = await response.json(); getAll(data.msg); } //Server side problem else { $('#status').text(`Status - ${response.status}, Problem on delete server side, see server console`); } $('#myModal').modal('toggle'); } catch (error) { $('#status').text(error.message); } }; //Updates an Employee in the DB const update = async () => { try { // Creating an Employee object emp = new Object(); // Setting object properties using modal fields values emp.title = $("#TextBoxTitle").val(); emp.firstname = $("#TextBoxFirstname").val(); emp.lastname = $("#TextBoxLastname").val(); emp.phoneno = $("#TextBoxPhone").val(); emp.email = $("#TextBoxEmail").val(); // Setting rest of object properties by retrieving and using items from session storage emp.id = parseInt(sessionStorage.getItem("id")); emp.DepartmentId = parseInt($("#ddlDepartments").val()); emp.timer = sessionStorage.getItem("timer"); sessionStorage.getItem("picture") ? emp.staffPicture64 = sessionStorage.getItem("picture") : emp.staffPicture64 = null; let response = await fetch("api/employee", { method: "PUT", headers: { "Content-Type": "application/json; charset=utf-8" }, body: JSON.stringify(emp) }); //Checks if response status is ok if (response.ok) { let data = await response.json(); getAll(data.msg); } //Probably Client Side Error else if (response.status !== 404) { let problemJson = await response.json(); errorRtn(problemJson, response.status); } //404 Not Found else { $("#status").text("no such path on server"); } } catch (error) { $("#status").text(error.message); } $("#myModal").modal("toggle"); } //Listens for the action button click and determines if it should add or update $("#actionbutton").click(() => { $("#actionbutton").val() === "update" ? update() : add(); }); //Listens for a click on an employee or the add button and calls the appropiate function $("#employeeList").click((e) => { if (!e) e = window.event; let id = e.target.parentNode.id; if (id === "employeeList" || id === "") { id = e.target.id; } // clicked on row somewhere else if (id !== "status" && id !== "heading") { let data = JSON.parse(sessionStorage.getItem("allemployees")); id === "0" ? setupForAdd() : setupForUpdate(id, data); } else { return false; } }); //Builds and displays the employee list const buildemployeeList = (data, usealldata = true) => { $("#employeeList").empty(); //Building the header of the list div = $(`<div class="list-group-item row d-flex" id="status">employee Info</div> <div class= "list-group-item row d-flex text-center" id="heading"> <div class="col-4 h4">Title</div> <div class="col-4 h4">First</div> <div class="col-4 h4">Last</div> </div>`); //Adding header to list div div.appendTo($("#employeeList")); //Adding all employees information to session storage usealldata ? sessionStorage.setItem("allemployees", JSON.stringify(data)) : null; //Creating the add button btn = $(`<button class="list-group-item row d-flex" id="0">...click to add employee</button>`); //Adding the add button to the list div btn.appendTo($("#employeeList")); //Building the button with employee information for each employee and adding them to the list div data.forEach((emp) => { btn = $(`<button class="list-group-item row d-flex" id="${emp.id}">`); btn.html(`<div class="col-4" id="employeetitle${emp.id}">${emp.title}</div> <div class="col-4" id="employeefname${emp.id}">${emp.firstname}</div> <div class="col-4" id="employeelastnam${emp.id}">${emp.lastname}</div>` ); btn.appendTo($("#employeeList")); }); //Checking if dark mode is enabled so we can apply it to the list we built checkDarkmode(); }; getAll(""); // Retrieving data from the server //Listens to click on delete prompt then displays the delete alert $('#deleteprompt').click((e) => { $('#deletealert').show(); }); //Listens to click on the alert no button and hides the alert $('#deletenobutton').click((e) => { $('#deletealert').hide(); }); //Listens to click on the alert yes button and calls the delete function to delete employee $('#deletebutton').click(() => { _delete(); }); //Loading departments and adding them to the dropdown options const loadDepartmentDDL = (empdiv) => { html = ''; $('#ddlDepartments').empty(); let allDepartments = JSON.parse(sessionStorage.getItem('allDepartments')); allDepartments.forEach((div) => { html += `<option value="${div.id}">${div.departmentName}</option>` }); $('#ddlDepartments').append(html); $('#ddlDepartments').val(empdiv); }; //Listens to click on the darkmode button $('#lightSwitch').click(() => { if ($('#lightSwitch').is(':checked') == true) { $('body').addClass('darkMode'); $('#employeeList').css('box-shadow', 'none'); $('button.list-group-item').addClass('bg-dark'); $('#heading').css('background-color', 'black'); $('div.h4').css('background-color', 'black'); $('#status').addClass('bg-dark'); $("#logo").attr("src", "img/logolight.png"); sessionStorage.setItem("darkmode", 1); } else { $('body').removeClass('darkMode'); $('#employeeList').css('box-shadow', ''); $('button.list-group-item').removeClass('bg-dark'); $('#heading').css('background-color', ''); $('div.h4').css('background-color', ''); $('#status').removeClass('bg-dark'); $("#logo").attr("src", "img/logo.png"); sessionStorage.setItem("darkmode", 0); } }); // Listening to keyup input on modal form and validating document.addEventListener("keyup", e => { $("#modalstatus").removeClass(); if ($("#EmployeeModalForm").valid()) { $("#modalstatus").attr("class", "text-success"); $("#modalstatus").text("data entered is valid"); $("#actionbutton").prop("disabled", false); } else { $("#modalstatus").attr("class", "text-danger"); $("#modalstatus").text("fix errors"); $("#actionbutton").prop("disabled", true); } }); // Listening to changes on the ddlDepartments and validating $("#ddlDepartments").change(e => { $("#modalstatus").removeClass(); if ($("#EmployeeModalForm").valid()) { $("#modalstatus").attr("class", "text-success"); $("#modalstatus").text("data entered is valid"); $("#actionbutton").prop("disabled", false); } else { $("#modalstatus").attr("class", "text-danger"); $("#modalstatus").text("fix errors"); $("#actionbutton").prop("disabled", true); } }); //Creating the validation rules and their messages for our modal form $("#EmployeeModalForm").validate({ rules: { TextBoxTitle: { maxlength: 4, required: true, validTitle: true }, TextBoxFirstname: { maxlength: 25, required: true }, TextBoxLastname: { maxlength: 25, required: true }, TextBoxEmail: { maxlength: 40, required: true, email: true }, TextBoxPhone: { maxlength: 15, required: true }, ddlDepartments: { required: true } }, errorElement: "div", messages: { TextBoxTitle: { required: "required 1-4 chars.", maxlength: "required 1-4 chars.", validTitle: "Mr. Ms. Mrs. or Dr." }, TextBoxFirstname: { required: "required 1-25 chars.", maxlength: "required 1-25 chars." }, TextBoxLastname: { required: "required 1-25 chars.", maxlength: "required 1-25 chars." }, TextBoxPhone: { required: "required 1-15 chars.", maxlength: "required 1-15 chars." }, TextBoxEmail: { required: "required 1-40 chars.", maxlength: "required 1-40 chars.", email: "need valid email format" }, ddlDepartments: { required: "select Department" } } }); // Adding a custom validation Rule to check Titles $.validator.addMethod("validTitle", (value) => { return (value === "Mr." || value === "Ms." || value === "Mrs." || value === "Dr."); }, ""); // Reads search input with every key up and filters the data and passes the filtered data to buildemployeeList $("#srch").keyup(() => { let alldata = JSON.parse(sessionStorage.getItem("allemployees")); let filtereddata = alldata.filter((emp) => emp.lastname.match(new RegExp($("#srch").val(), 'i'))); buildemployeeList(filtereddata, false); }); // Reads changes to the file input $("#uploader").change(() => { const reader = new FileReader(); reader.onload = (readerEvt) => { const binaryString = reader.result; const encodedString = btoa(binaryString); sessionStorage.setItem('picture', encodedString); $("#ImageHolder").html(`<img height="120" width="110" src="data:img/png;base64,${encodedString}" />`); }; const file = $("#uploader")[0].files[0]; file ? reader.readAsBinaryString(file) : null; }); }); //Server reached but it had a problem with the call const errorRtn = (problemJson, status) => { if (status > 499) { $("#status").text("Problem server side, see debug console"); } else { let keys = Object.keys(problemJson.errors) problem = { status: status, statusText: problemJson.errors[keys[0]][0], }; $("#status").text("Problem client side, see browser console"); console.log(problem); } }