fix: Select2 이벤트를 change에서 select2:select로 변경하여 같은 값 재선택 시에도 이벤트 발생하도록 수정

- estimateRegistFormPopup.jsp: 품번/품명 셀렉트박스 이벤트 수정
- estimateTemplate1.jsp: 품명 셀렉트박스 이벤트 수정 및 select2:clear 이벤트 추가
- common.js: initPartSelect2Ajax 함수의 품번/품명 이벤트 핸들러 수정
- ContractMgmtController.java: 견적서 신규 작성 시 품목 데이터 로드 주석처리
This commit is contained in:
2025-10-22 17:08:11 +09:00
parent 2fafff5ee5
commit 10c5a67b05
5 changed files with 159 additions and 129 deletions

View File

@@ -75,8 +75,8 @@ $(function(){
url = "/supplyChainMgmt/invoiceFormPopUp.do?checkArr="+targetObjId+"&actionType=view";
window.open(url, "", "width=1000,height=880");
}else if(targetType == "CONTRACT_ESTIMATE"){
url = "/contractMgmt/estimateRegistFormPopup.do?objId="+targetObjId+"&actionType=view";
window.open(url, "", "width=1000,height=560");
url = "/contractMgmt/estimateTemplate1.do?templateObjId="+targetObjId+"&actionType=view";
window.open(url, "", "width=1000,height=1200");
}
});

View File

@@ -1406,82 +1406,82 @@
}
});
// 품번 변경 이벤트
$partNoSelect.off('change').on('change', function() {
var selectedData = $(this).select2('data')[0];
if(selectedData && selectedData.id) {
// 무한루프 방지
$partNameSelect.data('syncing', true);
// 품명 셀렉트박스에 옵션이 없으면 추가
if($partNameSelect.find("option[value='" + selectedData.id + "']").length === 0) {
var newOption = new Option(selectedData.partName, selectedData.id, true, true);
$(newOption).data('partNo', selectedData.partNo);
$partNameSelect.append(newOption);
}
// 품명 셀렉트박스 값 설정
$partNameSelect.val(selectedData.id).trigger('change.select2');
// hidden 필드에 값 설정
var $row = $("#" + itemId);
$row.find(".item-part-objid").val(selectedData.id);
$row.find(".item-part-no").val(selectedData.partNo);
$row.find(".item-part-name").val(selectedData.partName);
console.log("품번 선택 후 hidden 필드 설정:", {
itemId: itemId,
partObjId: $row.find(".item-part-objid").val(),
partNo: $row.find(".item-part-no").val(),
partName: $row.find(".item-part-name").val()
});
setTimeout(function() {
$partNameSelect.data('syncing', false);
}, 100);
}
});
// 품번 선택 이벤트 (select2:select는 같은 값 재선택 시에도 발생)
$partNoSelect.off('select2:select').on('select2:select', function(e) {
var selectedData = e.params.data;
// 품명 변경 이벤트
$partNameSelect.off('change').on('change', function() {
if(selectedData && selectedData.id) {
// 무한루프 방지
if($(this).data('syncing')) return;
$partNameSelect.data('syncing', true);
var selectedData = $(this).select2('data')[0];
if(selectedData && selectedData.id) {
// 무한루프 방지
$partNoSelect.data('syncing', true);
// 품번 셀렉트박스에 옵션이 없으면 추가
if($partNoSelect.find("option[value='" + selectedData.id + "']").length === 0) {
var newOption = new Option(selectedData.partNo, selectedData.id, true, true);
$(newOption).data('partName', selectedData.partName);
$partNoSelect.append(newOption);
}
// 품번 셀렉트박스 값 설정
$partNoSelect.val(selectedData.id).trigger('change.select2');
// hidden 필드에 값 설정
var $row = $("#" + itemId);
$row.find(".item-part-objid").val(selectedData.id);
$row.find(".item-part-no").val(selectedData.partNo);
$row.find(".item-part-name").val(selectedData.partName);
console.log("품명 선택 후 hidden 필드 설정:", {
itemId: itemId,
partObjId: $row.find(".item-part-objid").val(),
partNo: $row.find(".item-part-no").val(),
partName: $row.find(".item-part-name").val()
});
setTimeout(function() {
$partNoSelect.data('syncing', false);
}, 100);
// 품명 셀렉트박스에 옵션이 없으면 추가
if($partNameSelect.find("option[value='" + selectedData.id + "']").length === 0) {
var newOption = new Option(selectedData.partName, selectedData.id, true, true);
$(newOption).data('partNo', selectedData.partNo);
$partNameSelect.append(newOption);
}
});
// 품명 셀렉트박스 값 설정
$partNameSelect.val(selectedData.id).trigger('change.select2');
// hidden 필드에 값 설정
var $row = $("#" + itemId);
$row.find(".item-part-objid").val(selectedData.id);
$row.find(".item-part-no").val(selectedData.partNo);
$row.find(".item-part-name").val(selectedData.partName);
console.log("품번 선택 후 hidden 필드 설정:", {
itemId: itemId,
partObjId: $row.find(".item-part-objid").val(),
partNo: $row.find(".item-part-no").val(),
partName: $row.find(".item-part-name").val()
});
setTimeout(function() {
$partNameSelect.data('syncing', false);
}, 100);
}
});
// 품명 선택 이벤트 (select2:select는 같은 값 재선택 시에도 발생)
$partNameSelect.off('select2:select').on('select2:select', function(e) {
// 무한루프 방지
if($(this).data('syncing')) return;
var selectedData = e.params.data;
if(selectedData && selectedData.id) {
// 무한루프 방지
$partNoSelect.data('syncing', true);
// 품번 셀렉트박스에 옵션이 없으면 추가
if($partNoSelect.find("option[value='" + selectedData.id + "']").length === 0) {
var newOption = new Option(selectedData.partNo, selectedData.id, true, true);
$(newOption).data('partName', selectedData.partName);
$partNoSelect.append(newOption);
}
// 품번 셀렉트박스 값 설정
$partNoSelect.val(selectedData.id).trigger('change.select2');
// hidden 필드에 값 설정
var $row = $("#" + itemId);
$row.find(".item-part-objid").val(selectedData.id);
$row.find(".item-part-no").val(selectedData.partNo);
$row.find(".item-part-name").val(selectedData.partName);
console.log("품명 선택 후 hidden 필드 설정:", {
itemId: itemId,
partObjId: $row.find(".item-part-objid").val(),
partNo: $row.find(".item-part-no").val(),
partName: $row.find(".item-part-name").val()
});
setTimeout(function() {
$partNoSelect.data('syncing', false);
}, 100);
}
});
// 기존 선택값이 있으면 로드 (수정 모드)
console.log("기존 데이터 로드 체크:", {objId: selectedObjId, partNo: savedPartNo, partName: savedPartName});

View File

@@ -561,20 +561,23 @@ function fn_initItemDescSelect(itemId) {
}
});
// 품명 선택 시 hidden 필드와 규격 자동 입력
$("#" + itemId + " .item-desc-select").on('change', function() {
var selectedData = $(this).select2('data')[0];
// 품명 선택 시 hidden 필드와 규격 자동 입력 (select2:select는 같은 값 재선택 시에도 발생)
$("#" + itemId + " .item-desc-select").on('select2:select', function(e) {
var selectedData = e.params.data;
if(selectedData) {
$("#" + itemId + " .item-desc").val(selectedData.text);
$("#" + itemId + " .item-part-objid").val(selectedData.id); // part_objid 저장
if(selectedData.spec) {
$("#" + itemId + " .item-spec").val(selectedData.spec);
}
} else {
$("#" + itemId + " .item-desc").val('');
$("#" + itemId + " .item-part-objid").val(''); // part_objid 초기화
}
});
// 품명 선택 해제 시 (X 버튼 클릭)
$("#" + itemId + " .item-desc-select").on('select2:clear', function() {
$("#" + itemId + " .item-desc").val('');
$("#" + itemId + " .item-part-objid").val(''); // part_objid 초기화
});
}
// 행 추가 함수
@@ -650,32 +653,36 @@ function fn_loadData() {
$("#contact_person").val(data.estimate.CONTACT_PERSON || "");
$("#greeting_text").val(data.estimate.GREETING_TEXT || "견적을 요청해 주셔서 대단히 감사합니다.\n하기와 같이 견적서를 제출합니다.");
// 담당자/연락처는 저장된 값이 있을 때만 덮어씀
var managerName = data.estimate.MANAGER_NAME || "";
var managerContact = data.estimate.MANAGER_CONTACT || "";
if(managerName && managerName !== "" && managerName !== "영업부") {
$("#manager_name").val(managerName);
}
if(managerContact && managerContact !== "") {
$("#manager_contact").val(managerContact);
}
// 담당자/연락처는 저장된 값이 있을 때만 덮어씀
var managerName = data.estimate.MANAGER_NAME || "";
var managerContact = data.estimate.MANAGER_CONTACT || "";
if(managerName && managerName !== "" && managerName !== "영업부") {
$("#manager_name").val(managerName);
}
if(managerContact && managerContact !== "") {
$("#manager_contact").val(managerContact);
}
// 품목 데이터 로드
/* 품목 데이터 로드 - 주석처리 (새로 작성 시 빈 템플릿 사용)
if(data.items && data.items.length > 0) {
// 기존 행 초기화 후 데이터 추가
var itemsHtml = "";
for(var i = 0; i < data.items.length; i++) {
var item = data.items[i];
var itemId = 'loaded_item_' + i;
itemsHtml += '<tr id="' + itemId + '">';
itemsHtml += '<td>' + (i + 1) + '</td>';
itemsHtml += '<td class="text-left editable">';
itemsHtml += '<select class="item-desc-select" style="width:100%;">';
itemsHtml += '<option value="" selected>' + (item.DESCRIPTION || '') + '</option>';
itemsHtml += '</select>';
itemsHtml += '<input type="hidden" class="item-desc" value="' + (item.DESCRIPTION || '') + '">';
itemsHtml += '<input type="hidden" class="item-part-objid" value="' + (item.PART_OBJID || item.part_objid || '') + '">';
itemsHtml += '</td>';
itemsHtml += '<tr id="' + itemId + '">';
itemsHtml += '<td>' + (i + 1) + '</td>';
itemsHtml += '<td class="text-left editable">';
itemsHtml += '<select class="item-desc-select" style="width:100%;">';
// PART_OBJID가 없으면 기존 텍스트를 옵션으로 표시
var description = item.DESCRIPTION || '';
if(description) {
itemsHtml += '<option value="" selected>' + description + '</option>';
}
itemsHtml += '</select>';
itemsHtml += '<input type="hidden" class="item-desc" value="' + description + '">';
itemsHtml += '<input type="hidden" class="item-part-objid" value="' + (item.PART_OBJID || item.part_objid || '') + '">';
itemsHtml += '</td>';
itemsHtml += '<td class="text-left editable"><textarea class="item-spec">' + (item.SPECIFICATION || '') + '</textarea></td>';
itemsHtml += '<td class="editable"><input type="text" class="item-qty" value="' + (item.QUANTITY || '') + '"></td>';
itemsHtml += '<td class="editable"><input type="text" class="item-unit" value="' + (item.UNIT || 'EA') + '"></td>';
@@ -758,6 +765,14 @@ function fn_loadData() {
// 합계 계산
fn_calculateTotal();
}
*/ // 품목 데이터 로드 주석처리 끝
// 새로 작성 시 기본 행의 셀렉트박스 초기화
fn_initItemDescSelect('default_item_1');
fn_initItemDescSelect('default_item_2');
// 초기 로드 시 합계 계산
fn_calculateTotal();
// 하단 비고 로드
$("#note1").val(data.estimate.NOTE1 || "1. 견적유효기간: 일");
@@ -874,13 +889,18 @@ function fn_loadTemplateData(templateObjId){
var unitPriceFormatted = unitPrice ? addComma(unitPrice) : '';
var amountFormatted = amount ? addComma(amount) : '';
itemsHtml += '<tr id="' + itemId + '">';
itemsHtml += '<td>' + (i + 1) + '</td>';
itemsHtml += '<td class="text-left editable">';
itemsHtml += '<select class="item-desc-select" style="width:100%;"></select>';
itemsHtml += '<input type="hidden" class="item-desc" value="' + description + '">';
itemsHtml += '<input type="hidden" class="item-part-objid" value="' + partObjId + '">';
itemsHtml += '</td>';
itemsHtml += '<tr id="' + itemId + '">';
itemsHtml += '<td>' + (i + 1) + '</td>';
itemsHtml += '<td class="text-left editable">';
itemsHtml += '<select class="item-desc-select" style="width:100%;">';
// PART_OBJID가 없으면 기존 텍스트를 옵션으로 표시
if(description) {
itemsHtml += '<option value="" selected>' + description + '</option>';
}
itemsHtml += '</select>';
itemsHtml += '<input type="hidden" class="item-desc" value="' + description + '">';
itemsHtml += '<input type="hidden" class="item-part-objid" value="' + partObjId + '">';
itemsHtml += '</td>';
itemsHtml += '<td class="text-left editable"><textarea class="item-spec">' + specification + '</textarea></td>';
itemsHtml += '<td class="editable"><input type="text" class="item-qty" value="' + quantity + '"></td>';
itemsHtml += '<td class="editable"><input type="text" class="item-unit" value="' + unit + '"></td>';

View File

@@ -3379,10 +3379,10 @@ function initPartSelect2Ajax(partNoSelectId, partNameSelectId, partObjIdInputId,
}
});
// 품번 변경 이벤트 핸들러
var partNoChangeHandler = function() {
var selectedData = $(this).select2('data')[0];
if(debug) console.log("품번 변경됨:", selectedData);
// 품번 선택 이벤트 핸들러 (select2:select는 같은 값 재선택 시에도 발생)
var partNoSelectHandler = function(e) {
var selectedData = e.params.data;
if(debug) console.log("품번 선택됨:", selectedData);
if(selectedData && selectedData.objId) {
if(debug) console.log("품목 OBJID 설정:", selectedData.objId);
@@ -3390,7 +3390,7 @@ function initPartSelect2Ajax(partNoSelectId, partNameSelectId, partObjIdInputId,
// 품명 셀렉트박스도 동기화
var $partNameSelect = $(partNameSelectId);
$partNameSelect.off('change');
$partNameSelect.off('select2:select');
if($partNameSelect.find("option[value='" + selectedData.partName + "']").length === 0) {
var newOption = new Option(selectedData.partName, selectedData.partName, true, true);
$partNameSelect.append(newOption);
@@ -3400,17 +3400,21 @@ function initPartSelect2Ajax(partNoSelectId, partNameSelectId, partObjIdInputId,
$partNameSelect.trigger('change.select2');
setTimeout(function() {
$partNameSelect.on('change', partNameChangeHandler);
$partNameSelect.on('select2:select', partNameSelectHandler);
}, 100);
} else {
$(partObjIdInputId).val("");
}
};
// 품명 변경 이벤트 핸들러
var partNameChangeHandler = function() {
var selectedData = $(this).select2('data')[0];
if(debug) console.log("품명 변경됨:", selectedData);
// 품번 선택 해제 이벤트
var partNoClearHandler = function() {
$(partObjIdInputId).val("");
$(partNameSelectId).val(null).trigger('change');
};
// 품명 선택 이벤트 핸들러 (select2:select는 같은 값 재선택 시에도 발생)
var partNameSelectHandler = function(e) {
var selectedData = e.params.data;
if(debug) console.log("품명 선택됨:", selectedData);
if(selectedData && selectedData.objId) {
if(debug) console.log("품목 OBJID 설정:", selectedData.objId);
@@ -3418,7 +3422,7 @@ function initPartSelect2Ajax(partNoSelectId, partNameSelectId, partObjIdInputId,
// 품번 셀렉트박스도 동기화
var $partNoSelect = $(partNoSelectId);
$partNoSelect.off('change');
$partNoSelect.off('select2:select');
if($partNoSelect.find("option[value='" + selectedData.partNo + "']").length === 0) {
var newOption = new Option(selectedData.partNo, selectedData.partNo, true, true);
$partNoSelect.append(newOption);
@@ -3428,14 +3432,20 @@ function initPartSelect2Ajax(partNoSelectId, partNameSelectId, partObjIdInputId,
$partNoSelect.trigger('change.select2');
setTimeout(function() {
$partNoSelect.on('change', partNoChangeHandler);
$partNoSelect.on('select2:select', partNoSelectHandler);
}, 100);
} else {
$(partObjIdInputId).val("");
}
};
// 품명 선택 해제 이벤트
var partNameClearHandler = function() {
$(partObjIdInputId).val("");
$(partNoSelectId).val(null).trigger('change');
};
// 이벤트 연결
$(partNoSelectId).on('change', partNoChangeHandler);
$(partNameSelectId).on('change', partNameChangeHandler);
$(partNoSelectId).on('select2:select', partNoSelectHandler);
$(partNoSelectId).on('select2:clear', partNoClearHandler);
$(partNameSelectId).on('select2:select', partNameSelectHandler);
$(partNameSelectId).on('select2:clear', partNameClearHandler);
}

View File

@@ -1868,11 +1868,11 @@ public class ContractMgmtController {
estimate = contractMgmtService.getEstimateTemplateByObjId(paramMap);
items = contractMgmtService.getEstimateTemplateItemsByTemplateObjId(paramMap);
}
// objId만 있으면 CONTRACT 정보로 견적서 신규 작성
else if(!"".equals(objId) && !"-1".equals(objId)){
estimate = contractMgmtService.getEstimateTemplateInfo(paramMap);
items = contractMgmtService.getEstimateTemplateItems(paramMap);
}
// objId만 있으면 CONTRACT 정보로 견적서 신규 작성
else if(!"".equals(objId) && !"-1".equals(objId)){
estimate = contractMgmtService.getEstimateTemplateInfo(paramMap);
// items = contractMgmtService.getEstimateTemplateItems(paramMap); // 주석처리: 새로 작성 시 빈 템플릿 사용
}
// 고객사 코드맵 추가
String customer_cd = "";