|
|
@ -80,101 +80,54 @@ |
|
|
.config-actions button{min-width:140px;padding:10px 18px;font-size:16px;border:1px solid #bbb;background:#d9d9d9;border-radius:4px;cursor:pointer} |
|
|
.config-actions button{min-width:140px;padding:10px 18px;font-size:16px;border:1px solid #bbb;background:#d9d9d9;border-radius:4px;cursor:pointer} |
|
|
|
|
|
|
|
|
/* MODBUS 화면 심플 스타일 */ |
|
|
/* MODBUS 화면 심플 스타일 */ |
|
|
#page-modbus .card { |
|
|
#page-modbus .card {background: #f7f7f7;border: 1px solid #bbb;box-shadow: none;padding: 24px;border-radius: 4px;display: flex;flex-direction: column;} |
|
|
background: #f7f7f7; |
|
|
#page-modbus table {width: 100%;border-collapse: collapse;background: #fff;border: 1px solid #bbb;} |
|
|
border: 1px solid #bbb; |
|
|
#page-modbus th, #page-modbus td {border: 1px solid #bbb;padding: 6px 8px;text-align: left;background: #fff;} |
|
|
box-shadow: none; |
|
|
#page-modbus th {background: #e5e5e5;font-weight: 500;} |
|
|
padding: 24px; |
|
|
#page-modbus .modbus-input-area {display: grid;grid-template-columns: 200px 200px 200px 200px;gap: 20px 20px;margin: 24px auto 16px auto;background: #eaeaea;padding: 16px;border-radius: 4px;margin-left: auto;margin-right: auto;} |
|
|
border-radius: 4px; |
|
|
#page-modbus .input-row {display: contents;} |
|
|
display: flex; |
|
|
#page-modbus .modbus-input-area label.nowrap {white-space: nowrap;} |
|
|
flex-direction: column; |
|
|
#page-modbus .modbus-input-area label {min-width: auto;color: #444;white-space: normal;} |
|
|
} |
|
|
#page-modbus .modbus-input-area input {background: #e0e0e0;border: none;border-radius: 2px;padding: 4px 8px;min-width: auto;} |
|
|
#page-modbus table { |
|
|
#page-modbus .modbus-actions {display: flex;gap: 24px;justify-content: center;margin: 16px 0 0 0;} |
|
|
width: 100%; |
|
|
#page-modbus .modbus-actions button {background: #d3d3d3;border: 1px solid #aaa;border-radius: 2px;padding: 8px 24px;font-size: 16px;cursor: pointer;} |
|
|
border-collapse: collapse; |
|
|
|
|
|
background: #fff; |
|
|
|
|
|
border: 1px solid #bbb; |
|
|
|
|
|
} |
|
|
|
|
|
#page-modbus th, #page-modbus td { |
|
|
|
|
|
border: 1px solid #bbb; |
|
|
|
|
|
padding: 6px 8px; |
|
|
|
|
|
text-align: left; |
|
|
|
|
|
background: #fff; |
|
|
|
|
|
} |
|
|
|
|
|
#page-modbus th { |
|
|
|
|
|
background: #e5e5e5; |
|
|
|
|
|
font-weight: 500; |
|
|
|
|
|
} |
|
|
|
|
|
#page-modbus .modbus-input-area { |
|
|
|
|
|
display: grid; |
|
|
|
|
|
grid-template-columns: 200px 200px 200px 200px; |
|
|
|
|
|
gap: 20px 20px; |
|
|
|
|
|
margin: 24px auto 16px auto; |
|
|
|
|
|
background: #eaeaea; |
|
|
|
|
|
padding: 16px; |
|
|
|
|
|
border-radius: 4px; |
|
|
|
|
|
margin-left: auto; |
|
|
|
|
|
margin-right: auto; |
|
|
|
|
|
} |
|
|
|
|
|
#page-modbus .input-row { |
|
|
|
|
|
display: contents; |
|
|
|
|
|
} |
|
|
|
|
|
#page-modbus .modbus-input-area label.nowrap { |
|
|
|
|
|
white-space: nowrap; |
|
|
|
|
|
} |
|
|
|
|
|
#page-modbus .modbus-input-area label { |
|
|
|
|
|
min-width: auto; |
|
|
|
|
|
color: #444; |
|
|
|
|
|
white-space: normal; |
|
|
|
|
|
} |
|
|
|
|
|
#page-modbus .modbus-input-area input { |
|
|
|
|
|
background: #e0e0e0; |
|
|
|
|
|
border: none; |
|
|
|
|
|
border-radius: 2px; |
|
|
|
|
|
padding: 4px 8px; |
|
|
|
|
|
min-width: auto; |
|
|
|
|
|
} |
|
|
|
|
|
#page-modbus .modbus-actions { |
|
|
|
|
|
display: flex; |
|
|
|
|
|
gap: 24px; |
|
|
|
|
|
justify-content: center; |
|
|
|
|
|
margin: 16px 0 0 0; |
|
|
|
|
|
} |
|
|
|
|
|
#page-modbus .modbus-actions button { |
|
|
|
|
|
background: #d3d3d3; |
|
|
|
|
|
border: 1px solid #aaa; |
|
|
|
|
|
border-radius: 2px; |
|
|
|
|
|
padding: 8px 24px; |
|
|
|
|
|
font-size: 16px; |
|
|
|
|
|
cursor: pointer; |
|
|
|
|
|
} |
|
|
|
|
|
/* 하단 버튼 영역 */ |
|
|
/* 하단 버튼 영역 */ |
|
|
#modbus-bottom-actions { |
|
|
#modbus-bottom-actions {display: flex;gap: 24px;justify-content: center;background: #f7f7f7;border: 1px solid #bbb;border-radius: 4px;margin: 24px 0 0 0;padding: 20px 0;} |
|
|
display: flex; |
|
|
#modbus-bottom-actions button {background: #e0e0e0;border: 1px solid #aaa;border-radius: 2px;padding: 10px 18px;font-size: 16px;min-width: 140px;cursor: pointer;} |
|
|
gap: 24px; |
|
|
|
|
|
justify-content: center; |
|
|
/* OPC_UA 화면 */ |
|
|
background: #f7f7f7; |
|
|
#page-opcua .card {background: #f7f7f7;border: 1px solid #bbb;box-shadow: none;padding: 24px;border-radius: 4px;display: flex;flex-direction: column;} |
|
|
border: 1px solid #bbb; |
|
|
#page-opcua table {width: 100%;border-collapse: collapse;background: #fff;border: 1px solid #bbb;} |
|
|
border-radius: 4px; |
|
|
#page-opcua th, #page-opcua td {border: 1px solid #bbb;padding: 6px 8px;text-align: left;background: #fff;} |
|
|
margin: 24px 0 0 0; |
|
|
#page-opcua th {background: #e5e5e5;font-weight: 500;} |
|
|
padding: 20px 0; |
|
|
#page-opcua .opcua-input-area {display: grid;grid-template-columns: 200px 200px 200px 200px;gap: 20px 20px;margin: 24px auto 16px auto;background: #eaeaea;padding: 16px;border-radius: 4px;margin-left: auto;margin-right: auto;} |
|
|
} |
|
|
#page-opcua .input-row {display: contents;} |
|
|
#modbus-bottom-actions button { |
|
|
#page-opcua .opcua-input-area label.nowrap {white-space: nowrap;} |
|
|
background: #e0e0e0; |
|
|
#page-opcua .opcua-input-area label {min-width: auto;color: #444;white-space: normal;} |
|
|
border: 1px solid #aaa; |
|
|
#page-opcua .opcua-input-area input {background: #e0e0e0;border: none;border-radius: 2px;padding: 4px 8px;min-width: auto;} |
|
|
border-radius: 2px; |
|
|
#page-opcua .opcua-actions {display: flex;gap: 24px;justify-content: center;margin: 16px 0 0 0;} |
|
|
padding: 10px 18px; |
|
|
#page-opcua .opcua-actions button {background: #d3d3d3;border: 1px solid #aaa;border-radius: 2px;padding: 8px 24px;font-size: 16px;cursor: pointer;} |
|
|
font-size: 16px; |
|
|
#opcUa-bottom-actions {display: flex;gap: 24px;justify-content: center;background: #f7f7f7;border: 1px solid #bbb;border-radius: 4px;margin: 24px 0 0 0;padding: 20px 0;} |
|
|
min-width: 140px; |
|
|
#opcUa-bottom-actions button {background: #e0e0e0;border: 1px solid #aaa;border-radius: 2px;padding: 10px 18px;font-size: 16px;min-width: 140px;cursor: pointer;} |
|
|
cursor: pointer; |
|
|
|
|
|
} |
|
|
/* CAN 화면 스타일 */ |
|
|
|
|
|
#page-can .card {background: #f7f7f7; border: 1px solid #bbb; box-shadow: none; padding: 24px; border-radius: 4px; display: flex; flex-direction: column;} |
|
|
|
|
|
#page-can table {width: 100%; border-collapse: collapse; background: #fff; border: 1px solid #bbb;} |
|
|
|
|
|
#page-can th, #page-can td {border: 1px solid #bbb; padding: 6px 8px; text-align: left; background: #fff;} |
|
|
|
|
|
#page-can th {background: #e5e5e5; font-weight: 500;} |
|
|
|
|
|
#page-can .can-input-area {display: grid; grid-template-columns: 200px 200px 200px 200px; gap: 20px 20px; margin: 24px auto 16px auto; background: #eaeaea; padding: 16px; border-radius: 4px; margin-left: auto; margin-right: auto;} |
|
|
|
|
|
#page-can .input-row {display: contents;} |
|
|
|
|
|
#page-can .can-input-area label.nowrap {white-space: nowrap;} |
|
|
|
|
|
#page-can .can-input-area label {min-width: auto; color: #444; white-space: normal;} |
|
|
|
|
|
#page-can .can-input-area input {background: #e0e0e0; border: none; border-radius: 2px; padding: 4px 8px; min-width: auto;} |
|
|
|
|
|
#page-can .can-actions {display: flex; gap: 24px; justify-content: center; margin: 16px 0 0 0;} |
|
|
|
|
|
#page-can .can-actions button {background: #d3d3d3; border: 1px solid #aaa; border-radius: 2px; padding: 8px 24px; font-size: 16px; cursor: pointer;} |
|
|
|
|
|
#can-bottom-actions {display: flex; gap: 24px; justify-content: center; background: #f7f7f7; border: 1px solid #bbb; border-radius: 4px; margin: 24px 0 0 0; padding: 20px 0;} |
|
|
|
|
|
#can-bottom-actions button {background: #e0e0e0; border: 1px solid #aaa; border-radius: 2px; padding: 10px 18px; font-size: 16px; min-width: 140px; cursor: pointer;} |
|
|
|
|
|
|
|
|
|
|
|
.selected-row{background: #d0e6ff !important;} |
|
|
|
|
|
.selected-row > td {background: #d0e6ff !important;} |
|
|
|
|
|
|
|
|
.selected-row{ |
|
|
|
|
|
background: #d0e6ff !important; |
|
|
|
|
|
} |
|
|
|
|
|
.selected-row > td { |
|
|
|
|
|
background: #d0e6ff !important; |
|
|
|
|
|
} |
|
|
|
|
|
</style> |
|
|
</style> |
|
|
</head> |
|
|
</head> |
|
|
<body> |
|
|
<body> |
|
|
@ -195,6 +148,7 @@ |
|
|
<button data-page="reg">Config</button> |
|
|
<button data-page="reg">Config</button> |
|
|
<button data-page="modbus" id="modbusSidebarBtn" style="display: none">MODBUS</button> |
|
|
<button data-page="modbus" id="modbusSidebarBtn" style="display: none">MODBUS</button> |
|
|
<button data-page="opcua" id="opcUaSidebarBtn" style="display: none">OPC_UA</button> |
|
|
<button data-page="opcua" id="opcUaSidebarBtn" style="display: none">OPC_UA</button> |
|
|
|
|
|
<button data-page="can" id="canSidebarBtn" style="display: none">CAN</button> |
|
|
</div> |
|
|
</div> |
|
|
</details> |
|
|
</details> |
|
|
</aside> |
|
|
</aside> |
|
|
@ -446,8 +400,8 @@ |
|
|
<select id="reg_four_byte_order"> |
|
|
<select id="reg_four_byte_order"> |
|
|
<option selected disabled hidden="hidden"></option> |
|
|
<option selected disabled hidden="hidden"></option> |
|
|
<option value="little">little</option> |
|
|
<option value="little">little</option> |
|
|
<option value="little_swap">little swap</option> |
|
|
<option value="littleSwap">little swap</option> |
|
|
<option value="big_swap">big swap</option> |
|
|
<option value="bigSwap">big swap</option> |
|
|
<option value="big">big</option> |
|
|
<option value="big">big</option> |
|
|
</select> |
|
|
</select> |
|
|
</div> |
|
|
</div> |
|
|
@ -538,11 +492,25 @@ |
|
|
<label>Field</label> |
|
|
<label>Field</label> |
|
|
<input type="text" id="modbus_field_input" placeholder="Enter field name"> |
|
|
<input type="text" id="modbus_field_input" placeholder="Enter field name"> |
|
|
<label class="nowrap">idt (Input Data Type)</label> |
|
|
<label class="nowrap">idt (Input Data Type)</label> |
|
|
<input type="text" id="modbus_idt_input" placeholder="Enter IDT"> |
|
|
<select id="modbus_idt_input"> |
|
|
|
|
|
<option selected disabled hidden="hidden"></option> |
|
|
|
|
|
<option value="integer">integer</option> |
|
|
|
|
|
<option value="float64">float64</option> |
|
|
|
|
|
<option value="boolean">boolean</option> |
|
|
|
|
|
<option value="unsignedInteger">unsignedInteger</option> |
|
|
|
|
|
<option value="short">short</option> |
|
|
|
|
|
<option value="unsignedShort">unsignedShort</option> |
|
|
|
|
|
</select> |
|
|
<label>addr</label> |
|
|
<label>addr</label> |
|
|
<input type="text" id="modbus_addr_input" placeholder="Enter address"> |
|
|
<input type="text" id="modbus_addr_input" placeholder="Enter address"> |
|
|
<label class="nowrap">odt (Output Data Type)</label> |
|
|
<label class="nowrap">odt (Output Data Type)</label> |
|
|
<input type="text" id="modbus_odt_input" placeholder="Enter ODT"> |
|
|
<select id="modbus_odt_input"> |
|
|
|
|
|
<option selected disabled hidden="hidden"></option> |
|
|
|
|
|
<option value="integer">integer</option> |
|
|
|
|
|
<option value="float64">float64</option> |
|
|
|
|
|
<option value="boolean">boolean</option> |
|
|
|
|
|
<option value="string">string</option> |
|
|
|
|
|
</select> |
|
|
<label>shift</label> |
|
|
<label>shift</label> |
|
|
<input type="text" id="modbus_shift_input" placeholder="Enter shift value"> |
|
|
<input type="text" id="modbus_shift_input" placeholder="Enter shift value"> |
|
|
<label class="nowrap">dv</label> |
|
|
<label class="nowrap">dv</label> |
|
|
@ -586,11 +554,14 @@ |
|
|
<table> |
|
|
<table> |
|
|
<thead> |
|
|
<thead> |
|
|
<tr> |
|
|
<tr> |
|
|
<th>field</th> |
|
|
<th>Field</th> |
|
|
<th>addr</th> |
|
|
<th>Address</th> |
|
|
<th>ns</th> |
|
|
<th>NS</th> |
|
|
<th>odt</th> |
|
|
<th>ODT</th> |
|
|
<th>dv</th> |
|
|
<th>Default Value</th> |
|
|
|
|
|
<th>Shift</th> |
|
|
|
|
|
<th>Expression</th> |
|
|
|
|
|
<th>Mask</th> |
|
|
</tr> |
|
|
</tr> |
|
|
</thead> |
|
|
</thead> |
|
|
<tbody id="opcua-field-list"> |
|
|
<tbody id="opcua-field-list"> |
|
|
@ -599,22 +570,28 @@ |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="opcua-input-area"> |
|
|
<div class="opcua-input-area"> |
|
|
<div class="input-row"> |
|
|
<label>field</label> |
|
|
<label>field</label><input type="text" id="opcua_field_input"> |
|
|
<input type="text" id="opcua_field_input" placeholder="Enter field name"> |
|
|
<label>ns(NameSpace)</label><input type="text" id="opcua_ns_input"> |
|
|
<label class="nowrap">ns(NameSpace)</label> |
|
|
</div> |
|
|
<input type="text" id="opcua_ns_input" placeholder="Enter NS"> |
|
|
<div class="input-row"> |
|
|
<label>addr(address)</label> |
|
|
<label>addr(address)</label><input type="text" id="opcua_addr_input"> |
|
|
<input type="text" id="opcua_addr_input" placeholder="Enter address"> |
|
|
<label>odt(Output Data Type)</label><input type="text" id="opcua_odt_input"> |
|
|
<label class="nowrap">odt(Output Data Type)</label> |
|
|
</div> |
|
|
<select id="opcua_odt_input"> |
|
|
<div class="input-row"> |
|
|
<option selected disabled hidden="hidden"></option> |
|
|
<label>shift</label><input type="text" id="opcua_shift_input"> |
|
|
<option value="integer">integer</option> |
|
|
<label>dv(Default Value)</label><input type="text" id="opcua_dv_input"> |
|
|
<option value="float64">float64</option> |
|
|
</div> |
|
|
<option value="boolean">boolean</option> |
|
|
<div class="input-row"> |
|
|
<option value="string">string</option> |
|
|
<label>expr</label><input type="text" id="opcua_expr_input"> |
|
|
</select> |
|
|
<label>mask</label><input type="text" id="opcua_mask_input"> |
|
|
<label>shift</label> |
|
|
</div> |
|
|
<input type="text" id="opcua_shift_input" placeholder="Enter shift value"> |
|
|
|
|
|
<label class="nowrap">dv(Default Value)</label> |
|
|
|
|
|
<input type="text" id="opcua_dv_input" placeholder="Enter default value"> |
|
|
|
|
|
<label>expr</label> |
|
|
|
|
|
<input type="text" id="opcua_expr_input" placeholder="Enter expression"> |
|
|
|
|
|
<label class="nowrap">mask</label> |
|
|
|
|
|
<input type="text" id="opcua_mask_input" placeholder="Enter mask"> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="opcua-actions"> |
|
|
<div class="opcua-actions"> |
|
|
@ -624,12 +601,78 @@ |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="actions"> |
|
|
<div id="opcUa-bottom-actions"> |
|
|
<button id="loadOpcUaFileBtn">Load Protocol File</button> |
|
|
<button id="loadOpcUaFileBtn">Load Protocol File</button> |
|
|
<button id="saveOpcUaFileBtn">Save to Protocol</button> |
|
|
<button id="saveOpcUaFileBtn">Save to Protocol</button> |
|
|
</div> |
|
|
</div> |
|
|
</section> |
|
|
</section> |
|
|
|
|
|
|
|
|
|
|
|
<template id="can-row-template"> |
|
|
|
|
|
<tr class="can-row"> |
|
|
|
|
|
<td><span class="can-field-display"></span></td> |
|
|
|
|
|
<td><span class="can-id-display"></span></td> |
|
|
|
|
|
<td><span class="can-odt-display"></span></td> |
|
|
|
|
|
<td><span class="can-dv-display"></span></td> |
|
|
|
|
|
<td><span class="can-shift-display"></span></td> |
|
|
|
|
|
<td><span class="can-mask-display"></span></td> |
|
|
|
|
|
<td><span class="can-expr-display"></span></td> |
|
|
|
|
|
</tr> |
|
|
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
|
|
<section id="page-can" class="page" style="display:none;"> |
|
|
|
|
|
<div class="card"> |
|
|
|
|
|
<h3>CAN Configuration</h3> |
|
|
|
|
|
<div class="can-table-container"> |
|
|
|
|
|
<table> |
|
|
|
|
|
<thead> |
|
|
|
|
|
<tr> |
|
|
|
|
|
<th>Field</th> |
|
|
|
|
|
<th>ID</th> |
|
|
|
|
|
<th>ODT</th> |
|
|
|
|
|
<th>Default Value</th> |
|
|
|
|
|
<th>Shift</th> |
|
|
|
|
|
<th>Expression</th> |
|
|
|
|
|
<th>Mask</th> |
|
|
|
|
|
</tr> |
|
|
|
|
|
</thead> |
|
|
|
|
|
<tbody id="can-field-list"> |
|
|
|
|
|
</tbody> |
|
|
|
|
|
</table> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div class="can-input-area"> |
|
|
|
|
|
<label>Field</label> |
|
|
|
|
|
<input type="text" id="can_field_input" placeholder="Enter field name"> |
|
|
|
|
|
<label>ID</label> |
|
|
|
|
|
<input type="text" id="can_id_input" placeholder="Enter ID"> |
|
|
|
|
|
<label>odt (Output Data Type)</label> |
|
|
|
|
|
<select id="can_odt_input"> |
|
|
|
|
|
<option selected disabled hidden="hidden"></option> |
|
|
|
|
|
<option value="integer">integer</option> |
|
|
|
|
|
<option value="float64">float64</option> |
|
|
|
|
|
<option value="boolean">boolean</option> |
|
|
|
|
|
<option value="string">string</option> |
|
|
|
|
|
</select> |
|
|
|
|
|
<label>dv</label> |
|
|
|
|
|
<input type="text" id="can_dv_input" placeholder="Enter default value"> |
|
|
|
|
|
<label>shift</label> |
|
|
|
|
|
<input type="text" id="can_shift_input" placeholder="Enter shift value"> |
|
|
|
|
|
<label>expr</label> |
|
|
|
|
|
<input type="text" id="can_expr_input" placeholder="Enter expression"> |
|
|
|
|
|
<label>mask</label> |
|
|
|
|
|
<input type="text" id="can_mask_input" placeholder="Enter mask"> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div class="can-actions"> |
|
|
|
|
|
<button id="can_add_btn">Add</button> |
|
|
|
|
|
<button id="can_modify_btn">Modify</button> |
|
|
|
|
|
<button id="can_delete_btn">Delete</button> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div id="can-bottom-actions"> |
|
|
|
|
|
<button id="loadCanBtn">Load Protocol File</button> |
|
|
|
|
|
<button id="saveCanBtn">Save Protocol File</button> |
|
|
|
|
|
</div> |
|
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
</main> |
|
|
</main> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
@ -733,7 +776,8 @@ |
|
|
io : document.getElementById('page-io'), |
|
|
io : document.getElementById('page-io'), |
|
|
reg : document.getElementById('page-reg'), |
|
|
reg : document.getElementById('page-reg'), |
|
|
modbus : document.getElementById('page-modbus'), |
|
|
modbus : document.getElementById('page-modbus'), |
|
|
opcua : document.getElementById('page-opcua') |
|
|
opcua : document.getElementById('page-opcua'), |
|
|
|
|
|
can : document.getElementById('page-can') |
|
|
}; |
|
|
}; |
|
|
const titleEl = document.getElementById('page-title'); |
|
|
const titleEl = document.getElementById('page-title'); |
|
|
|
|
|
|
|
|
@ -872,18 +916,22 @@ |
|
|
const selectProtocol = regProtocolSelect.value; |
|
|
const selectProtocol = regProtocolSelect.value; |
|
|
const modbusSidebarBtn = document.getElementById('modbusSidebarBtn'); |
|
|
const modbusSidebarBtn = document.getElementById('modbusSidebarBtn'); |
|
|
const opcUaSidebarBtn = document.getElementById('opcUaSidebarBtn'); |
|
|
const opcUaSidebarBtn = document.getElementById('opcUaSidebarBtn'); |
|
|
|
|
|
const canSidebarBtn = document.getElementById('canSidebarBtn'); |
|
|
if(modbusSidebarBtn) modbusSidebarBtn.style.display = 'none'; |
|
|
if(modbusSidebarBtn) modbusSidebarBtn.style.display = 'none'; |
|
|
if(opcUaSidebarBtn) opcUaSidebarBtn.style.display = 'none'; |
|
|
if(opcUaSidebarBtn) opcUaSidebarBtn.style.display = 'none'; |
|
|
|
|
|
if(canSidebarBtn) canSidebarBtn.style.display = 'none'; |
|
|
if(selectProtocol === 'MODBUS'){ |
|
|
if(selectProtocol === 'MODBUS'){ |
|
|
if (modbusSidebarBtn) modbusSidebarBtn.style.display = 'block'; |
|
|
if (modbusSidebarBtn) modbusSidebarBtn.style.display = 'block'; |
|
|
} |
|
|
} |
|
|
else if(selectProtocol === 'OPC_UA'){ |
|
|
else if(selectProtocol === 'OPC_UA'){ |
|
|
if(opcUaSidebarBtn) opcUaSidebarBtn.style.display = 'block'; |
|
|
if(opcUaSidebarBtn) opcUaSidebarBtn.style.display = 'block'; |
|
|
} |
|
|
} |
|
|
|
|
|
// CAN Input이 on일 때만 CAN 메뉴 보이기 |
|
|
// Protocol configuration 메뉴를 자동으로 펼치기 |
|
|
const canInputEl = document.getElementById('reg_can_input'); |
|
|
|
|
|
if(canInputEl && canInputEl.value === 'on'){ |
|
|
|
|
|
if(canSidebarBtn) canSidebarBtn.style.display = 'block'; |
|
|
|
|
|
} |
|
|
|
|
|
// Protocol configuration 메뉴 자동 펼치기 |
|
|
const protocolDetails = document.querySelectorAll('details.nav')[1]; |
|
|
const protocolDetails = document.querySelectorAll('details.nav')[1]; |
|
|
if (protocolDetails) protocolDetails.open = true; |
|
|
if (protocolDetails) protocolDetails.open = true; |
|
|
} |
|
|
} |
|
|
@ -961,28 +1009,53 @@ |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const opcUaContainer = document.getElementById('opc_ua_fields_container'); |
|
|
|
|
|
if (opcUaContainer) { |
|
|
// OPC_UA UI 테이블 렌더링 |
|
|
opcUaContainer.innerHTML = ''; |
|
|
const opcUaFieldList = document.getElementById('opcua-field-list'); |
|
|
if (lastLoadedRegisterData.OPC_UA && lastLoadedRegisterData.OPC_UA.length > 0) { |
|
|
const opcUaRowTemplate = document.getElementById('opcua-row-template'); |
|
|
lastLoadedRegisterData.OPC_UA.forEach(field => { |
|
|
if (opcUaFieldList && opcUaRowTemplate) { |
|
|
// ... OPC_UA 필드 표시 로직 ... |
|
|
opcUaFieldList.innerHTML = ''; |
|
|
|
|
|
if (Array.isArray(register.OPC_UA) && register.OPC_UA.length > 0) { |
|
|
|
|
|
register.OPC_UA.forEach(field => { |
|
|
|
|
|
const newRow = opcUaRowTemplate.content.cloneNode(true); |
|
|
|
|
|
newRow.querySelector('.opcua-field-display').textContent = field.field ?? ''; |
|
|
|
|
|
newRow.querySelector('.opcua-addr-display').textContent = field.addr ?? ''; |
|
|
|
|
|
newRow.querySelector('.opcua-ns-display').textContent = field.idt ?? ''; |
|
|
|
|
|
newRow.querySelector('.opcua-odt-display').textContent = field.odt ?? ''; |
|
|
|
|
|
newRow.querySelector('.opcua-dv-display').textContent = field.dv ?? ''; |
|
|
|
|
|
newRow.querySelector('.opcua-shift-display').textContent = field.shift ?? ''; |
|
|
|
|
|
newRow.querySelector('.opcua-expr-display').textContent = field.expr ?? ''; |
|
|
|
|
|
newRow.querySelector('.opcua-mask-display').textContent = field.mask ?? ''; |
|
|
|
|
|
opcUaFieldList.appendChild(newRow); |
|
|
}); |
|
|
}); |
|
|
} else { |
|
|
} else { |
|
|
opcUaContainer.textContent = 'No OPC_UA fields configured.'; |
|
|
// OPC_UA 데이터가 없으면 빈 행 하나 추가 |
|
|
|
|
|
const newRow = opcUaRowTemplate.content.cloneNode(true); |
|
|
|
|
|
opcUaFieldList.appendChild(newRow); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
const canContainer = document.getElementById('can_fields_container'); |
|
|
|
|
|
if (canContainer) { |
|
|
// CAN 테이블 렌더링 |
|
|
canContainer.innerHTML = ''; |
|
|
const canFieldList = document.getElementById('can-field-list'); |
|
|
if (lastLoadedRegisterData.CAN && lastLoadedRegisterData.CAN.length > 0) { |
|
|
const canRowTemplate = document.getElementById('can-row-template'); |
|
|
lastLoadedRegisterData.CAN.forEach(field => { |
|
|
canFieldList.innerHTML = ''; |
|
|
// ... CAN 필드 표시 로직 ... |
|
|
if (Array.isArray(register.CAN) && register.CAN.length > 0) { |
|
|
}); |
|
|
register.CAN.forEach(field => { |
|
|
} else { |
|
|
const newRow = canRowTemplate.content.cloneNode(true); |
|
|
canContainer.textContent = 'No CAN fields configured.'; |
|
|
newRow.querySelector('.can-field-display').textContent = field.field ?? ''; |
|
|
} |
|
|
newRow.querySelector('.can-id-display').textContent = field.id ?? ''; |
|
|
|
|
|
newRow.querySelector('.can-odt-display').textContent = field.odt ?? ''; |
|
|
|
|
|
newRow.querySelector('.can-dv-display').textContent = field.dv ?? ''; |
|
|
|
|
|
newRow.querySelector('.can-shift-display').textContent = field.shift ?? ''; |
|
|
|
|
|
newRow.querySelector('.can-expr-display').textContent = field.expr ?? ''; |
|
|
|
|
|
newRow.querySelector('.can-mask-display').textContent = field.mask ?? ''; |
|
|
|
|
|
canFieldList.appendChild(newRow); |
|
|
|
|
|
}); |
|
|
|
|
|
} else { |
|
|
|
|
|
const newRow = canRowTemplate.content.cloneNode(true); |
|
|
|
|
|
canFieldList.appendChild(newRow); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -1011,19 +1084,16 @@ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function collectConfigData() { |
|
|
function collectConfigData() { |
|
|
const collectedRegister = {...lastLoadedRegisterData}; // DTO 필드명(camelCase)으로 값을 수집할 객체 |
|
|
const collectedRegister = {...lastLoadedRegisterData}; |
|
|
|
|
|
|
|
|
// configIdMap을 순회하며 HTML ID로부터 값을 가져와 DTO 필드명에 매핑 |
|
|
// configIdMap을 순회하며 HTML ID로부터 값을 가져와 DTO 필드명에 매핑 |
|
|
for (const htmlId in configIdMap) { |
|
|
for (const htmlId in configIdMap) { |
|
|
const dtoKey = configIdMap[htmlId]; // HTML ID에 해당하는 DTO 필드명 (camelCase) |
|
|
const dtoKey = configIdMap[htmlId]; |
|
|
const el = document.getElementById(htmlId); |
|
|
const el = document.getElementById(htmlId); |
|
|
if (el) { |
|
|
if (el) { |
|
|
collectedRegister[dtoKey] = el.value !== null && el.value !== undefined ? el.value.trim() : ''; |
|
|
collectedRegister[dtoKey] = el.value !== null && el.value !== undefined ? el.value.trim() : ''; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 체크박스 필드 (HTML ID와 DTO 필드명이 같음) |
|
|
// 체크박스 필드 (HTML ID와 DTO 필드명이 같음) |
|
|
// AnalogPort 매핑: true -> "1", false -> "0" |
|
|
|
|
|
['ai0', 'ai1', 'ai2', 'ai3', 'di0', 'di1', 'di2', 'di3'].forEach(id => { |
|
|
['ai0', 'ai1', 'ai2', 'ai3', 'di0', 'di1', 'di2', 'di3'].forEach(id => { |
|
|
const el = document.getElementById(id); |
|
|
const el = document.getElementById(id); |
|
|
if (el && el.type === 'checkbox') { |
|
|
if (el && el.type === 'checkbox') { |
|
|
@ -1034,6 +1104,79 @@ |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
}); |
|
|
}); |
|
|
|
|
|
// MODBUS 테이블 수집 (빈 값은 필드에서 제외) |
|
|
|
|
|
const modbusRows = document.querySelectorAll('#modbus-field-list tr'); |
|
|
|
|
|
collectedRegister.MODBUS = []; |
|
|
|
|
|
modbusRows.forEach(row => { |
|
|
|
|
|
const field = row.querySelector('.field-display')?.textContent.trim(); |
|
|
|
|
|
if (field) { |
|
|
|
|
|
const obj = {}; |
|
|
|
|
|
obj.field = field; |
|
|
|
|
|
const addr = row.querySelector('.addr-display')?.textContent.trim(); |
|
|
|
|
|
const idt = row.querySelector('.idt-display')?.textContent.trim(); |
|
|
|
|
|
const odt = row.querySelector('.odt-display')?.textContent.trim(); |
|
|
|
|
|
const dv = row.querySelector('.dv-display')?.textContent.trim(); |
|
|
|
|
|
const shift = row.querySelector('.shift-display')?.textContent.trim(); |
|
|
|
|
|
const expr = row.querySelector('.expr-display')?.textContent.trim(); |
|
|
|
|
|
const mask = row.querySelector('.mask-display')?.textContent.trim(); |
|
|
|
|
|
if (addr) obj.addr = addr; |
|
|
|
|
|
if (idt) obj.idt = idt; |
|
|
|
|
|
if (odt) obj.odt = odt; |
|
|
|
|
|
if (dv) obj.dv = dv; |
|
|
|
|
|
if (shift) obj.shift = shift; |
|
|
|
|
|
if (expr) obj.expr = expr; |
|
|
|
|
|
if (mask) obj.mask = mask; |
|
|
|
|
|
collectedRegister.MODBUS.push(obj); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
// OPC_UA 테이블 수집 (빈 값은 필드에서 제외) |
|
|
|
|
|
const opcuaRows = document.querySelectorAll('#opcua-field-list tr'); |
|
|
|
|
|
collectedRegister.OPC_UA = []; |
|
|
|
|
|
opcuaRows.forEach(row => { |
|
|
|
|
|
const field = row.querySelector('.opcua-field-display')?.textContent.trim(); |
|
|
|
|
|
if (field) { |
|
|
|
|
|
const obj = {}; |
|
|
|
|
|
obj.field = field; |
|
|
|
|
|
const addr = row.querySelector('.opcua-addr-display')?.textContent.trim(); |
|
|
|
|
|
const ns = row.querySelector('.opcua-ns-display')?.textContent.trim(); |
|
|
|
|
|
const odt = row.querySelector('.opcua-odt-display')?.textContent.trim(); |
|
|
|
|
|
const dv = row.querySelector('.opcua-dv-display')?.textContent.trim(); |
|
|
|
|
|
const shift = row.querySelector('.opcua-shift-display')?.textContent.trim(); |
|
|
|
|
|
const expr = row.querySelector('.opcua-expr-display')?.textContent.trim(); |
|
|
|
|
|
const mask = row.querySelector('.opcua-mask-display')?.textContent.trim(); |
|
|
|
|
|
if (addr) obj.addr = addr; |
|
|
|
|
|
if (ns) obj.ns = ns; |
|
|
|
|
|
if (odt) obj.odt = odt; |
|
|
|
|
|
if (dv) obj.dv = dv; |
|
|
|
|
|
if (shift) obj.shift = shift; |
|
|
|
|
|
if (expr) obj.expr = expr; |
|
|
|
|
|
if (mask) obj.mask = mask; |
|
|
|
|
|
collectedRegister.OPC_UA.push(obj); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
// CAN 테이블 수집 (빈 값은 필드에서 제외) |
|
|
|
|
|
const canRows = document.querySelectorAll('#can-field-list tr'); |
|
|
|
|
|
collectedRegister.CAN = []; |
|
|
|
|
|
canRows.forEach(row => { |
|
|
|
|
|
const field = row.querySelector('.can-field-display')?.textContent.trim(); |
|
|
|
|
|
if (field) { |
|
|
|
|
|
const obj = {}; |
|
|
|
|
|
obj.field = field; |
|
|
|
|
|
const id = row.querySelector('.can-id-display')?.textContent.trim(); |
|
|
|
|
|
const odt = row.querySelector('.can-odt-display')?.textContent.trim(); |
|
|
|
|
|
const dv = row.querySelector('.can-dv-display')?.textContent.trim(); |
|
|
|
|
|
const shift = row.querySelector('.can-shift-display')?.textContent.trim(); |
|
|
|
|
|
const expr = row.querySelector('.can-expr-display')?.textContent.trim(); |
|
|
|
|
|
const mask = row.querySelector('.can-mask-display')?.textContent.trim(); |
|
|
|
|
|
if (id) obj.id = id; |
|
|
|
|
|
if (odt) obj.odt = odt; |
|
|
|
|
|
if (dv) obj.dv = dv; |
|
|
|
|
|
if (shift) obj.shift = shift; |
|
|
|
|
|
if (expr) obj.expr = expr; |
|
|
|
|
|
if (mask) obj.mask = mask; |
|
|
|
|
|
collectedRegister.CAN.push(obj); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
return collectedRegister; |
|
|
return collectedRegister; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -1066,6 +1209,33 @@ |
|
|
document.getElementById('modbus_mask_input').value = tr.querySelector('.mask-display').textContent; |
|
|
document.getElementById('modbus_mask_input').value = tr.querySelector('.mask-display').textContent; |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
const opcUalist = document.getElementById('opcua-field-list'); |
|
|
|
|
|
// 처음에 행이 없으면 빈 행을 하나 추가 |
|
|
|
|
|
if(opcUalist.children.length === 0) { |
|
|
|
|
|
const opcUaRowTemplate = document.getElementById('opcua-row-template'); |
|
|
|
|
|
if(opcUaRowTemplate) { |
|
|
|
|
|
const newRow = opcUaRowTemplate.content.cloneNode(true); |
|
|
|
|
|
opcUalist.appendChild(newRow); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
document.getElementById('opcua-field-list').addEventListener('click', function(e){ |
|
|
|
|
|
let tr = e.target.closest('tr'); |
|
|
|
|
|
if (!tr) return; |
|
|
|
|
|
|
|
|
|
|
|
Array.from(this.children).forEach(row => row.classList.remove('selected-row')); |
|
|
|
|
|
tr.classList.add('selected-row'); |
|
|
|
|
|
selectedRow = tr; |
|
|
|
|
|
|
|
|
|
|
|
document.getElementById('opcua_field_input').value = tr.querySelector('.opcua-field-display').textContent; |
|
|
|
|
|
document.getElementById('opcua_addr_input').value = tr.querySelector('.opcua-addr-display').textContent; |
|
|
|
|
|
document.getElementById('opcua_ns_input').value = tr.querySelector('.opcua-ns-display').textContent; |
|
|
|
|
|
document.getElementById('opcua_odt_input').value = tr.querySelector('.opcua-odt-display').textContent; |
|
|
|
|
|
document.getElementById('opcua_dv_input').value = tr.querySelector('.opcua-dv-display').textContent; |
|
|
|
|
|
document.getElementById('opcua_shift_input').value = tr.querySelector('.opcua-shift-display').textContent; |
|
|
|
|
|
document.getElementById('opcua_expr_input').value = tr.querySelector('.opcua-expr-display').textContent; |
|
|
|
|
|
document.getElementById('opcua_mask_input').value = tr.querySelector('.opcua-mask-display').textContent; |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -1128,6 +1298,110 @@ |
|
|
document.querySelectorAll('.modbus-input-area input').forEach(i => i.value = ''); |
|
|
document.querySelectorAll('.modbus-input-area input').forEach(i => i.value = ''); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const opcUaAddBtn = document.getElementById('opcua_add_btn'); |
|
|
|
|
|
const opcUaFieldList = document.getElementById('opcua-field-list'); |
|
|
|
|
|
const opcUaRowTemplate = document.getElementById('opcua-row-template'); |
|
|
|
|
|
|
|
|
|
|
|
if(opcUaAddBtn && opcUaFieldList && opcUaRowTemplate){ |
|
|
|
|
|
opcUaAddBtn.addEventListener('click',()=>{ |
|
|
|
|
|
const field = document.getElementById('opcua_field_input').value; |
|
|
|
|
|
const addr = document.getElementById('opcua_addr_input').value; |
|
|
|
|
|
const ns = document.getElementById('opcua_ns_input').value; |
|
|
|
|
|
const odt = document.getElementById('opcua_odt_input').value; |
|
|
|
|
|
const defaultValue = document.getElementById('opcua_dv_input').value; |
|
|
|
|
|
const shift = document.getElementById('opcua_shift_input').value; |
|
|
|
|
|
const expr = document.getElementById('opcua_expr_input').value; |
|
|
|
|
|
const mask = document.getElementById('opcua_mask_input').value; |
|
|
|
|
|
|
|
|
|
|
|
const newRow = opcUaRowTemplate.content.cloneNode(true); |
|
|
|
|
|
newRow.querySelector('.opcua-field-display').textContent = field; |
|
|
|
|
|
newRow.querySelector('.opcua-addr-display').textContent = addr; |
|
|
|
|
|
newRow.querySelector('.opcua-ns-display').textContent = ns; |
|
|
|
|
|
newRow.querySelector('.opcua-odt-display').textContent = odt; |
|
|
|
|
|
newRow.querySelector('.opcua-dv-display').textContent = defaultValue; |
|
|
|
|
|
newRow.querySelector('.opcua-shift-display').textContent = shift; |
|
|
|
|
|
newRow.querySelector('.opcua-expr-display').textContent = expr; |
|
|
|
|
|
newRow.querySelector('.opcua-mask-display').textContent = mask; |
|
|
|
|
|
|
|
|
|
|
|
opcUaFieldList.appendChild(newRow); |
|
|
|
|
|
|
|
|
|
|
|
document.getElementById('opcua_field_input').value = ''; |
|
|
|
|
|
document.getElementById('opcua_addr_input').value = ''; |
|
|
|
|
|
document.getElementById('opcua_ns_input').value = ''; |
|
|
|
|
|
document.getElementById('opcua_odt_input').value = ''; |
|
|
|
|
|
document.getElementById('opcua_dv_input').value = ''; |
|
|
|
|
|
document.getElementById('opcua_shift_input').value = ''; |
|
|
|
|
|
document.getElementById('opcua_expr_input').value = ''; |
|
|
|
|
|
document.getElementById('opcua_mask_input').value = ''; |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
document.getElementById('opcua_modify_btn').onclick = function() { |
|
|
|
|
|
if (!selectedRow) return alert('수정할 행을 선택하세요!'); |
|
|
|
|
|
selectedRow.querySelector('.opcua-field-display').textContent = document.getElementById('opcua_field_input').value; |
|
|
|
|
|
selectedRow.querySelector('.opcua-addr-display').textContent = document.getElementById('opcua_addr_input').value; |
|
|
|
|
|
selectedRow.querySelector('.opcua-ns-display').textContent = document.getElementById('opcua_ns_input').value; |
|
|
|
|
|
selectedRow.querySelector('.opcua-odt-display').textContent = document.getElementById('opcua_odt_input').value; |
|
|
|
|
|
selectedRow.querySelector('.opcua-dv-display').textContent = document.getElementById('opcua_dv_input').value; |
|
|
|
|
|
selectedRow.querySelector('.opcua-shift-display').textContent = document.getElementById('opcua_shift_input').value; |
|
|
|
|
|
selectedRow.querySelector('.opcua-expr-display').textContent = document.getElementById('opcua_expr_input').value; |
|
|
|
|
|
selectedRow.querySelector('.opcua-mask-display').textContent = document.getElementById('opcua_mask_input').value; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// 삭제 버튼 |
|
|
|
|
|
document.getElementById('opcua_delete_btn').onclick = function() { |
|
|
|
|
|
if (!selectedRow) return alert('삭제할 행을 선택하세요!'); |
|
|
|
|
|
const list = document.getElementById('opcua-field-list'); |
|
|
|
|
|
selectedRow.remove(); |
|
|
|
|
|
selectedRow = null; |
|
|
|
|
|
document.querySelectorAll('.opcua-input-area input').forEach(i => i.value = ''); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// CAN 테이블 |
|
|
|
|
|
document.getElementById('can_add_btn').addEventListener('click',()=>{ |
|
|
|
|
|
const field = document.getElementById('can_field_input').value; |
|
|
|
|
|
const id = document.getElementById('can_id_input').value; |
|
|
|
|
|
const odt = document.getElementById('can_odt_input').value; |
|
|
|
|
|
const dv = document.getElementById('can_dv_input').value; |
|
|
|
|
|
const shift = document.getElementById('can_shift_input').value; |
|
|
|
|
|
const expr = document.getElementById('can_expr_input').value; |
|
|
|
|
|
const mask = document.getElementById('can_mask_input').value; |
|
|
|
|
|
const canRowTemplate = document.getElementById('can-row-template'); |
|
|
|
|
|
const newRow = canRowTemplate.content.cloneNode(true); |
|
|
|
|
|
newRow.querySelector('.can-field-display').textContent = field; |
|
|
|
|
|
newRow.querySelector('.can-id-display').textContent = id; |
|
|
|
|
|
newRow.querySelector('.can-odt-display').textContent = odt; |
|
|
|
|
|
newRow.querySelector('.can-dv-display').textContent = dv; |
|
|
|
|
|
newRow.querySelector('.can-shift-display').textContent = shift; |
|
|
|
|
|
newRow.querySelector('.can-expr-display').textContent = expr; |
|
|
|
|
|
newRow.querySelector('.can-mask-display').textContent = mask; |
|
|
|
|
|
canFieldList.appendChild(newRow); |
|
|
|
|
|
document.getElementById('can_field_input').value = ''; |
|
|
|
|
|
document.getElementById('can_id_input').value = ''; |
|
|
|
|
|
document.getElementById('can_odt_input').value = ''; |
|
|
|
|
|
document.getElementById('can_dv_input').value = ''; |
|
|
|
|
|
document.getElementById('can_shift_input').value = ''; |
|
|
|
|
|
document.getElementById('can_expr_input').value = ''; |
|
|
|
|
|
document.getElementById('can_mask_input').value = ''; |
|
|
|
|
|
}); |
|
|
|
|
|
document.getElementById('can_modify_btn').onclick = function() { |
|
|
|
|
|
if (!selectedRow) return alert('수정할 행을 선택하세요!'); |
|
|
|
|
|
selectedRow.querySelector('.can-field-display').textContent = document.getElementById('can_field_input').value; |
|
|
|
|
|
selectedRow.querySelector('.can-id-display').textContent = document.getElementById('can_id_input').value; |
|
|
|
|
|
selectedRow.querySelector('.can-odt-display').textContent = document.getElementById('can_odt_input').value; |
|
|
|
|
|
selectedRow.querySelector('.can-dv-display').textContent = document.getElementById('can_dv_input').value; |
|
|
|
|
|
selectedRow.querySelector('.can-shift-display').textContent = document.getElementById('can_shift_input').value; |
|
|
|
|
|
selectedRow.querySelector('.can-expr-display').textContent = document.getElementById('can_expr_input').value; |
|
|
|
|
|
selectedRow.querySelector('.can-mask-display').textContent = document.getElementById('can_mask_input').value; |
|
|
|
|
|
}; |
|
|
|
|
|
document.getElementById('can_delete_btn').onclick = function() { |
|
|
|
|
|
if (!selectedRow) return alert('삭제할 행을 선택하세요!'); |
|
|
|
|
|
const list = document.getElementById('can-field-list'); |
|
|
|
|
|
selectedRow.remove(); |
|
|
|
|
|
selectedRow = null; |
|
|
|
|
|
document.querySelectorAll('.can-input-area input').forEach(i => i.value = ''); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
regProtocolSelect = document.getElementById('reg_protocol'); |
|
|
regProtocolSelect = document.getElementById('reg_protocol'); |
|
|
if(regProtocolSelect) { |
|
|
if(regProtocolSelect) { |
|
|
@ -1377,6 +1651,58 @@ |
|
|
alert('Register 설정 전송 중 통신 오류 발생'); |
|
|
alert('Register 설정 전송 중 통신 오류 발생'); |
|
|
}); |
|
|
}); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
document.getElementById('reg_can_input')?.addEventListener('change', toggleProtocolMenus);//-------------------------------- |
|
|
|
|
|
|
|
|
|
|
|
// DOMContentLoaded 내부에 추가: CAN 테이블도 처음에 빈 행이 없으면 하나 추가 |
|
|
|
|
|
const canFieldList = document.getElementById('can-field-list'); |
|
|
|
|
|
if(canFieldList.children.length === 0) { |
|
|
|
|
|
const canRowTemplate = document.getElementById('can-row-template'); |
|
|
|
|
|
if(canRowTemplate) { |
|
|
|
|
|
const newRow = canRowTemplate.content.cloneNode(true); |
|
|
|
|
|
canFieldList.appendChild(newRow); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
// CAN row 클릭 시 선택 표시 및 입력폼에 값 반영 |
|
|
|
|
|
canFieldList.addEventListener('click', function(e){ |
|
|
|
|
|
let tr = e.target.closest('tr'); |
|
|
|
|
|
if (!tr) return; |
|
|
|
|
|
Array.from(this.children).forEach(row => row.classList.remove('selected-row')); |
|
|
|
|
|
tr.classList.add('selected-row'); |
|
|
|
|
|
selectedRow = tr; |
|
|
|
|
|
document.getElementById('can_field_input').value = tr.querySelector('.can-field-display').textContent; |
|
|
|
|
|
document.getElementById('can_id_input').value = tr.querySelector('.can-id-display').textContent; |
|
|
|
|
|
document.getElementById('can_odt_input').value = tr.querySelector('.can-odt-display').textContent; |
|
|
|
|
|
document.getElementById('can_dv_input').value = tr.querySelector('.can-dv-display').textContent; |
|
|
|
|
|
document.getElementById('can_shift_input').value = tr.querySelector('.can-shift-display').textContent; |
|
|
|
|
|
document.getElementById('can_expr_input').value = tr.querySelector('.can-expr-display').textContent; |
|
|
|
|
|
document.getElementById('can_mask_input').value = tr.querySelector('.can-mask-display').textContent; |
|
|
|
|
|
}); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
document.getElementById('loadCanBtn').addEventListener('click', () => { |
|
|
|
|
|
fetch('http://localhost:8080/setting/get-register') |
|
|
|
|
|
.then(res => res.json()) |
|
|
|
|
|
.then(apiResponseData => { |
|
|
|
|
|
if (apiResponseData && apiResponseData.body) { |
|
|
|
|
|
loadFromRegisterJson(apiResponseData.body); |
|
|
|
|
|
alert('Protocol 설정 파일 로드 완료'); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
}); |
|
|
|
|
|
document.getElementById('saveCanBtn').addEventListener('click', () => { |
|
|
|
|
|
fetch('http://localhost:8080/setting/register', { |
|
|
|
|
|
method: 'POST', |
|
|
|
|
|
headers: {'Content-Type': 'application/json'}, |
|
|
|
|
|
body: JSON.stringify(collectConfigData()) |
|
|
|
|
|
}) |
|
|
|
|
|
.then(res => { |
|
|
|
|
|
if (res.ok) { |
|
|
|
|
|
alert('Register 설정 전송 완료'); |
|
|
|
|
|
} else { |
|
|
|
|
|
alert('Register 설정 전송 실패: ' + res.statusText); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
}); |
|
|
}); |
|
|
</script> |
|
|
</script> |
|
|
</body> |
|
|
</body> |
|
|
|