자동으로 엑셀처럼 행을 추가하는 javascript 코드 연구
기본적으로 행추가 함수
// 행 추가
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>');
});
});
}