Skip to content

Commit

Permalink
Merge pull request #28 from SoopSASM/feature/dropdown-node
Browse files Browse the repository at this point in the history
[add] dropdown node
  • Loading branch information
gemnsh authored Sep 29, 2022
2 parents 16c9573 + 9c7cff6 commit 76b24aa
Show file tree
Hide file tree
Showing 2 changed files with 516 additions and 0 deletions.
319 changes: 319 additions & 0 deletions dashboard/nodes/soop_dropdown.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,319 @@
<style></style>
<script type="text/javascript">
RED.nodes.registerType("soop_dropdown", {
category: "soop-dashboard",
color: "rgb(255, 189, 27)",
defaults: {
name: {
value: "",
},
label: {
value: "dropdown",
},
tooltip: {
value: "",
},
place: { value: "Select" },
group: {
type: "soop_group",
required: true,
},
order: {
value: 0,
},
width: {
value: 0,
validate: function (v) {
var width = v || 0;
var currentGroup = $("#node-input-group").val() || this.group;
var groupNode = RED.nodes.node(currentGroup);
var valid = !groupNode || +width <= +groupNode.width;
$("#node-input-size").toggleClass("input-error", !valid);
return valid;
},
},
height: {
value: 0,
validate: function (v) {
var height = v || 0;
var currentGroup = $("#node-input-group").val() || this.group;
var groupNode = RED.nodes.node(currentGroup);
var valid = !groupNode || +height <= +groupNode.height;
$("#node-input-size").toggleClass("input-error", !valid);
return valid;
},
},
options: {
value: [{ value: "", label: "" }],
validate: function (v) {
var unique = new Set(
v.map(function (o) {
return o.value;
})
);
return v.length == unique.size;
},
},
payload: { value: "" },
topic: {
value: "topic",
validate: RED.validators.hasOwnProperty("typedInput")
? RED.validators.typedInput("topicType")
: function (v) {
return true;
},
},
passthru: { value: true },
multipleSelect: { value: false },
topicType: {
value: "msg",
},
},
inputs: 1,
outputs: 1,
icon: "ui_switch.png",
paletteLabel: "dropdown",
outputLabels: function () {
return this.min + " - " + this.max;
},
label: function () {
return (
this.name ||
(~this.label.indexOf("{{") ? null : this.label) ||
"dropdown"
);
},
labelStyle: function () {
return this.name ? "node_label_italic" : "";
},
oneditprepare: function () {
if (this.multiple === undefined) {
$("#node-input-multiple").prop("checked", false);
}
$("#node-input-size").elementSizer({
width: "#node-input-width",
height: "#node-input-height",
group: "#node-input-group",
});
var un = new Set(
this.options.map(function (o) {
return o.value;
})
);
if (this.options.length == un.size) {
$("#valWarning").hide();
} else {
$("#valWarning").show();
}

function generateOption(i, option) {
var container = $("<li/>", {
style:
"background: #fff; margin:0; padding:8px 0px 0px; border-bottom: 1px solid #ccc;",
});
var row = $("<div/>").appendTo(container);
var row2 = $("<div/>", {
style: "padding-top:5px; padding-left:175px;",
}).appendTo(container);
var row3 = $("<div/>", {
style: "padding-top:5px; padding-left:120px;",
}).appendTo(container);

$(
'<i style="color:#eee; cursor:move; margin-left:3px;" class="node-input-option-handle fa fa-bars"></i>'
).appendTo(row);

var valueField = $("<input/>", {
class: "node-input-option-value",
type: "text",
style: "margin-left:7px; width:calc(50% - 32px);",
placeholder: "Value",
value: option.value,
})
.appendTo(row)
.typedInput({
default: option.type || "str",
types: ["str", "num", "bool"],
});
var labelField = $("<input/>", {
class: "node-input-option-label",
type: "text",
style: "margin-left:7px; width:calc(50% - 32px);",
placeholder: "Label",
value: option.label,
}).appendTo(row);

var finalspan = $("<span/>", {
style: "float:right; margin-right:8px;",
}).appendTo(row);
var deleteButton = $("<a/>", {
href: "#",
class: "editor-button editor-button-small",
style: "margin-top:7px; margin-left:5px;",
}).appendTo(finalspan);
$("<i/>", { class: "fa fa-remove" }).appendTo(deleteButton);

deleteButton.click(function () {
container.css({ background: "#fee" });
container.fadeOut(300, function () {
$(this).remove();
});
});

$("#node-input-option-container").append(container);
}

$("#node-input-add-option").click(function () {
generateOption(
$("#node-input-option-container").children().length + 1,
{}
);
$("#node-input-option-container-div").scrollTop(
$("#node-input-option-container-div").get(0).scrollHeight
);
});

for (var i = 0; i < this.options.length; i++) {
var option = this.options[i];
generateOption(i + 1, option);
}

$("#node-input-option-container").sortable({
axis: "y",
handle: ".node-input-option-handle",
cursor: "move",
});

$("#node-input-topic").typedInput({
default: "str",
typeField: $("#node-input-topicType"),
types: ["str", "msg", "flow", "global"],
});
},
oneditsave: function () {
var options = $("#node-input-option-container").children();
var node = this;
node.options = [];
options.each(function (i) {
var option = $(this);
var o = {
label: option.find(".node-input-option-label").val(),
value: option.find(".node-input-option-value").typedInput("value"),
type: option.find(".node-input-option-value").typedInput("type"),
};
if (
option.find(".node-input-option-value").typedInput("type") === "num"
) {
o.value = Number(o.value);
}
if (
option.find(".node-input-option-value").typedInput("type") === "bool"
) {
o.value = o.value == "true";
}
node.options.push(o);
});
},
oneditresize: function () {},
});
</script>

<script type="text/html" data-template-name="soop_dropdown">
<div class="form-row">
<label for="node-input-group"><i class="fa fa-table"></i> Group</label>
<input type="text" id="node-input-group" />
</div>
<div class="form-row">
<label><i class="fa fa-object-group"></i> Size</label>
<input type="hidden" id="node-input-width" />
<input type="hidden" id="node-input-height" />
<button class="editor-button" id="node-input-size"></button>
</div>
<div class="form-row">
<label for="node-input-label"><i class="fa fa-tag"></i> Label</label>
<input type="text" id="node-input-label" placeholder="optional label" />
</div>
<div class="form-row">
<label for="node-input-tooltip"
><i class="fa fa-info-circle"></i> Tooltip</label
>
<input type="text" id="node-input-tooltip" placeholder="optional tooltip" />
</div>
<div class="form-row">
<label for="node-input-place"><i class="fa fa-tag"></i> Placeholder</label>
<input
type="text"
id="node-input-place"
placeholder="optional placeholder"
/>
</div>
<div
class="form-row node-input-option-container-row"
style="margin-bottom: 0px;width: 100%"
>
<label for="node-input-width" style="vertical-align:top"
><i class="fa fa-list-alt"></i> Options</label
>
<div
id="node-input-option-container-div"
style="box-sizing:border-box; border-radius:5px; height:257px; padding:5px; border:1px solid #ccc; overflow-y:scroll; display:inline-block; width:calc(70% + 15px);"
>
<span id="valWarning" style="color:#910000"
><b>All Values must be unique.</b></span
>
<ol
id="node-input-option-container"
style="list-style-type:none; margin:0;"
></ol>
</div>
</div>
<div class="form-row">
<a
href="#"
class="editor-button editor-button-small"
id="node-input-add-option"
style="margin-top:4px; margin-left:103px;"
><i class="fa fa-plus"></i> <span>option</span></a
>
</div>
<div class="form-row">
<label style="width:auto" for="node-input-multiple"
><i class="fa fa-th-list"></i> Allow multiple selections from list:
</label>
<input
type="checkbox"
checked
id="node-input-multiple"
style="display:inline-block; width:auto; vertical-align:top;"
/>
</div>
<div class="form-row">
<label style="width:auto" for="node-input-passthru"
><i class="fa fa-arrow-right"></i> If <code>msg</code> arrives on input,
pass through to output:
</label>
<input
type="checkbox"
checked
id="node-input-passthru"
style="display:inline-block; width:auto; vertical-align:top;"
/>
</div>
<div class="form-row">
<label for="node-input-topic"><i class="fa fa-tasks"></i> Topic</label>
<input type="text" id="node-input-topic" placeholder="optional msg.topic" />
<input type="hidden" id="node-input-topicType" />
</div>
<div class="form-row">
<label for="node-input-className"><i class="fa fa-code"></i> Class</label>
<input
type="text"
id="node-input-className"
placeholder="Optional CSS class name(s) for widget"
/>
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" />
</div>
</script>
Loading

0 comments on commit 76b24aa

Please sign in to comment.