kds_mysql_query_writer
Version:
A beginner-friendly node for writing SQL queries via input fields
291 lines (251 loc) • 8.74 kB
HTML
<script type="text/html" data-template-name="kds mysql query writer">
<style>
/* X 버튼 스타일 (파스텔 붉은색, 고정된 크기) */
.remove-field-value {
background-color: #ff9999;
color: white;
border: none;
border-radius: 4px;
width: 40px;
height: 30px;
cursor: pointer;
font-size: 14px;
display: flex;
justify-content: center;
align-items: center;
}
/* + 버튼 스타일 */
#add-field-value {
background-color: #4d4d4d;
color: white;
border: none;
border-radius: 4px;
padding: 8px 16px;
cursor: pointer;
margin-top: 10px;
font-size: 14px;
}
/* 필드와 값 입력 칸 스타일 */
.field-input,
.value-input {
width: 45%;
padding: 6px;
margin-bottom: 8px;
}
/* 필드와 값 입력 행 */
.field-value-row {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
}
</style>
<!-- 쿼리 작업 유형 선택 -->
<div class="form-row">
<label for="node-input-operation">Operation Type</label>
<select id="node-input-operation">
<option value="SELECT">SELECT</option>
<option value="INSERT">INSERT</option>
<option value="UPDATE">UPDATE</option>
<option value="DELETE">DELETE</option>
</select>
</div>
<!-- 테이블명 입력 -->
<div class="form-row">
<label for="node-input-table">Table</label>
<input type="text" id="node-input-table" placeholder="Enter table name" />
</div>
<!-- 필드와 값을 함께 묶어서 처리 -->
<div class="form-row" id="fields-values-section">
<label for="node-input-fields-values">Fields & Values</label>
<div id="field-value-list"></div>
<button type="button" id="add-field-value">+ Add Field & Value</button>
</div>
<!-- 조건절 (WHERE) -->
<div class="form-row" id="condition-section">
<label for="node-input-condition">WHERE Condition (optional)</label>
<input
type="text"
id="node-input-condition"
placeholder="Enter WHERE condition"
/>
</div>
<!-- 실시간 쿼리문 표시 -->
<div class="form-row">
<label for="node-input-generated-query">Generated Query</label>
<textarea
id="node-input-generated-query"
style="width: 100%;"
readonly
></textarea>
</div>
</script>
<script type="text/javascript">
let fieldsValues = [];
let operationType = "";
RED.nodes.registerType("kds mysql query writer", {
category: "KDS",
color: "white",
defaults: {
operation: { value: "SELECT" },
table: { value: "" },
condition: { value: "" },
fields_values: { value: [] },
},
inputs: 1,
outputs: 1,
icon: "kds-logo-figma7.png",
label: function () {
return this.name || "[KDS]mysql query writer";
},
oneditprepare: function () {
const node = this;
fieldsValues = node.fields_values ? [...node.fields_values] : [];
$("#field-value-list").empty();
function addField(field = "") {
const fieldValueCount = $("#field-value-list .field-value-row").length;
if (!fieldsValues[fieldValueCount]) {
fieldsValues[fieldValueCount] = { field: "" };
}
const fieldRow = `
<div class="field-value-row" id="field-value-row-${fieldValueCount}">
<input type="text" class="field-input" value="${field}" placeholder="Enter field name" />
<button type="button" class="remove-field-value" data-id="${fieldValueCount}">X</button>
</div>`;
$("#field-value-list").append(fieldRow);
$(`#field-value-row-${fieldValueCount} .field-input`).on(
"input",
function () {
fieldsValues[fieldValueCount].field = $(this).val();
console.log(fieldsValues);
updateQuery();
}
);
}
function syncFieldIds() {
$("#field-value-list .field-value-row").each(function (index) {
$(this).attr("id", `field-value-row-${index}`);
$(this).find(".remove-field-value").data("id", index);
});
}
function addFieldValue(field = "", value = "") {
const fieldValueCount = $("#field-value-list .field-value-row").length;
if (!fieldsValues[fieldValueCount]) {
fieldsValues[fieldValueCount] = { field: "", value: "" };
}
const fieldValueRow = `
<div class="field-value-row" id="field-value-row-${fieldValueCount}">
<input type="text" class="field-input" value="${field}" placeholder="Enter field name" />
<input type="text" class="value-input" value="${value}" placeholder="Enter value" />
<button type="button" class="remove-field-value" data-id="${fieldValueCount}">X</button>
</div>`;
$("#field-value-list").append(fieldValueRow);
$(`#field-value-row-${fieldValueCount} .field-input`).on(
"input",
function () {
fieldsValues[fieldValueCount].field = $(this).val();
updateQuery();
}
);
$(`#field-value-row-${fieldValueCount} .value-input`).on(
"input",
function () {
fieldsValues[fieldValueCount].value = $(this).val();
updateQuery();
}
);
$(`#field-value-row-${fieldValueCount} .remove-field-value`).on(
"click",
function () {
const index = $(this).data("id");
$(this).parent().remove();
fieldsValues.splice(index, 1);
syncFieldIds();
updateQuery();
}
);
}
function updateFieldsVisibility(type) {
$("#field-value-list").empty();
if (type === "SELECT") {
fieldsValues.forEach((item) => {
addField(item.field);
});
$("#fields-values-section").show();
} else if (type === "INSERT" || type === "UPDATE") {
fieldsValues.forEach((item) => {
addFieldValue(item.field, item.value);
});
$("#fields-values-section").show();
} else {
$("#fields-values-section").hide();
}
}
function updateQuery() {
const table = $("#node-input-table").val().trim();
let query = "";
const fields = fieldsValues
.map((item) => (item.field ? item.field.trim() : ""))
.filter((field) => field !== "");
console.log("Fields for SELECT query:", fields);
const condition = $("#node-input-condition").val()
? $("#node-input-condition").val().trim()
: "";
if (operationType === "SELECT") {
if (table) {
query = `SELECT ${
fields.length > 0 ? fields.join(", ") : "*"
} FROM ${table}`;
if (condition) query += ` WHERE ${condition}`;
} else {
query = "Please enter a table name";
}
}
console.log("Generated query:", query);
$("#node-input-generated-query").val(query);
}
$(".field-input, .value-input").on("input", function () {
RED.nodes.dirty(true);
node.changed = true;
});
$(".remove-field-value").on("click", function () {
RED.nodes.dirty(true);
node.changed = true;
});
$("#add-field-value").on("click", function () {
if (operationType === "INSERT" || operationType === "UPDATE") {
addFieldValue("", "");
} else {
addField("");
}
});
$("#node-input-operation").on("change", function () {
operationType = $(this).val();
updateFieldsVisibility(operationType);
updateQuery();
});
operationType = $("#node-input-operation").val();
updateFieldsVisibility(operationType);
updateQuery();
},
oneditinit: function () {
const node = this;
this.on("input", function (msg) {
const generatedQuery = $("#node-input-generated-query").val();
msg.topic = generatedQuery;
node.send(msg);
});
},
oneditsave: function () {
this.fields_values = fieldsValues.filter(
(item) =>
item.field &&
item.field.trim() !== "" &&
item.value &&
item.value.trim() !== ""
);
RED.nodes.dirty(true);
this.changed = true;
},
});
</script>