- URL 하드코딩 → .env APP_URL 기반 동적 URL로 변경 - DB 연결 하드코딩 → .env 기반으로 변경 - MySQL strict mode DATE 오류 수정
12 KiB
12 KiB
common_addrowJS.php 개발자 가이드
📋 개요
common_addrowJS.php는 방화셔터 견적 시스템의 핵심 JavaScript 컴포넌트로, 견적 테이블에 새로운 행을 동적으로 추가하고 관리하는 기능을 제공합니다. 이 파일은 PHP와 JavaScript가 혼합된 형태로 구성되어 있으며, 견적 항목의 복잡한 입력 폼을 자동으로 생성합니다.
🏗️ 파일 구조
📁 파일 위치
/estimate/common/common_addrowJS.php
📊 파일 정보
- 파일 크기: 113KB (2536 lines)
- 주요 언어: PHP + JavaScript + jQuery
- 의존성: jQuery, Bootstrap, models.json
🔧 핵심 기능
1. 모델 데이터 로드
// models.json에서 스크린/철재 모델 정보 로드
$jsonFile = $_SERVER['DOCUMENT_ROOT'] . '/models/models.json';
$models = json_decode(file_get_contents($jsonFile), true);
// 스크린과 철재 모델 분리
$screenModels = array_filter($models, function ($m) {
return $m['slatitem'] === '스크린';
});
$steelModels = array_filter($models, function ($m) {
return $m['slatitem'] === '철재';
});
2. 메인 함수: addRow()
function addRow(tableBody, rowData, typebutton, afterRow = null, autoData = {})
매개변수
tableBody: 대상 테이블의 tbody 요소rowData: 행에 설정할 초기 데이터 객체typebutton: 버튼 타입 (사용되지 않음)afterRow: 삽입할 기준 행 (선택사항)autoData: 자동 계산 데이터 (선택사항)
📊 컬럼 구조 (71개 컬럼)
🎯 컬럼별 특성
기본 컬럼 (1-3)
- col1: 행 번호 (자동 생성, readonly)
- col2: 기본 입력 필드
- col3: 기본 입력 필드
모델 관련 컬럼 (4-7)
- col4: 스크린 모델 선택 (드롭다운)
screenModelOptions에서 동적 로드- 변경 시
modelChange_screen()함수 호출
- col5: readonly 필드 (자동 계산)
- col6: 셔터박스 타입 선택
- 벽면형(120*70)
- 측면형(120*120)
- 혼합형(12070)(120120)
- col7: 마감 타입 선택
- SUS마감
- EGI마감
제작 사이즈 컬럼 (10-11)
- col10: 제작 사이즈 (가로)
- col11: 제작 사이즈 (세로)
- 특별 처리: col10은 3개의 필드로 분할
col10_SW: 가로 사이즈col11_SH: 세로 사이즈col10: 통합 사이즈
수량 컬럼 (14)
- col14: 수량 입력 + 자동산출 버튼
'<button type="button" class="btn btn-sm btn-outline-primary ms-1 calc-btn viewNoBtn" title="자동산출"><i class="bi bi-calculator-fill"></i></button>'
모터 관련 컬럼 (18-19)
- col18: 모터 브랜드 + 전압 + 유선/무선
- 브랜드: 경동(견적가포함), 대한, 기타
- 전압: 220V, 380V
- 연결: 유선, 무선
- col19: 모터 용량 선택
- 브라켓 사이즈별 용량 매핑
- 380*180: 150K, 300K, 400K
- 530*320: 300K, 400K
- 600*350: 500K, 600K
- 690*390: 800K, 1000K
셔터박스 컬럼 (36)
- col36: 복합 입력 필드
- 기본 옵션: 500380, 500350
- 직접 입력 옵션
- 전면밑, 레일폭, 박스 방향 설정
let selectHtml = '<select name="col36[]">...</select>';
let inputHtml = '<input type="text" name="col36_custom[]">';
let inputHtmlfrontbottom = '<input type="text" name="col36_frontbottom[]">';
let inputHtmlrailwidth = '<input type="text" name="col36_railwidth[]">';
let selectHtmlboxdirection = '<select name="col36_boxdirection[]">...</select>';
마구리 윙 컬럼 (45)
- col45: 기본 입력 필드
- col45_wing: 마구리 윙 길이
- 기본값:
$('#maguriWing').val()또는 빈 값
- 기본값:
샤프트 관련 컬럼 (59)
- col59: 복합 입력 필드
- 인치 선택: 2인치, 3인치
- 길이 입력
- 수량 입력
Readonly 컬럼들
- col5, 12, 13, 23, 37, 48, 51, 54, 58, 67: 자동 계산 필드
🎨 UI/UX 특징
📱 반응형 디자인
- Bootstrap 클래스 활용
- 모바일 최적화
- 테이블 반응형 처리
🎯 컬럼 너비 최적화
let width = [2, 3, 4, 5, 7, 20, 22, 23, 29, 30, 36, 45].includes(i) ? '85px' : '50px';
width = [6].includes(i) ? '170px' : width;
width = [18].includes(i) ? '60px' : width;
width = [23,32,43,46,49,53,62].includes(i) ? '50px' : width;
🔘 버튼 시스템
- 추가 버튼:
+(새 행 추가) - 삭제 버튼:
-(행 삭제) - 복사 버튼: 📋 (행 복사)
- 계산 버튼: 🧮 (자동 산출)
⚡ 이벤트 핸들링
🔄 모델 변경 이벤트
newRow.find('.col4-select').on('input change', function() {
var row = $(this).closest('tr');
modelChange_screen(row);
});
🔌 모터 브랜드 변경 이벤트
newRow.find('.col18_brand').on('change', function() {
var row = $(this).closest('tr');
const qty = row.find('.col14-input').val();
const col18_brandValue = row.find('.col18_brand').val();
// 모터 브랜드별 처리 로직
});
🎛️ 셔터박스 커스텀 입력 이벤트
newRow.find('.col36-select').on('change', function() {
var selectedValue = $(this).val();
var customInput = $(this).closest('td').find('.col36-custom-input');
if (selectedValue === 'custom') {
customInput.show();
customInput.focus();
} else {
customInput.hide();
customInput.val('');
}
});
🧮 자동 계산 시스템
📏 철재 스라트 계산 함수들
Slat_updateCol59(): 샤프트 수량 계산
function Slat_updateCol59(row) {
var col10Value = parseFloat(row.find('.col10-input').val()) || 0; // 셔터 길이
var col13Value = parseFloat(row.find('.col13-input').val()) || 0; // 중량
var col59Input = row.find('.col59-input');
// 길이와 중량에 따른 샤프트 수량 결정
if (col10Value <= 4500) {
if (col13Value <= 400) {
col59Input.val(4);
} else if (col13Value > 400) {
col59Input.val(5);
}
}
// ... 추가 조건들
}
Slat_updateCol60to71(): 샤프트 길이별 수량 계산
function Slat_updateCol60to71(row) {
var col15Value = parseFloat(row.find('.col15-input').val()) || 0; // 셔터수량
var col59Value = parseFloat(row.find('.col22-select').val()) || 0; // 브라켓인치
var col10Value = parseFloat(row.find('.col10-input').val()) || 0; // 제작사이즈 가로
// 브라켓 인치별 샤프트 길이 분류
row.find('.col61-input').val((col59Value === 4 && col10Value <= 3050) ? col15Value : 0);
row.find('.col62-input').val((col59Value === 4 && col10Value > 3050 && col10Value <= 4550) ? col15Value : 0);
// ... 추가 조건들
}
Slat_updateCol72(): 셔터박스 수량 계산
function Slat_updateCol72(row) {
var col38Value = parseFloat(row.find('.col38-input').val()) || 0; // 셔터박스 사이즈
var col72Input = row.find('.col72-input');
// 사이즈별 박스 수량 결정
col72Input.val((col38Value <= 1600) ? 3 :
(col38Value <= 2800) ? 4 :
(col38Value <= 4000) ? 5 :
// ... 추가 조건들
0);
}
Slat_updateCol73(): 셔터박스 길이 계산
function Slat_updateCol73(row) {
var col38Value = parseFloat(row.find('.col38-input').val()) || 0; // 셔터박스 사이즈
var col72Value = parseFloat(row.find('.col72-input').val()) || 0;
row.find('.col73-input').val(col38Value + 3000 * col72Value);
}
Slat_updateCol74to75(): 앵글 수량 계산
function Slat_updateCol74to75(row) {
var col15Value = parseFloat(row.find('.col15-input').val()) || 0; // 셔터수량
var col73Value = parseFloat(row.find('.col73-input').val()) || 0;
// 길이별 앵글 수량 계산
var col74Input = row.find('.col74-input');
col74Input.val((col73Value <= 9000) ? 3 * col15Value:
(col73Value > 9000 && col73Value <= 12000) ? 4 * col15Value:
// ... 추가 조건들
0);
}
Slat_updateCo76(): 조인트바 수량 계산
function Slat_updateCo76(row) {
var col15Value = parseFloat(row.find('.col15-input').val()) || 0; // 셔터수량
var col10Value = parseFloat(row.find('.col10-input').val()) || 0; // 제작사이즈 (가로)
var col76Input = row.find('.col76-input');
var calculatedValue = 2 + Math.floor((col10Value - 500) / 1000);
col76Input.val(calculatedValue * col15Value);
}
Slat_updateTotals(): 전체 합계 계산
function Slat_updateTotals() {
var sumColumns = [16, 17, 18, 19, 20, 21, 22, 31, 32, 33, 34, 35, 38, 39, 40, 41, 42, 45, 46, 47, 48, 49, 50, 51, 54, 55, 57, 58, 59, 60, 61, 62, 63, 64, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 81, 82, 83, 84];
sumColumns.forEach(function (colIndex) {
var total = 0;
$('#estimateSlatTable tbody tr').each(function () {
var $cell = $(this).find('td').eq(colIndex - 1);
var val = '';
if ($cell.find('input').length > 0) {
val = $cell.find('input').val() || '';
} else if ($cell.find('select').length > 0) {
val = $cell.find('select').val() || '';
}
var numericValue = parseFloat(val.toString().replace(/,/g, '')) || 0;
total += numericValue;
});
var formattedTotal = total === 0 ? '' : total.toLocaleString();
$('#estimateSlattotalCol' + colIndex).text(formattedTotal);
});
}
🔧 개발자 사용법
📝 기본 사용법
// 새로운 행 추가
addRow($('#estimateTable tbody'), {}, 'add');
// 특정 데이터로 행 추가
addRow($('#estimateTable tbody'), {
col4: '스크린모델명',
col14: '10',
col10: '3000'
}, 'add');
// 특정 행 다음에 삽입
addRow($('#estimateTable tbody'), {}, 'add', $('#someRow'));
🎯 커스텀 데이터 처리
// 자동 계산 데이터 포함
addRow($('#estimateTable tbody'), rowData, 'add', null, {
calculated: true,
timestamp: new Date().getTime()
});
🔄 이벤트 바인딩
// 새로 추가된 행에 이벤트 바인딩
$('#estimateTable').on('change', '.col4-select', function() {
var row = $(this).closest('tr');
modelChange_screen(row);
});
🚨 주의사항
⚠️ 필수 의존성
- jQuery 3.x 이상
- Bootstrap 5.x
- models.json 파일 존재 필요
🔒 보안 고려사항
- XSS 방지를 위한 입력값 검증 필요
- SQL 인젝션 방지를 위한 서버 사이드 검증 필요
📱 성능 최적화
- 대량의 행 추가 시 성능 저하 가능
- 이벤트 위임 사용 권장
- 메모리 누수 방지를 위한 이벤트 정리 필요
🐛 디버깅 가이드
🔍 콘솔 로그 확인
// 조인트바 계산 디버깅
console.log('조인트바 계산 col10Value : ', col10Value);
console.log('조인트바 계산 col15Value : ', col15Value);
console.log('조인트바 계산 col76 : ', col76Input.val());
🛠️ 일반적인 문제 해결
1. 모델 옵션이 로드되지 않는 경우
// models.json 파일 경로 확인
console.log('Models loaded:', screenModelOptions, steelModelOptions);
2. 이벤트가 작동하지 않는 경우
// 이벤트 바인딩 확인
$(document).on('change', '.col4-select', function() {
console.log('Model changed:', $(this).val());
});
3. 계산이 올바르지 않은 경우
// 입력값 확인
console.log('Input values:', {
col10: $('.col10-input').val(),
col13: $('.col13-input').val(),
col15: $('.col15-input').val()
});
📚 관련 파일
🔗 의존성 파일
/models/models.json: 모델 데이터jQuery: DOM 조작Bootstrap: UI 프레임워크
🔗 연관 함수
modelChange_screen(): 모델 변경 처리calculateAmount(): 금액 계산updateTotals(): 합계 업데이트
🎯 향후 개선 방향
🔄 코드 리팩토링
- 함수 분리 및 모듈화
- TypeScript 도입 고려
- ES6+ 문법 활용
🎨 UI/UX 개선
- 드래그 앤 드롭 행 재정렬
- 키보드 단축키 지원
- 실시간 검증 메시지
⚡ 성능 최적화
- 가상 스크롤링 도입
- 지연 로딩 구현
- 메모리 사용량 최적화
📅 문서 버전: 1.0
👨💻 작성자: 전산실장 김보곤