79720652

Date: 2025-07-31 00:33:25
Score: 0.5
Natty:
Report link

If this is what you want: Demo gif

Then here is what you need:

my_custom_nodes/
├── js/
│   └── TextOrFile.js
├── TextOrFile.py
└── __init__.py
# __init__.py

from .TextOrFile import TextOrFile
NODE_CLASS_MAPPINGS = { "TextOrFile": TextOrFile }
NODE_DISPLAY_NAME_MAPPINGS = { "TextOrFile": "Text or File" }
WEB_DIRECTORY = "./js"
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS", "WEB_DIRECTORY"]
# TextOrFile.py

class TextOrFile:
    CATEGORY = "Custom"
    
    @classmethod
    def INPUT_TYPES(cls):
        return {
            "required": {
                "mode": (["text", "file"],),
                "text_content": ("STRING", {"multiline": False, "default": "Text", "forceInput": False}),
                "file_path": ("STRING", {"multiline": False, "default": "/", "forceInput": False}),
            }
        }

    RETURN_TYPES = ("STRING",)
    FUNCTION     = "run"

    def run(self, mode, text_content, file_path):
        if mode == "text":
            return (text_content,)
        return (file_path,)
// js/TextOrFile.js

import { app } from "../../scripts/app.js";

app.registerExtension({
    name: "text_or_file_ui",
    async nodeCreated(node) {
        if (node.comfyClass !== "TextOrFile") return;

        // Locate the primary dropdown widget
        const modeWidget = node.widgets.find(w => w.name === "mode");
        const origCallback = modeWidget.callback;

        // Override its callback to add/remove inputs on change
        modeWidget.callback = (value) => {
            origCallback?.call(node, value);

            // Get widget indices
            const textWidgetIndex = node.widgets.findIndex(w => w.name === "text_content");
            const fileWidgetIndex = node.widgets.findIndex(w => w.name === "file_path");

            if (value === "text") {
                // Add text content widget
                if (textWidgetIndex === -1) node.addWidget("STRING", "text_content", "default-value-here");
                // Remove file path widget
                if (fileWidgetIndex !== -1) node.widgets.splice(fileWidgetIndex, 1);
            } else if (value === "file") {
                // Add file path widget
                if (fileWidgetIndex === -1) node.addWidget("STRING", "file_path", "default-file-path-here");
                 // Remove text content widget
                if (textWidgetIndex !== -1) node.widgets.splice(textWidgetIndex, 1);
            }

            // Force a redraw so the UI updates immediately
            node.setDirtyCanvas(true, true);
        };

        // Initialize once on node creation
        modeWidget.callback(modeWidget.value);
    }
});

Sources:

  1. https://docs.comfy.org/custom-nodes/js/javascript_hooks
  2. https://docs.comfy.org/custom-nodes/js/javascript_objects_and_hijacking
Reasons:
  • Probably link only (1):
  • Long answer (-1):
  • Has code block (-0.5):
  • Low reputation (1):
Posted by: Ulric Huot