본문 바로가기
asp.net

[.net] mvc 웹 프로젝트(5)

by TTTGGG 2024. 6. 27.
728x90
반응형
SMALL

CRUD 페이지

 

StandardInfo1 페이지 구현

 

@model List<ExWebData.Models.Users>

@{
    Layout = null;
}

@inject ExWebServices.Interfaces.IButtonProvider ButtonProvider

<!-- 공통 버튼 영역 -->
@{
    var pageName = "StandardInfo1";
    var buttons = ButtonProvider.GetButtons(pageName).ToList();

    // 기본 기능 버튼 비활성화
    var excelButton = buttons.FirstOrDefault(b => b.Id == "btnExcel");
    if (excelButton != null)
    {
        excelButton.Used = false;
    }

    // 기본 버튼 외에 새로운 기능 필요한 경우
    buttons.Add(new ExWebServices.Interfaces.ButtonModel { Id = "btnAdd", Text = "추가", OnClickAction = "addFunction", AriaLabel = "추가 버튼", Used = true, Visible = true });
    ViewData["PageName"] = pageName;
}

<!-- 공통 팝업 프레임 포함 -->
@Html.Partial("~/Views/Shared/CommonPopup.cshtml")
@Html.Partial("~/Views/Shared/ErrorPopup.cshtml")

<div class="container mt-4">
    <div class="row mb-3">
        <form role="form" id="StandardInfo1_form" class="form-inline w-100" action="javascript:void(0);" style="display: flex; flex-wrap: nowrap; align-items: center;">
            <div class="form-group mr-4">
                <label for="ddlCompany" class="mr-2">Company:</label>
                <select id="ddlCompany" class="form-control" style="width: 200px; margin-right: 10px;">
                    <option value="">All</option>
                </select>
            </div>
            <div class="form-group mr-4">
                <label for="ddlDepartment" class="mr-2">Department:</label>
                <select id="ddlDepartment" class="form-control" style="width: 200px; margin-right: 10px;">
                    <option value="">All</option>
                </select>
            </div>
            <div class="form-group mr-4">
                <label for="ddlTeam" class="mr-2">Team:</label>
                <select id="ddlTeam" class="form-control" style="width: 200px; margin-right: 10px;">
                    <option value="">All</option>
                </select>
            </div>
            <div class="form-group mr-4">
                <label for="txtUserName" class="mr-2">Name:</label>
                <input type="text" id="txtUserName" class="form-control" style="width: 200px; margin-right: 10px;" autocomplete="off">
            </div>
        </form>
    </div>

    <div class="row mb-3">
        @Html.Partial("_CommonButtons", buttons)
    </div>

    <div class="table-responsive">
        <table id="dataTable_StandardInfo1" class="table table-striped table-bordered table-hover">
            <thead class="thead-light">
                <tr>
                    <th>Id</th>
                    <th>Company</th>
                    <th>Department</th>
                    <th>Team</th>
                    <th>Number</th>
                    <th>Name</th>
                    <th>Email</th>
                    <th>Address</th>
                </tr>
            </thead>
        </table>
    </div>
    <div class="row mt-3">
        <div class="col-sm-12 text-center">
            <div id="dataTable_paginate" class="dataTables_paginate"></div>
        </div>
        <div class="col-sm-6 text-left">
            <div id="dataTable_info" class="dataTables_info"></div>
        </div>
        <div class="col-sm-6 text-right">
            <div id="dataTable_length" class="dataTables_length"></div>
        </div>
    </div>
</div>


@section Styles {
    <link rel="stylesheet" href="~/css/datatables.css">
}

<script>
    var table;  // 전역 변수로 선언

    function openPopup(content, title = '', width = '90%', height = 'auto') {
        $('#popupTitle').text(title);
        $('#popupBody').html(content);
        $('.popup-content').css({
            'width': width,
            'height': height
        });
        $('#commonPopup').fadeIn();
    }

    function closePopup() {
        $('#commonPopup').fadeOut();
    }

    // editRecord 함수를 전역에서 참조할 수 있도록 window 객체에 바인딩
    window.editRecord = function (id) {
        $.get("/Standard/StandardInfo1/GetUserById", { id: id }, function (data) {
            if (data.success) {
                window.editData = data.user;
                $.get("/Standard/StandardInfo1_Popup", function (popupContent) {
                    openPopup(popupContent, 'Edit Form', '400px', '600px');
                });
            } else {
                openErrorPopup('데이터를 불러오는 중 오류가 발생했습니다.');
            }
        }).fail(function () {
            openErrorPopup('오류가 발생하였습니다.');
        });
    }

    $(document).ready(function () {
        initializeStandardInfo1();

        // 콤보박스 데이터 로드
        loadComboBoxData('/Comm/GetCompanies', '#ddlCompany');

        $('#ddlCompany').on('change', function () {
            var company = $(this).val();
            loadComboBoxData(`/Comm/GetDepartments?company=${company}`, '#ddlDepartment');
            resetComboBox('#ddlDepartment');
            resetComboBox('#ddlTeam');
            reloadDataTable();
        });

        $('#ddlDepartment').on('change', function () {
            var company = $('#ddlCompany').val();
            var department = $(this).val();
            loadComboBoxData(`/Comm/GetTeams?company=${company}&department=${department}`, '#ddlTeam');
            resetComboBox('#ddlTeam');
            reloadDataTable();
        });

        $('#ddlTeam').on('change', function () {
            reloadDataTable();
        });

        //$('#txtUserName').on('keyup', function () {
        //    reloadDataTable();
        //});
    });

    function loadComboBoxData(url, elementId) {
        $.get(url, function (data) {
            var options = '<option value="">All</option>';
            options += data.map(function (item) {
                return `<option value="${item}">${item}</option>`;
            }).join('');
            $(elementId).html(options);
        }).fail(function () {
            console.error(`Failed to load data from ${url}`);
            alert('Failed to load data. Please try again later.');
        });
    }

    function resetComboBox(elementId) {
        $(elementId).empty().append('<option value="">All</option>');
        $(elementId).val(''); // 콤보박스 값을 비웁니다
    }

    function reloadDataTable() {
        table.ajax.reload();
    }

    function initializeStandardInfo1() {
        console.log('set button for StandardInfo1!');

        // Close button event
        $('.close-btn').on('click', function () {
            closePopup();
        });

        function bindButtonEvents() {
            var pageName = '@ViewData["PageName"]';

            $(`#${pageName}btnSearch`).on('click', function () {
                $('#dataTable_StandardInfo1').DataTable().ajax.reload();
                searchFunction();
            });
            $(`#${pageName}btnRegister`).on('click', function () {
                registerFunction();
            });
            $(`#${pageName}btnExcel`).on('click', function () {
                exportExcelFunction();
            });
            //
            // 이 화면에만 필요한 기능이 있으면 추가
            $(`#${pageName}btnAdd`).on('click', function () {
                addFunction();
            });
        }

        function searchFunction() {
            // 추가 기능 구현
        }

        function registerFunction() {
            window.editData = null;  // 새로 등록할 때는 editData를 null로 설정
            $.get("/Standard/StandardInfo1_Popup", function (data) {
                openPopup(data, 'Register Form', '400px', '600px');
                //openPopup(data, 'Register Form', '80%', 'auto');
            }).fail(function () {
                openErrorPopup('오류가 발생하였습니다.');
            });
        }

        function exportExcelFunction() {
            // 추가 기능 구현
        }

        function addFunction() {
            alert("추가 버튼 클릭됨");
            // 추가 기능 구현
        }

        bindButtonEvents();

        // DataTable 초기화
        table = $('#dataTable_StandardInfo1').DataTable({
            scrollY: '50vh',
            scrollCollapse: true,
            ajax: {
                url: '/Standard/StandardInfo1/GetData',
                type: 'POST',
                data: function (d) {
                    d.company = $('#ddlCompany').val();
                    d.department = $('#ddlDepartment').val();
                    d.team = $('#ddlTeam').val();
                    d.name = $('#txtUserName').val();
                },
                dataSrc: function (json) {
                    console.log(json); // 반환된 데이터 확인
                    return json.data;
                },
                error: function (xhr, error, code) {
                    console.error('Ajax request failed:', xhr, error, code);
                    openErrorPopup('오류가 발생하였습니다.');
                }
            },
            columns: [
                {
                    data: 'id',
                    render: function (data, type, row, meta) {
                        return '<a href="javascript:void(0);" onclick="editRecord(' + data + ');">' + data + '</a>';
                    }
                },
                { data: 'company' },
                { data: 'department' },
                { data: 'team' },
                { data: 'number' },
                { data: 'name' },
                { data: 'email' },
                { data: 'addr' }
            ],
            dom: 'rt<"bottom"ip><"clear">',
            pageLength: 10,
            lengthMenu: [10, 25, 50, 100],
            language: {
                paginate: {
                    first: 'First',
                    last: 'Last',
                    next: 'Next',
                    previous: 'Previous'
                },
                //info: 'Showing _START_ to _END_ of _TOTAL_ entries',
                info: '',
                lengthMenu: 'Show _MENU_ entries'
            }
        });

        $('#dataTable_StandardInfo1 tbody').on('dblclick', 'tr', function () {
            var data = table.row(this).data();
            editRecord(data.id);
        });
    }
</script>

 

 

등록/수정/삭제 팝업 구현

 

@{
    Layout = null;
}

@Html.Partial("~/Views/Shared/CommonPopup.cshtml")
@Html.Partial("~/Views/Shared/CommonConfirm.cshtml")
@Html.Partial("~/Views/Shared/ErrorPopup.cshtml")

<form id="registerForm">
    <div class="mb-4 text-center">
        <h2 id="formTitle">등록</h2>
    </div>
    <div class="form-group mb-3">
        <label for="inputId">Id</label>
        <input type="text" id="inputId" class="form-control" required />
    </div>
    <div class="form-group mb-3">
        <label for="inputNumber">Number</label>
        <input type="text" id="inputNumber" class="form-control" required />
    </div>
    <div class="form-group mb-3">
        <label for="inputName">Name</label>
        <input type="text" id="inputName" class="form-control" required />
    </div>
    <div class="form-group mb-3">
        <label for="inputEmail">Email</label>
        <input type="email" id="inputEmail" class="form-control" required />
    </div>
    <div class="form-group mb-3">
        <label for="inputAddr">Addr</label>
        <input type="text" id="inputAddr" class="form-control" required />
    </div>
    <div class="form-group mb-3 text-center">
        <button type="submit" class="btn btn-primary w-50">Submit</button>
        <button type="button" id="deleteButton" class="btn btn-danger w-50" style="display: none;">Delete</button>
    </div>
</form>

<script>
    $(document).ready(function () {
        // 전달된 데이터가 있는 경우 처리
        if (window.editData) {
            $('#formTitle').text('수정');
            $('#inputId').val(window.editData.id).prop('readonly', true);
            $('#inputNumber').val(window.editData.number).prop('readonly', true);
            $('#inputName').val(window.editData.name);
            $('#inputEmail').val(window.editData.email);
            $('#inputAddr').val(window.editData.addr);
            $('#deleteButton').show(); // 수정 모드에서는 삭제 버튼 보이기
        } else {
            $('#formTitle').text('등록');
            $('#inputId').prop('readonly', false);
            $('#inputNumber').prop('readonly', false);
            $('#deleteButton').hide(); // 등록 모드에서는 삭제 버튼 숨기기
        }

        $('#registerForm').on('submit', function (e) {
            e.preventDefault();
            var formData = {
                id: $('#inputId').val(),
                number: $('#inputNumber').val(),
                name: $('#inputName').val(),
                email: $('#inputEmail').val(),
                addr: $('#inputAddr').val()
            };

            $.ajax({
                url: '/Standard/StandardInfo1/Register',
                type: 'POST',
                data: formData,
                success: function (response) {
                    if (response.success) {
                        closePopup();
                        var table = $('#dataTable_StandardInfo1').DataTable();
                        table.ajax.reload(function () {
                            var rowIndex = table.rows().eq(0).filter(function (index) {
                                return table.cell(index, 0).data() == response.newId;
                            });

                            if (rowIndex.any()) {
                                var rowIndexArray = rowIndex.toArray();
                                var page = Math.floor(rowIndexArray[0] / table.page.info().length);
                                table.page(page).draw(false);
                            } else {
                                table.page('last').draw(false);
                            }
                        }, false);
                    } else {
                        openErrorPopup('오류가 발생하였습니다.<br>' + response.errors.join('<br>'));
                    }
                },
                error: function (xhr, status, error) {
                    var errorMessage = '오류가 발생하였습니다.<br>' + xhr.responseText;
                    openErrorPopup(errorMessage);
                    console.error(xhr, status, error);
                }
            });
        });

        $('#deleteButton').on('click', function () {
            var userId = $('#inputId').val();
            openConfirm('정말로 삭제하시겠습니까?', function () {
                $.ajax({
                    url: '/Standard/StandardInfo1/Delete',
                    type: 'POST',
                    data: { id: userId },
                    success: function (response) {
                        if (response.success) {
                            var table = $('#dataTable_StandardInfo1').DataTable();
                            var currentPage = table.page();

                            table.ajax.reload(function () {
                                var info = table.page.info();
                                if (currentPage >= info.pages) {
                                    table.page(info.pages - 1).draw(false);
                                }
                            }, false);

                            closePopup(); // 등록/수정 팝업 창 닫기
                        } else {
                            openErrorPopup('삭제 중 오류가 발생하였습니다.<br>' + response.errors.join('<br>'));
                        }
                    },
                    error: function (xhr, status, error) {
                        var errorMessage = '오류가 발생하였습니다.<br>' + xhr.responseText;
                        openErrorPopup(errorMessage);
                        console.error(xhr, status, error);
                    }
                });
            });
        });
    });
</script>

 

 

컨트롤러 구현

 

public class StandardInfo1Controller : BaseController
{
    public StandardInfo1Controller(ApplicationDbContext context, ILogger<StandardInfo1Controller> logger)
        : base(context, logger)
    {
        _logger.LogInformation("StandardInfo1Controller created");
    }

    public IActionResult Index()
    {
        _logger.LogInformation("Index method called");
        return View("~/Views/Standard/StandardInfo1.cshtml");
    }

    [HttpPost]
    [Route("Standard/StandardInfo1/GetData")]
    public IActionResult GetData([FromForm] string company, [FromForm] string department, [FromForm] string team, [FromForm] string name)
    {
        _logger.LogInformation("GetData method called with company: {Company}, department: {Department}, team: {Team}, name: {Name}", company, department, team, name);

        var query = _context.Users.AsQueryable();

        if (!string.IsNullOrEmpty(company))
        {
            query = query.Where(u => u.Company == company);
        }

        if (!string.IsNullOrEmpty(department))
        {
            query = query.Where(u => u.Department == department);
        }

        if (!string.IsNullOrEmpty(team))
        {
            query = query.Where(u => u.Team == team);
        }

        if (!string.IsNullOrEmpty(name))
        {
            query = query.Where(u => u.Name.Contains(name));
        }

        var usersList = query
            .Select(u => new
            {
                u.Id,
                u.Company,
                u.Department,
                u.Team,
                u.Number,
                u.Name,
                u.Email,
                u.Addr
            })
            .ToList()
            .OrderBy(u => u.Company)
            .ThenBy(u => u.Department)
            .ThenBy(u => u.Team)
            .ThenBy(u => u.Id);

        _logger.LogInformation("Users list: {@UsersList}", usersList);

        return Json(new { data = usersList });
    }

    [HttpGet]
    [Route("Standard/StandardInfo1/GetUserById")]
    public IActionResult GetUserById([FromQuery] long id)
    {
        var user = _context.Users.Find(id);
        if (user == null)
        {
            return Json(new { success = false, error = "User not found" });
        }

        return Json(new { success = true, user = new { user.Id, user.Company, user.Department, user.Team, user.Number, user.Name, user.Email, user.Addr } });
    }

    [HttpPost]
    [Route("Standard/StandardInfo1/Register")]
    public IActionResult Register([FromForm] string id, [FromForm] string company, [FromForm] string department, [FromForm] string team, [FromForm] string number, [FromForm] string name, [FromForm] string email, [FromForm] string addr)
    {
        _logger.LogInformation("Register method called");

        try
        {
            if (ModelState.IsValid)
            {
                var userId = Convert.ToInt64(id);
                var user = _context.Users.Find(userId);

                if (user == null)
                {
                    user = new Users
                    {
                        Id = userId,
                        Company = company,
                        Department = department,
                        Team = team,
                        Number = number,
                        Name = name,
                        Email = email,
                        Addr = addr
                    };
                    _context.Users.Add(user);
                }
                else
                {
                    user.Company = company;
                    user.Department = department;
                    user.Team = team;
                    user.Name = name;
                    user.Email = email;
                    user.Addr = addr;
                    _context.Users.Update(user);
                }

                _context.SaveChanges();

                _logger.LogInformation("User registered/updated: {@User}", user);
                return Json(new { success = true, newId = user.Id });
            }

            _logger.LogWarning("Model state invalid: {@ModelState}", ModelState);
            return Json(new { success = false, errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage) });
        }
        catch (Exception ex)
        {
            return HandleException(ex, "Error occurred while registering/updating user");
        }
    }

    [HttpPost]
    [Route("Standard/StandardInfo1/Delete")]
    public IActionResult Delete([FromForm] long id)
    {
        _logger.LogInformation("Delete method called with id: {Id}", id);

        try
        {
            var user = _context.Users.Find(id);
            if (user == null)
            {
                return Json(new { success = false, errors = new[] { "User not found" } });
            }

            _context.Users.Remove(user);
            _context.SaveChanges();

            _logger.LogInformation("User deleted: {@User}", user);
            return Json(new { success = true });
        }
        catch (Exception ex)
        {
            return HandleException(ex, "Error occurred while deleting user");
        }
    }
}

 

728x90
반응형
LIST

'asp.net' 카테고리의 다른 글

[.net] ViewBag  (0) 2024.07.10
[.net] LINQ  (0) 2024.07.05
[.net] mvc 웹 프로젝트(4)  (0) 2024.06.27
[.net] mvc 웹 프로젝트(3)  (0) 2024.06.27
[.net] mvc 웹 프로젝트(2)  (0) 2024.06.27