ASP.NET / ASP.NET Helpdesk System Using jQuery and Bootstrap / CasestudyWebsite / wwwroot / js / call.js
call.js
Raw
// 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');
            $('#callList').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, Problems, and Calls
    const getAll = async (msg) => {
        try {
            $("#callList").text("Finding call Information...");
            // Get Calls data
            let response = await fetch(`api/call`);
            if (response.ok) {
                // This returns a Promise
                let payload = await response.json();
                buildcallList(payload);
                msg === "" ? 
                    $("#status").text("Calls Loaded") : $("#status").text(`${msg} - Calls 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 Problem data
            response = await fetch(`api/problem`);
            if (response.ok) {
                // This returns a Promise
                let divs = await response.json();
                sessionStorage.setItem("allProblems", 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");
            }

            // Get Employee data
            response = await fetch(`api/employee`);
            if (response.ok) {
                // This returns a Promise
                let divs = await response.json();
                sessionStorage.setItem("allEmployees", 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 call
    const setupForUpdate = (id, data) => {
        //Changes what the buttons and Titles say
        $("#actionbutton").val("update");
        $("#actionbutton").prop("disabled", false);
        $("#modaltitle").html("<h4>update call</h4>");
        //Clears the Modal from any prior information
        clearModalFields();
        //Finding call and setting their information inside the text boxes
        data.forEach(call => {
            if (call.id === parseInt(id)) {

                $("#ddlProblems").val(call.problemId);
                $("#ddlEmployees").val(call.employeeId);
                $("#ddlTechnicians").val(call.techId);
                $("#TextAreaNote").val(call.notes);
                sessionStorage.setItem("dateOpened", formatDate(call.dateOpened));
                $("#dateOpenedText").text(formatDate(call.dateOpened).replace("T", " "));
                sessionStorage.setItem("id", call.id);
                sessionStorage.setItem("timer", call.timer);
                //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();
                //Shows the checkbox to close calls and that date it was closed
                $('#CheckBoxCloseCallDiv').show();
                $('#dateClosedDiv').show();

                //Checks if call is marked as closed and disables inputs for user if true

                if (!call.openStatus) {
                    $('#CheckBoxCloseCall').prop('checked', true);
                    $('#TextAreaNote').attr('readonly', true);
                    $('#ddlProblems').attr('disabled', true);
                    $('#ddlEmployees').attr('disabled', true);
                    $('#ddlTechnicians').attr('disabled', true);
                    $('#CheckBoxCloseCall').attr('disabled', true);
                    $("#actionbutton").hide();

                    $("#dateClosedText").text(formatDate(call.dateClosed).replace("T", " "));
                    sessionStorage.setItem("dateClosed", formatDate(call.dateClosed));

                }

                loadProblemDDL(call.problemId);
                loadEmployeeDDL(call.employeeId);
                loadTechnicianDDL(call.techId);
            }
        });
    };

    // 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 call</h4>");
        $("#theModal").modal("toggle");
        //Sets the status
        $("#modalstatus").text("add new call");
        $("#myModalLabel").text("Add");
        //Hides the delete alert and delete prompt since we don't need them when adding
        $('#deletealert').hide();
        $('#deleteprompt').hide();
        //Hides the date closed and close checkbox
        $('#dateClosedDiv').hide();
        $('#CheckBoxCloseCallDiv').hide();
        //Clears modal fields from prior information
        clearModalFields();
        $("#dateOpenedText").text(formatDate().replace("T", " "));
        sessionStorage.setItem("dateOpened", formatDate());


    };

    // Clears all Modal Fields and Removes Items from session storage
    const clearModalFields = () => {
        loadProblemDDL(-1);
        loadEmployeeDDL(-1);
        loadTechnicianDDL(-1);
        $('#CheckBoxCloseCall').prop('checked', false);
        $("#dateOpenedText").empty();
        $("#dateClosedText").empty();
        $("#TextAreaNote").val("");
        sessionStorage.removeItem("id");
        sessionStorage.removeItem("timer");
        $('#TextAreaNote').attr('readonly', false);
        $('#ddlProblems').attr('disabled', false);
        $('#ddlEmployees').attr('disabled', false);
        $('#ddlTechnicians').attr('disabled', false);
        $('#CheckBoxCloseCall').attr('disabled', false);
        $("#actionbutton").show();
        $("#modalstatus").attr("class", "text-warning");
        $("#myModal").modal("toggle");
        let validator = $("#CallModalForm").validate();
        validator.resetForm();
    };

    //Adds an employee to the DB
    const add = async () => {
        try {
            //Creating employee object and assigning it values from modal fields
            call = new Object();
            call.dateOpened = formatDate();
            call.dateClosed = null;
            call.openStatus = true;
            call.problemId = $("#ddlProblems").val();
            call.employeeId = $("#ddlEmployees").val();
            call.techId = $("#ddlTechnicians").val();
            call.id = -1;
            call.notes = $("#TextAreaNote").val()
            call.timer = null;

            // Sends employee information to the server asynchronously using POST
            let response = await fetch("api/call", {
                method: "POST",
                headers: {
                    "Content-Type": "application/json; charset=utf-8"
                },
                body: JSON.stringify(call)
            });
            //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/call/${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
            call = new Object();
            // Setting object properties using modal fields values

            call.dateOpened = sessionStorage.getItem("dateOpened");
            call.openStatus = true;
            call.problemId = $("#ddlProblems").val();
            call.employeeId = $("#ddlEmployees").val();
            call.techId = $("#ddlTechnicians").val();
            call.id = parseInt(sessionStorage.getItem("id"));
            call.notes = $("#TextAreaNote").val();
            call.timer = sessionStorage.getItem("timer");

            if ($("#CheckBoxCloseCall").is(':checked')) {
                call.openStatus = false;
                call.dateClosed = sessionStorage.getItem("dateClosed");
            }
            else {
                call.dateClosed = null;
            }

            let response = await fetch("api/call", {
                method: "PUT",
                headers: { "Content-Type": "application/json; charset=utf-8" },
                body: JSON.stringify(call)
            });
            //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
    $("#callList").click((e) => {
        if (!e) e = window.event;
        let id = e.target.parentNode.id;
        if (id === "callList" || id === "") {
            id = e.target.id;
        } // clicked on row somewhere else 
        if (id !== "status" && id !== "heading") {
            let data = JSON.parse(sessionStorage.getItem("allcalls"));
            id === "0" ? setupForAdd() : setupForUpdate(id, data);
        } else {
            return false;
        }
    });

    //Builds and displays the employee list 
    const buildcallList = (data, usealldata = true) => {
        $("#callList").empty();
        //Building the header of the list
        div = $(`<div class="list-group-item row d-flex" id="status">call Info</div>
 <div class= "list-group-item row d-flex text-center" id="heading">
 <div class="col-4 h4">Date</div>
<div class="col-4 h4">For</div>
<div class="col-4 h4">Problem</div>
 </div>`);
        //Adding header to list div
        div.appendTo($("#callList"));
        //Adding all employees information to session storage
        usealldata ? sessionStorage.setItem("allcalls", JSON.stringify(data)) : null;
        //Creating the add button
        btn = $(`<button class="list-group-item row d-flex" id="0">...click to add call</button>`);
        //Adding the add button to the list div
        btn.appendTo($("#callList"));
        //Building the button with call information for each call and adding them to the list div
        data.forEach((call) => {
            btn = $(`<button class="list-group-item row d-flex" id="${call.id}">`);
            btn.html(`<div class="col-4" id="calldate${call.id}">${call.dateOpened.replace("T", " ")}</div>
 <div class="col-4" id="callfor${call.id}">${call.employeeName}</div>
 <div class="col-4" id="employeelastnam${call.id}">${call.problemDescription}</div>`
            );
            btn.appendTo($("#callList"));
        });

        //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 call
    $('#deletebutton').click(() => {
        _delete();
    });

    //Loading problems, employees, technicians and adding them to the dropdown options

    const loadProblemDDL = (empdiv) => {
        html = '';
        $('#ddlProblems').empty();
        let allProblems = JSON.parse(sessionStorage.getItem('allProblems'));
        allProblems.forEach((div) => { html += `<option value="${div.id}">${div.description}</option>` });
        $('#ddlProblems').append(html);
        $('#ddlProblems').val(empdiv);
    }; 
    const loadEmployeeDDL = (empdiv) => {
        html = '';
        $('#ddlEmployees').empty();
        let allEmployees = JSON.parse(sessionStorage.getItem('allEmployees'));
        allEmployees.forEach((div) => { html += `<option value="${div.id}">${div.lastname}</option>` });
        $('#ddlEmployees').append(html);
        $('#ddlEmployees').val(empdiv);
    }; 
    const loadTechnicianDDL = (empdiv) => {
        html = '';
        $('#ddlTechnicians').empty();
        let allEmployees = JSON.parse(sessionStorage.getItem('allEmployees'));
        allEmployees.forEach((div) => { if (div.isTech) { html += `<option value="${div.id}">${div.lastname}</option>` } });
        $('#ddlTechnicians').append(html);
        $('#ddlTechnicians').val(empdiv);
    }; 

    //Listens to click on the darkmode button and turns darkmode on or off

    $('#lightSwitch').click(() => {

        if ($('#lightSwitch').is(':checked') == true) {
            $('body').addClass('darkMode');
            $('#callList').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');
            $('#callList').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 ($("#CallModalForm").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 ddlProblems and validating

    $("#ddlProblems").change(e => {
        $("#modalstatus").removeClass();
        if ($("#CallModalForm").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 ddlEmployees and validating

    $("#ddlEmployees").change(e => {
        $("#modalstatus").removeClass();
        if ($("#CallModalForm").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 ddlTechnicians and validating

    $("#ddlTechnicians").change(e => {
        $("#modalstatus").removeClass();
        if ($("#CallModalForm").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

    $("#CallModalForm").validate({
        rules: {
            ddlProblems: {required: true},
            ddlEmployees: {required: true},
            ddlTechnicians: {required: true},
            TextAreaNote: { maxlength: 250, required: true}
        },
        errorElement: "div",
        messages: {
            ddlProblems: {
                required: "select Problem"
            },
            ddlEmployees: {
                required: "select Employee"
            },
            ddlTechnicians: {
                required: "select Tech"
            },
            TextAreaNote: {
                required: "required 1-250 chars.", maxlength: "required 1-250 chars."
            }
        }
    });

    // Gives us the proper format for the date and time

    const formatDate = (date) => {
        let d;
        (date === undefined) ? d = new Date() : d = new Date(Date.parse(date));
        let _day = d.getDate();
        if (_day < 10) { _day = "0" + _day; }
        let _month = d.getMonth() + 1;
        if (_month < 10) { _month = "0" + _month; }
        let _year = d.getFullYear();
        let _hour = d.getHours();
        if (_hour < 10) { _hour = "0" + _hour; }
        let _min = d.getMinutes();
        if (_min < 10) { _min = "0" + _min; }
        return _year + "-" + _month + "-" + _day + "T" + _hour + ":" + _min;
    }

    // Listens to close call checkbox click and displays or removes the date closed based on if it is checked or unchecked

    $("#CheckBoxCloseCall").click(() => {
        if ($("#CheckBoxCloseCall").is(":checked")) {
            $("#dateClosedText").text(formatDate().replace("T", " "));
            sessionStorage.setItem("dateClosed", formatDate());
        } else {
            $("#dateClosedText").text("");
            sessionStorage.setItem("dateClosed", "");
        }
    }); 

    // Reads search input with every key up and filters the data and passes the filtered data to buildcallList

    $("#srch").keyup(() => {
        let alldata = JSON.parse(sessionStorage.getItem("allcalls"));
        let filtereddata = alldata.filter((call) => call.employeeName.match(new RegExp($("#srch").val(), 'i')));
        buildcallList(filtereddata, false);
    }); 

}); 

//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);
    } 
}