fix: 조제 관리 약재 추가 시 마스터 약재명 표시 및 2단계 선택 구조 개선
- 약재 추가 드롭다운에서 제품명 대신 마스터 약재명 표시 - /api/herbs/masters 엔드포인트 사용하여 ingredient_code 기반 약재 목록 로드 - /api/herbs/by-ingredient/<code> 엔드포인트 추가 (제품 목록 조회) - 2단계 선택 구조: 약재(마스터) → 제품 → 원산지/롯트 - 기존 처방 약재와 새로 추가하는 약재의 테이블 구조 통일 (6칼럼) - 원산지 선택 칼럼에 제품/원산지 드롭다운 함께 표시 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
bfc5c992de
commit
a4861dc1b8
34
app.py
34
app.py
@ -255,6 +255,40 @@ def get_herb_masters():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return jsonify({'success': False, 'error': str(e)}), 500
|
return jsonify({'success': False, 'error': str(e)}), 500
|
||||||
|
|
||||||
|
@app.route('/api/herbs/by-ingredient/<ingredient_code>', methods=['GET'])
|
||||||
|
def get_herbs_by_ingredient(ingredient_code):
|
||||||
|
"""특정 ingredient_code에 해당하는 제품 목록 조회"""
|
||||||
|
try:
|
||||||
|
with get_db() as conn:
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT
|
||||||
|
h.herb_item_id,
|
||||||
|
h.insurance_code,
|
||||||
|
h.herb_name,
|
||||||
|
h.specification,
|
||||||
|
CASE
|
||||||
|
WHEN h.specification LIKE '%신흥%' THEN '신흥'
|
||||||
|
WHEN h.specification LIKE '%한동%' THEN '한동'
|
||||||
|
ELSE COALESCE(h.specification, '기타')
|
||||||
|
END as company_name,
|
||||||
|
COALESCE(SUM(il.quantity_onhand), 0) as stock_quantity,
|
||||||
|
COUNT(DISTINCT il.lot_id) as lot_count,
|
||||||
|
AVG(il.unit_price_per_g) as avg_price
|
||||||
|
FROM herb_items h
|
||||||
|
LEFT JOIN inventory_lots il ON h.herb_item_id = il.herb_item_id
|
||||||
|
AND il.is_depleted = 0
|
||||||
|
WHERE h.ingredient_code = ?
|
||||||
|
AND h.is_active = 1
|
||||||
|
GROUP BY h.herb_item_id
|
||||||
|
ORDER BY stock_quantity DESC, h.herb_name
|
||||||
|
""", (ingredient_code,))
|
||||||
|
|
||||||
|
products = [dict(row) for row in cursor.fetchall()]
|
||||||
|
return jsonify({'success': True, 'data': products})
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'success': False, 'error': str(e)}), 500
|
||||||
|
|
||||||
# ==================== 처방 관리 API ====================
|
# ==================== 처방 관리 API ====================
|
||||||
|
|
||||||
@app.route('/api/formulas', methods=['GET'])
|
@app.route('/api/formulas', methods=['GET'])
|
||||||
|
|||||||
112
static/app.js
112
static/app.js
@ -617,15 +617,15 @@ $(document).ready(function() {
|
|||||||
value="${ing.grams_per_cheop}" min="0.1" step="0.1">
|
value="${ing.grams_per_cheop}" min="0.1" step="0.1">
|
||||||
</td>
|
</td>
|
||||||
<td class="total-grams">${totalGrams.toFixed(1)}</td>
|
<td class="total-grams">${totalGrams.toFixed(1)}</td>
|
||||||
<td class="product-select-cell">
|
|
||||||
<select class="form-control form-control-sm product-select" ${ing.available_products.length === 0 ? 'disabled' : ''}>
|
|
||||||
${productOptions}
|
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
<td class="origin-select-cell">
|
<td class="origin-select-cell">
|
||||||
<select class="form-control form-control-sm origin-select" disabled>
|
<div class="d-flex gap-1">
|
||||||
<option value="">제품 먼저 선택</option>
|
<select class="form-control form-control-sm product-select" style="flex: 1;" ${ing.available_products.length === 0 ? 'disabled' : ''}>
|
||||||
</select>
|
${productOptions}
|
||||||
|
</select>
|
||||||
|
<select class="form-control form-control-sm origin-select" style="flex: 1;" disabled>
|
||||||
|
<option value="">제품 먼저 선택</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="stock-status">대기중</td>
|
<td class="stock-status">대기중</td>
|
||||||
<td>
|
<td>
|
||||||
@ -722,7 +722,7 @@ $(document).ready(function() {
|
|||||||
// 빈 약재 행 추가 함수
|
// 빈 약재 행 추가 함수
|
||||||
function addEmptyIngredientRow() {
|
function addEmptyIngredientRow() {
|
||||||
const newRow = $(`
|
const newRow = $(`
|
||||||
<tr>
|
<tr data-ingredient-code="" data-herb-id="">
|
||||||
<td>
|
<td>
|
||||||
<select class="form-control form-control-sm herb-select-compound">
|
<select class="form-control form-control-sm herb-select-compound">
|
||||||
<option value="">약재 선택</option>
|
<option value="">약재 선택</option>
|
||||||
@ -734,9 +734,14 @@ $(document).ready(function() {
|
|||||||
</td>
|
</td>
|
||||||
<td class="total-grams">0.0</td>
|
<td class="total-grams">0.0</td>
|
||||||
<td class="origin-select-cell">
|
<td class="origin-select-cell">
|
||||||
<select class="form-control form-control-sm origin-select" disabled>
|
<div class="d-flex gap-1">
|
||||||
<option value="">약재 선택 후 표시</option>
|
<select class="form-control form-control-sm product-select" style="flex: 1;" disabled>
|
||||||
</select>
|
<option value="">약재 선택 후 표시</option>
|
||||||
|
</select>
|
||||||
|
<select class="form-control form-control-sm origin-select" style="flex: 1;" disabled>
|
||||||
|
<option value="">제품 선택 후 표시</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="stock-status">-</td>
|
<td class="stock-status">-</td>
|
||||||
<td>
|
<td>
|
||||||
@ -750,18 +755,53 @@ $(document).ready(function() {
|
|||||||
$('#compoundIngredients').append(newRow);
|
$('#compoundIngredients').append(newRow);
|
||||||
|
|
||||||
// 약재 목록 로드
|
// 약재 목록 로드
|
||||||
loadHerbsForSelect(newRow.find('.herb-select-compound'));
|
const herbSelect = newRow.find('.herb-select-compound');
|
||||||
|
loadHerbsForSelect(herbSelect);
|
||||||
|
|
||||||
// 약재 선택 시 원산지 옵션 로드
|
// 약재(마스터) 선택 시 제품 옵션 로드
|
||||||
newRow.find('.herb-select-compound').on('change', function() {
|
newRow.find('.herb-select-compound').on('change', function() {
|
||||||
const herbId = $(this).val();
|
const ingredientCode = $(this).val();
|
||||||
if (herbId) {
|
const herbName = $(this).find('option:selected').data('herb-name');
|
||||||
|
if (ingredientCode) {
|
||||||
const row = $(this).closest('tr');
|
const row = $(this).closest('tr');
|
||||||
|
row.attr('data-ingredient-code', ingredientCode);
|
||||||
|
|
||||||
|
// 제품 목록 로드
|
||||||
|
loadProductOptions(row, ingredientCode, herbName);
|
||||||
|
|
||||||
|
// 제품 선택 활성화
|
||||||
|
row.find('.product-select').prop('disabled', false);
|
||||||
|
|
||||||
|
// 원산지 선택 초기화 및 비활성화
|
||||||
|
row.find('.origin-select').empty().append('<option value="">제품 선택 후 표시</option>').prop('disabled', true);
|
||||||
|
} else {
|
||||||
|
const row = $(this).closest('tr');
|
||||||
|
row.attr('data-ingredient-code', '');
|
||||||
|
row.attr('data-herb-id', '');
|
||||||
|
row.find('.product-select').empty().append('<option value="">약재 선택 후 표시</option>').prop('disabled', true);
|
||||||
|
row.find('.origin-select').empty().append('<option value="">제품 선택 후 표시</option>').prop('disabled', true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 제품 선택 이벤트
|
||||||
|
newRow.find('.product-select').on('change', function() {
|
||||||
|
const herbId = $(this).val();
|
||||||
|
const row = $(this).closest('tr');
|
||||||
|
|
||||||
|
if (herbId) {
|
||||||
row.attr('data-herb-id', herbId);
|
row.attr('data-herb-id', herbId);
|
||||||
|
|
||||||
|
// 원산지 선택 활성화
|
||||||
|
row.find('.origin-select').prop('disabled', false);
|
||||||
|
|
||||||
|
// 원산지 옵션 로드
|
||||||
const cheopTotal = parseFloat($('#cheopTotal').val()) || 0;
|
const cheopTotal = parseFloat($('#cheopTotal').val()) || 0;
|
||||||
const gramsPerCheop = parseFloat(row.find('.grams-per-cheop').val()) || 0;
|
const gramsPerCheop = parseFloat(row.find('.grams-per-cheop').val()) || 0;
|
||||||
const totalGrams = gramsPerCheop * cheopTotal;
|
const totalGrams = gramsPerCheop * cheopTotal;
|
||||||
loadOriginOptions(herbId, totalGrams);
|
loadOriginOptions(herbId, totalGrams);
|
||||||
|
} else {
|
||||||
|
row.attr('data-herb-id', '');
|
||||||
|
row.find('.origin-select').empty().append('<option value="">제품 선택 후 표시</option>').prop('disabled', true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1599,14 +1639,48 @@ $(document).ready(function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadHerbsForSelect(selectElement) {
|
function loadHerbsForSelect(selectElement) {
|
||||||
$.get('/api/herbs', function(response) {
|
$.get('/api/herbs/masters', function(response) {
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
selectElement.empty().append('<option value="">약재 선택</option>');
|
selectElement.empty().append('<option value="">약재 선택</option>');
|
||||||
|
|
||||||
response.data.forEach(herb => {
|
// 재고가 있는 약재만 필터링하여 표시
|
||||||
selectElement.append(`<option value="${herb.herb_item_id}">${herb.herb_name}</option>`);
|
const herbsWithStock = response.data.filter(herb => herb.has_stock === 1);
|
||||||
|
|
||||||
|
herbsWithStock.forEach(herb => {
|
||||||
|
// ingredient_code를 value로 사용하고, 한글명(한자명) 형식으로 표시
|
||||||
|
let displayName = herb.herb_name;
|
||||||
|
if (herb.herb_name_hanja) {
|
||||||
|
displayName += ` (${herb.herb_name_hanja})`;
|
||||||
|
}
|
||||||
|
selectElement.append(`<option value="${herb.ingredient_code}" data-herb-name="${herb.herb_name}">${displayName}</option>`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}).fail(function(error) {
|
||||||
|
console.error('Failed to load herbs:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ingredient_code 기반으로 제품 옵션 로드
|
||||||
|
function loadProductOptions(row, ingredientCode, herbName) {
|
||||||
|
$.get(`/api/herbs/by-ingredient/${ingredientCode}`, function(response) {
|
||||||
|
if (response.success) {
|
||||||
|
const productSelect = row.find('.product-select');
|
||||||
|
productSelect.empty();
|
||||||
|
|
||||||
|
if (response.data.length === 0) {
|
||||||
|
productSelect.append('<option value="">재고 없음</option>');
|
||||||
|
productSelect.prop('disabled', true);
|
||||||
|
} else {
|
||||||
|
productSelect.append('<option value="">제품 선택</option>');
|
||||||
|
response.data.forEach(product => {
|
||||||
|
const stockInfo = product.stock_quantity > 0 ? `(재고: ${product.stock_quantity.toFixed(1)}g)` : '(재고 없음)';
|
||||||
|
productSelect.append(`<option value="${product.herb_item_id}" ${product.stock_quantity === 0 ? 'disabled' : ''}>${product.company_name} ${stockInfo}</option>`);
|
||||||
|
});
|
||||||
|
productSelect.prop('disabled', false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).fail(function() {
|
||||||
|
console.error(`Failed to load products for ingredient code: ${ingredientCode}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -35,6 +35,14 @@ def test_compound_ginseng_selection():
|
|||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
print("✓ 조제관리 화면 진입")
|
print("✓ 조제관리 화면 진입")
|
||||||
|
|
||||||
|
# 조제 입력 섹션 표시
|
||||||
|
print("\n[2-1] 조제 입력 섹션 표시...")
|
||||||
|
show_compound_entry = page.locator('#showCompoundEntry')
|
||||||
|
if show_compound_entry.count() > 0:
|
||||||
|
show_compound_entry.click()
|
||||||
|
time.sleep(1)
|
||||||
|
print("✓ 조제 입력 섹션 표시")
|
||||||
|
|
||||||
# 3. 현재 화면 상태 확인
|
# 3. 현재 화면 상태 확인
|
||||||
print("\n[3] 화면 상태 확인...")
|
print("\n[3] 화면 상태 확인...")
|
||||||
|
|
||||||
@ -54,10 +62,16 @@ def test_compound_ginseng_selection():
|
|||||||
# 처방 선택 시도
|
# 처방 선택 시도
|
||||||
print("\n[4] 처방 선택...")
|
print("\n[4] 처방 선택...")
|
||||||
|
|
||||||
# 처방 드롭다운 찾기 (유연하게)
|
# compoundFormula select 요소 찾기 (ID로 정확히)
|
||||||
formula_select = page.locator('select').first
|
formula_select = page.locator('#compoundFormula')
|
||||||
|
|
||||||
if formula_select.count() > 0:
|
if formula_select.count() > 0:
|
||||||
|
# select가 visible 될 때까지 기다리기
|
||||||
|
try:
|
||||||
|
formula_select.wait_for(state="visible", timeout=5000)
|
||||||
|
except:
|
||||||
|
print("⚠️ 처방 선택 드롭다운이 보이지 않음")
|
||||||
|
|
||||||
# 옵션 확인
|
# 옵션 확인
|
||||||
options = formula_select.locator('option').all()
|
options = formula_select.locator('option').all()
|
||||||
print(f"✓ 드롭다운 옵션: {len(options)}개")
|
print(f"✓ 드롭다운 옵션: {len(options)}개")
|
||||||
@ -71,72 +85,93 @@ def test_compound_ginseng_selection():
|
|||||||
print("✓ 쌍화탕 선택 완료")
|
print("✓ 쌍화탕 선택 완료")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"⚠️ label로 선택 실패: {e}")
|
print(f"⚠️ label로 선택 실패: {e}")
|
||||||
# index로 시도
|
# index로 시도 (첫 번째 옵션은 보통 placeholder이므로 index=1)
|
||||||
formula_select.select_option(index=1)
|
try:
|
||||||
time.sleep(3)
|
formula_select.select_option(index=1)
|
||||||
print("✓ 첫 번째 처방 선택 완료")
|
time.sleep(3)
|
||||||
|
print("✓ 첫 번째 처방 선택 완료")
|
||||||
|
except Exception as e2:
|
||||||
|
print(f"❌ 처방 선택 실패: {e2}")
|
||||||
else:
|
else:
|
||||||
print("❌ 처방 드롭다운을 찾을 수 없음")
|
print("❌ 처방 드롭다운을 찾을 수 없음")
|
||||||
|
|
||||||
# 4. 약재 목록 확인
|
# 5. 약재 추가 버튼 클릭
|
||||||
print("\n[4] 약재 목록 확인...")
|
print("\n[5] 약재 추가 버튼 클릭...")
|
||||||
|
|
||||||
# 약재 테이블이나 목록이 나타날 때까지 대기
|
# 약재 추가 버튼 찾기
|
||||||
page.wait_for_selector('table, .ingredient-list', timeout=10000)
|
add_ingredient_btn = page.locator('#addIngredientBtn')
|
||||||
|
|
||||||
# 페이지 스크린샷
|
if add_ingredient_btn.count() > 0:
|
||||||
page.screenshot(path='/tmp/compound_screen_1.png')
|
add_ingredient_btn.click()
|
||||||
print("✓ 스크린샷 저장: /tmp/compound_screen_1.png")
|
time.sleep(1)
|
||||||
|
print("✓ 약재 추가 버튼 클릭 완료")
|
||||||
|
|
||||||
# 5. 인삼 항목 찾기
|
# 6. 새로 추가된 행에서 약재 선택 드롭다운 확인
|
||||||
print("\n[5] 인삼 항목 찾기...")
|
print("\n[6] 약재 선택 드롭다운 확인...")
|
||||||
|
|
||||||
# 인삼을 포함하는 행 찾기
|
# 새로 추가된 행 찾기 (마지막 행)
|
||||||
ginseng_row = page.locator('tr:has-text("인삼"), div:has-text("인삼")').first
|
new_row = page.locator('#compoundIngredients tr').last
|
||||||
|
|
||||||
if ginseng_row.count() > 0:
|
# 약재 선택 드롭다운 찾기
|
||||||
print("✓ 인삼 항목 발견")
|
herb_select = new_row.locator('.herb-select-compound')
|
||||||
|
|
||||||
# 6. 제품 선택 드롭다운 확인
|
if herb_select.count() > 0:
|
||||||
print("\n[6] 제품 선택 드롭다운 확인...")
|
print("✓ 약재 선택 드롭다운 발견")
|
||||||
|
|
||||||
# 인삼 행에서 select 요소 찾기
|
# 드롭다운 옵션 확인
|
||||||
product_select = ginseng_row.locator('select').first
|
time.sleep(1) # 드롭다운이 로드될 시간 확보
|
||||||
|
options = herb_select.locator('option').all()
|
||||||
|
print(f"✓ 약재 옵션: {len(options)}개")
|
||||||
|
|
||||||
if product_select.count() > 0:
|
# 처음 10개 옵션 출력
|
||||||
print("✓ 제품 선택 드롭다운 발견")
|
for idx, option in enumerate(options[:10]):
|
||||||
|
|
||||||
# 옵션 개수 확인
|
|
||||||
options = product_select.locator('option').all()
|
|
||||||
print(f"✓ 사용 가능한 제품: {len(options)}개")
|
|
||||||
|
|
||||||
# 각 옵션 출력
|
|
||||||
for idx, option in enumerate(options):
|
|
||||||
text = option.text_content()
|
text = option.text_content()
|
||||||
value = option.get_attribute('value')
|
value = option.get_attribute('value')
|
||||||
print(f" [{idx}] {text} (value: {value})")
|
print(f" [{idx}] {text} (value: {value})")
|
||||||
|
|
||||||
# 신흥인삼 또는 세화인삼 선택 가능한지 확인
|
# 마스터 약재명이 표시되는지 확인
|
||||||
has_shinheung = any('신흥인삼' in opt.text_content() for opt in options)
|
has_master_names = False
|
||||||
has_sehwa = any('세화인삼' in opt.text_content() for opt in options)
|
for option in options:
|
||||||
|
text = option.text_content()
|
||||||
|
# ingredient_code 형식의 value와 한글/한자 형식의 텍스트 확인
|
||||||
|
if '(' in text and ')' in text: # 한자 포함 형식
|
||||||
|
has_master_names = True
|
||||||
|
break
|
||||||
|
|
||||||
if has_shinheung or has_sehwa:
|
if has_master_names:
|
||||||
print("\n✅ 인삼 제품 선택 가능!")
|
print("\n✅ 마스터 약재명이 드롭다운에 표시됨!")
|
||||||
|
|
||||||
# 첫 번째 제품 선택 시도
|
# 인삼 선택 시도
|
||||||
if len(options) > 0:
|
try:
|
||||||
product_select.select_option(index=0)
|
herb_select.select_option(label='인삼 (人蔘)')
|
||||||
print(f"✓ '{options[0].text_content()}' 선택 완료")
|
print("✓ 인삼 선택 완료")
|
||||||
|
except:
|
||||||
|
# label이 정확히 일치하지 않으면 부분 매칭
|
||||||
|
for idx, option in enumerate(options):
|
||||||
|
if '인삼' in option.text_content():
|
||||||
|
herb_select.select_option(index=idx)
|
||||||
|
print(f"✓ 인삼 선택 완료 (index {idx})")
|
||||||
|
break
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
# 제품 선택 드롭다운 확인
|
||||||
|
product_select = new_row.locator('.product-select')
|
||||||
|
if product_select.count() > 0:
|
||||||
|
print("\n[7] 제품 선택 드롭다운 확인...")
|
||||||
|
time.sleep(1) # 제품 목록 로드 대기
|
||||||
|
|
||||||
|
product_options = product_select.locator('option').all()
|
||||||
|
print(f"✓ 제품 옵션: {len(product_options)}개")
|
||||||
|
for idx, option in enumerate(product_options):
|
||||||
|
print(f" [{idx}] {option.text_content()}")
|
||||||
else:
|
else:
|
||||||
print("\n❌ 인삼 대체 제품이 드롭다운에 없음")
|
print("\n⚠️ 마스터 약재명 대신 제품명이 드롭다운에 표시됨")
|
||||||
|
print("(신흥생강, 신흥작약 등의 제품명이 보임)")
|
||||||
else:
|
else:
|
||||||
print("❌ 제품 선택 드롭다운을 찾을 수 없음")
|
print("❌ 약재 선택 드롭다운을 찾을 수 없음")
|
||||||
print("페이지 HTML 일부:")
|
|
||||||
print(ginseng_row.inner_html()[:500])
|
|
||||||
else:
|
else:
|
||||||
print("❌ 인삼 항목을 찾을 수 없음")
|
print("❌ 약재 추가 버튼을 찾을 수 없음")
|
||||||
print("\n페이지 내용:")
|
|
||||||
print(page.content()[:2000])
|
|
||||||
|
|
||||||
# 7. 최종 스크린샷
|
# 7. 최종 스크린샷
|
||||||
page.screenshot(path='/tmp/compound_screen_final.png')
|
page.screenshot(path='/tmp/compound_screen_final.png')
|
||||||
|
|||||||
43
test_herb_select.html
Normal file
43
test_herb_select.html
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>약재 선택 테스트</title>
|
||||||
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>약재 선택 드롭다운 테스트</h1>
|
||||||
|
|
||||||
|
<div id="test-area"></div>
|
||||||
|
|
||||||
|
<button id="add-row">행 추가</button>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$('#add-row').click(function() {
|
||||||
|
// API 호출하여 약재 목록 가져오기
|
||||||
|
$.get('http://localhost:5001/api/herbs/masters', function(response) {
|
||||||
|
console.log('API Response:', response);
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
const select = $('<select></select>');
|
||||||
|
select.append('<option value="">약재 선택</option>');
|
||||||
|
|
||||||
|
// 재고가 있는 약재만 필터링
|
||||||
|
const herbsWithStock = response.data.filter(herb => herb.has_stock === 1);
|
||||||
|
console.log('Herbs with stock:', herbsWithStock.length);
|
||||||
|
|
||||||
|
herbsWithStock.forEach(herb => {
|
||||||
|
let displayName = herb.herb_name;
|
||||||
|
if (herb.herb_name_hanja) {
|
||||||
|
displayName += ` (${herb.herb_name_hanja})`;
|
||||||
|
}
|
||||||
|
select.append(`<option value="${herb.ingredient_code}">${displayName}</option>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#test-area').append(select);
|
||||||
|
$('#test-area').append('<br><br>');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Reference in New Issue
Block a user