IT tech Coding/javascript

자동으로 엑셀처럼 행을 추가하는 javascript 코드 연구

Coding Life 2024. 8. 23. 14:47

기본적으로 행추가 함수


// 행 추가
function addRow(tableBody, rowData, typebutton) {
    var newRow = $('<tr>');

    newRow.append('<td class="text-center" style="width:80px;">' +
        '<div class="d-flex justify-content-center mt-1">' + 
        '<button type="button" class="btn btn-primary btn-sm viewNoBtn add-row me-1" data-table="' + tableBody.closest('table').attr('id') + '">+</button>' +
        '<button type="button" class="btn btn-danger btn-sm viewNoBtn remove-row">-</button>' +
        '</div></td>');

    newRow.append('<td class="text-end">' +
      '<div class="d-flex">' +      
      '<div class="specialinputWrap"><input type="text" name="col1[]" class="form-control text-start w200px" required value="' + (rowData.col1 || '') + '" data-modal="itemModalTemplate"><button class="specialbtnClear"></button></div></div></td>');
    newRow.append('<td class="text-center"><input type="text" name="col2[]" class="form-control text-center w100px"  value="' + (rowData.col2 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="text" name="col3[]" class="form-control text-center w120px" value="' + (rowData.col3 || '') + '"></td>');
    newRow.append('<td class="text-center"><select name="col4[]" class="form-control w80px"><option value="">선택</option><option value="일반">일반</option><option value="타업체">타업체</option><option value="한산">한산</option></select></td>');
    newRow.append('<td class="text-center"><input type="text" name="col5[]" class="form-control text-center w60px"  onkeyup="inputNumberFormat(this);" value="' + (rowData.col5 || '') + '"></td>');
    newRow.append('<td class="text-center"><select name="col6[]" class="form-control text-center"> <option value="">선택</option><option value="BOX">BOX</option><option value="EA">EA</option><option value="ST">ST</option><option value="대">대</option><option value="식">식</option></select></td>');
    newRow.append('<td class="text-center"><input type="date" name="col7[]" class="form-control text-center" value="' + (rowData.col7 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="date" name="col8[]" class="form-control text-center" value="' + (rowData.col8 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="date" name="col9[]" class="form-control text-center" value="' + (rowData.col9 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="date" name="col10[]" class="form-control text-center" value="' + (rowData.col10 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="date" name="col11[]" class="form-control text-center" value="' + (rowData.col11 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="date" name="col12[]" class="form-control text-center" value="' + (rowData.col12 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="text" name="col13[]" class="form-control text-start w200px" value="' + (rowData.col13 || '') + '"></td>');
newRow.append('<td class="text-center"><input type="date" name="col14[]" class="form-control text-center w200px" value="' + (rowData.col14 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="text" name="col15[]" class="form-control text-end" onkeyup="inputNumberFormat(this);" value="' + (rowData.col15 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="text" name="col16[]" class="form-control text-end" onkeyup="inputNumberFormat(this);" value="' + (rowData.col16 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="text" name="col17[]" class="form-control text-end" onkeyup="inputNumberFormat(this);" value="' + (rowData.col17 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="date" name="col18[]" class="form-control text-center" value="' + (rowData.col18 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="text" name="col19[]" class="form-control text-start" value="' + (rowData.col19 || '') + '"></td>');
    
    tableBody.append(newRow);
    initializeAutocomplete(newRow.find('input[name="col1[]"], input[name="col2[]"], input[name="col3[]"]'), itemOptions);

    // 첫 번째 행이 추가될 때 thead를 표시
    if (tableBody.children('tr').length === 1) {
        tableBody.closest('table').find('thead').show();
    }
}

 

위의 select문을 읽어서 기존의 데이터를 다시 보여주는 화면의 코드는 아래와 같습니다.

function addRow(tableBody, rowData, typebutton) {
    var newRow = $('<tr>');

    // + / - 버튼
    newRow.append('<td class="text-center" style="width:80px;">' +
        '<div class="d-flex justify-content-center mt-1">' + 
        '<button type="button" class="btn btn-primary btn-sm viewNoBtn add-row me-1" data-table="' + tableBody.closest('table').attr('id') + '">+</button>' +
        '<button type="button" class="btn btn-danger btn-sm viewNoBtn remove-row">-</button>' +
        '</div></td>');

    // 품명
    newRow.append('<td class="text-end">' +
      '<div class="d-flex">' +      
      '<div class="specialinputWrap"><input type="text" name="col1[]" class="form-control text-start w200px" required value="' + (rowData.col1 || '') + '" data-modal="itemModalTemplate"><button class="specialbtnClear"></button></div></div></td>');
    
    // 분류
    newRow.append('<td class="text-center"><input type="text" name="col2[]" class="form-control text-center w100px" value="' + (rowData.col2 || '') + '"></td>');
    
    // 사양
    newRow.append('<td class="text-center"><input type="text" name="col3[]" class="form-control text-center w120px" value="' + (rowData.col3 || '') + '"></td>');
    
    // 방화여부
    newRow.append('<td class="text-center"><select name="col4[]" class="form-control w80px">' +
        '<option value="" ' + (rowData.col4 === '' ? 'selected' : '') + '>선택</option>' +
        '<option value="일반" ' + (rowData.col4 === '일반' ? 'selected' : '') + '>일반</option>' +
        '<option value="타업체" ' + (rowData.col4 === '타업체' ? 'selected' : '') + '>타업체</option>' +
        '<option value="한산" ' + (rowData.col4 === '한산' ? 'selected' : '') + '>한산</option>' +
        '</select></td>');
    
    // 대수
    newRow.append('<td class="text-center"><input type="text" name="col5[]" class="form-control text-center w60px" onkeyup="inputNumberFormat(this);" value="' + (rowData.col5 || '') + '"></td>');
    
    // 단위
    newRow.append('<td class="text-center"><select name="col6[]" class="form-control text-center">' +
        '<option value="" ' + (rowData.col6 === '' ? 'selected' : '') + '>선택</option>' +
        '<option value="BOX" ' + (rowData.col6 === 'BOX' ? 'selected' : '') + '>BOX</option>' +
        '<option value="EA" ' + (rowData.col6 === 'EA' ? 'selected' : '') + '>EA</option>' +
        '<option value="ST" ' + (rowData.col6 === 'ST' ? 'selected' : '') + '>ST</option>' +
        '<option value="대" ' + (rowData.col6 === '대' ? 'selected' : '') + '>대</option>' +
        '<option value="식" ' + (rowData.col6 === '식' ? 'selected' : '') + '>식</option>' +
        '</select></td>');
    
    // 소재신청, 절단, NCT(L), 절곡, 제작, 출하
    newRow.append('<td class="text-center"><input type="date" name="col7[]" class="form-control text-center" value="' + (rowData.col7 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="date" name="col8[]" class="form-control text-center" value="' + (rowData.col8 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="date" name="col9[]" class="form-control text-center" value="' + (rowData.col9 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="date" name="col10[]" class="form-control text-center" value="' + (rowData.col10 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="date" name="col11[]" class="form-control text-center" value="' + (rowData.col11 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="date" name="col12[]" class="form-control text-center" value="' + (rowData.col12 || '') + '"></td>');

    // 비고, 메모
    newRow.append('<td class="text-center"><input type="text" name="col13[]" class="form-control text-start w200px" value="' + (rowData.col13 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="text" name="col14[]" class="form-control text-center w200px" value="' + (rowData.col14 || '') + '"></td>');
    
    // 수주단가, 수주금액, 계산서금액
    newRow.append('<td class="text-center"><input type="text" name="col15[]" class="form-control text-end" onkeyup="inputNumberFormat(this);" value="' + (rowData.col15 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="text" name="col16[]" class="form-control text-end" onkeyup="inputNumberFormat(this);" value="' + (rowData.col16 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="text" name="col17[]" class="form-control text-end" onkeyup="inputNumberFormat(this);" value="' + (rowData.col17 || '') + '"></td>');
    
    // 계산서발행일, 실적
    newRow.append('<td class="text-center"><input type="date" name="col18[]" class="form-control text-center" value="' + (rowData.col18 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="text" name="col19[]" class="form-control text-start" value="' + (rowData.col19 || '') + '"></td>');

    tableBody.append(newRow);

    // Autocomplete 설정
    initializeAutocomplete(newRow.find('input[name="col1[]"], input[name="col2[]"], input[name="col3[]"]'), itemOptions);

    // 첫 번째 행이 추가될 때 thead를 표시
    if (tableBody.children('tr').length === 1) {
        tableBody.closest('table').find('thead').show();
    }
}

function addRow(tableBody, rowData, typebutton) {
    var newRow = $('<tr>');

    // + / - 버튼
    newRow.append('<td class="text-center" style="width:80px;">' +
        '<div class="d-flex justify-content-center mt-1">' + 
        '<button type="button" class="btn btn-primary btn-sm viewNoBtn add-row me-1" data-table="' + tableBody.closest('table').attr('id') + '">+</button>' +
        '<button type="button" class="btn btn-danger btn-sm viewNoBtn remove-row">-</button>' +
        '</div></td>');

    // 품명
    newRow.append('<td class="text-end">' +
      '<div class="d-flex">' +      
      '<div class="specialinputWrap"><input type="text" name="col1[]" class="form-control text-start w200px" required value="' + (rowData.col1 || '') + '" data-modal="itemModalTemplate"><button class="specialbtnClear"></button></div></div></td>');
    
    // 분류
    newRow.append('<td class="text-center"><input type="text" name="col2[]" class="form-control text-center w100px" value="' + (rowData.col2 || '') + '"></td>');
    
    // 사양
    newRow.append('<td class="text-center"><input type="text" name="col3[]" class="form-control text-center w120px" value="' + (rowData.col3 || '') + '"></td>');
    
    // 방화여부
    newRow.append('<td class="text-center"><select name="col4[]" class="form-control w80px">' +
        '<option value="" ' + (rowData.col4 === '' ? 'selected' : '') + '>선택</option>' +
        '<option value="일반" ' + (rowData.col4 === '일반' ? 'selected' : '') + '>일반</option>' +
        '<option value="타업체" ' + (rowData.col4 === '타업체' ? 'selected' : '') + '>타업체</option>' +
        '<option value="한산" ' + (rowData.col4 === '한산' ? 'selected' : '') + '>한산</option>' +
        '</select></td>');
    
    // 대수
    newRow.append('<td class="text-center"><input type="text" name="col5[]" class="form-control text-center w60px" onkeyup="inputNumberFormat(this);" value="' + (rowData.col5 || '') + '"></td>');
    
    // 단위
    newRow.append('<td class="text-center"><select name="col6[]" class="form-control text-center">' +
        '<option value="" ' + (rowData.col6 === '' ? 'selected' : '') + '>선택</option>' +
        '<option value="BOX" ' + (rowData.col6 === 'BOX' ? 'selected' : '') + '>BOX</option>' +
        '<option value="EA" ' + (rowData.col6 === 'EA' ? 'selected' : '') + '>EA</option>' +
        '<option value="ST" ' + (rowData.col6 === 'ST' ? 'selected' : '') + '>ST</option>' +
        '<option value="대" ' + (rowData.col6 === '대' ? 'selected' : '') + '>대</option>' +
        '<option value="식" ' + (rowData.col6 === '식' ? 'selected' : '') + '>식</option>' +
        '</select></td>');
    
    // 소재신청, 절단, NCT(L), 절곡, 제작, 출하
    newRow.append('<td class="text-center"><input type="date" name="col7[]" class="form-control text-center" value="' + (rowData.col7 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="date" name="col8[]" class="form-control text-center" value="' + (rowData.col8 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="date" name="col9[]" class="form-control text-center" value="' + (rowData.col9 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="date" name="col10[]" class="form-control text-center" value="' + (rowData.col10 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="date" name="col11[]" class="form-control text-center" value="' + (rowData.col11 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="date" name="col12[]" class="form-control text-center" value="' + (rowData.col12 || '') + '"></td>');

    // 비고, 메모
    newRow.append('<td class="text-center"><input type="text" name="col13[]" class="form-control text-start w200px" value="' + (rowData.col13 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="text" name="col14[]" class="form-control text-center w200px" value="' + (rowData.col14 || '') + '"></td>');
    
    // 수주단가, 수주금액, 계산서금액
    newRow.append('<td class="text-center"><input type="text" name="col15[]" class="form-control text-end" onkeyup="inputNumberFormat(this);" value="' + (rowData.col15 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="text" name="col16[]" class="form-control text-end" onkeyup="inputNumberFormat(this);" value="' + (rowData.col16 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="text" name="col17[]" class="form-control text-end" onkeyup="inputNumberFormat(this);" value="' + (rowData.col17 || '') + '"></td>');
    
    // 계산서발행일, 실적
    newRow.append('<td class="text-center"><input type="date" name="col18[]" class="form-control text-center" value="' + (rowData.col18 || '') + '"></td>');
    newRow.append('<td class="text-center"><input type="text" name="col19[]" class="form-control text-start" value="' + (rowData.col19 || '') + '"></td>');

    tableBody.append(newRow);

    // Autocomplete 설정
    initializeAutocomplete(newRow.find('input[name="col1[]"], input[name="col2[]"], input[name="col3[]"]'), itemOptions);

    // 첫 번째 행이 추가될 때 thead를 표시
    if (tableBody.children('tr').length === 1) {
        tableBody.closest('table').find('thead').show();
    }
}

 

 

아이템을 가져오는 코드(함수)

fetch_item.php 파일 내용입니다.

<?php
require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");

header("Content-Type: application/json");  // JSON을 사용하기 위해 필요한 구문

require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
$pdo = db_connect();

// 테이블에서 항목을 가져오는 함수
function getItems($pdo, $table) {
    $sql = "SELECT item_name FROM $table";
    try {
        $stmh = $pdo->query($sql);
        $items = $stmh->fetchAll(PDO::FETCH_COLUMN, 0);  // 첫 번째 열의 값을 배열로 가져옵니다.
        // 빈 항목을 제거
        return array_filter($items, function($value) {
            return !empty($value) && $value !== null && $value !== '';
        });
    } catch (PDOException $Exception) {
        print "오류: " . $Exception->getMessage();
        return [];
    }
}

// 각 테이블에서 항목을 가져옵니다.
$itemProd = getItems($pdo, 'item_prod');
$itemSep = getItems($pdo, 'item_sep');
$itemSpec = getItems($pdo, 'item_spec');

// 데이터를 배열로 구성합니다.
$data = [
    'itemProd' => $itemProd,
    'itemSep' => $itemSep,
    'itemSpec' => $itemSpec
];

// JSON으로 인코딩하여 반환합니다.
echo json_encode($data, JSON_UNESCAPED_UNICODE);
?>

 

아이템을 불러오는 코드는 아래와 같다.

function fetchItemOptions() {
    if (ajaxRequest !== null) {
        ajaxRequest.abort();
    }

    ajaxRequest = $.ajax({
        enctype: 'multipart/form-data',
        processData: false,
        contentType: false,
        cache: false,
        timeout: 600000,
        url: "fetch_item.php",
        type: "post",
        data: '',
        dataType: "json",
        success: function(data) {
            // 품목, 분류, 사양에 해당하는 데이터를 가져와서 각각의 select 요소에 추가
            populateSelectOptions('col1[]', data.itemProd);
            populateSelectOptions('col2[]', data.itemSep);
            populateSelectOptions('col3[]', data.itemSpec);

            console.log(data); // 데이터 확인
        },
        error: function(jqxhr, status, error) {
            console.log(jqxhr, status, error);
        }
    });
}

function populateSelectOptions(selectName, items) {
    $('select[name="' + selectName + '"]').each(function() {
        var selectElement = $(this);
        selectElement.empty(); // 기존 옵션을 초기화

        // 기본 옵션 추가
        selectElement.append('<option value="">선택</option>');

        // 아이템 목록을 순회하며 옵션 추가
        items.forEach(function(item) {
            selectElement.append('<option value="' + item + '">' + item + '</option>');
        });
    });
}
반응형