jerosoler / Drawflow

Simple flow library 🖥️🖱️
https://jerosoler.github.io/Drawflow/
MIT License
4.65k stars 722 forks source link

Redraw dynamic outputs #537

Closed sunco007 closed 1 year ago

sunco007 commented 1 year ago

First, thanks for this great library, y saludos desde México

I want to create a flow for a Whatsapp chat. The main node is just a text, but user must be able to add buttons

This can be done with some jquery append and addNodeOutput

The thing is that I'm using [this code] (https://github.com/jerosoler/Drawflow/issues/363) (the one inside nodeCreated event) to align outputs, but just can't make it work

My node content is this:

<!--
<div>
      <div class="title-box"><i class="far fa-comment-alt"></i> Mensaje</div>
      <div class="box">
            <textarea placeholder="Just a test" df-mensajex readonly></textarea>
      </div>
</div>
-->

Then add the "button" with this

<!-- $(".box").append('<div class="panel"><input type="text" class="boton" df-btn1 value="Si" readonly><div class="link output_1"></div></div>'); -->

And now I call the redraw (363)

It works fine. But then I add another "button", run addNodeOutput method and the redraw one

Got this:

image image

I tried updating the connections but is the same result:

editor.updateConnectionNodes(1); editor.updateConnectionNodes("node-1");

jerosoler commented 1 year ago

Hello, Saludos!

I think the problem is that when you add a button it is always passing "link output_1" ???

Try:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/gh/jerosoler/Drawflow/dist/drawflow.min.css"
    />
    <script src="https://cdn.jsdelivr.net/gh/jerosoler/Drawflow/dist/drawflow.min.js"></script>
    <style>
      #drawflow {
        position: relative;
        width: 100%;
        height: 800px;
        border: 1px solid red;
      }
      textarea {
          width: 100%;
          height: 70px;
      }
      button {
          width: 100%;
          height: 30px;

      }
      </style>
  </head>
  <body>
    <div>
        <div id="drawflow"></div>  
        <button onClick="addButton()">AddButon</button>
    </div>
    <script>

    var id = document.getElementById("drawflow");

    const editor = new Drawflow(id);
    editor.start();

    editor.addNode('test1', 1, 1, 200, 300, 'test1', {}, '<textarea></textarea><div id="content"></div>');

    const addButton = () => {
        const content = document.getElementById("content");
        const buttons = [...document.querySelectorAll("#content .link")].length;

        console.log(buttons);
        const button = document.createElement('button');
        if(buttons % 2) {
            button.innerText = "Si";
        } else {
            button.innerText = "No";
        }

        button.classList.add("link");
        const number = buttons+1;
        button.classList.add(`output_${number}`);
        content.appendChild(button);
        setTimeout(addConnection(number),250);

    }

    const addConnection = (number) => {
        const id = 1
        editor.addNodeOutput(id); 
        const item = document.querySelector(`#node-${id} .drawflow_content_node .link.output_${number}`);
        const target = document.querySelector(`#node-${id} .outputs .output_${number}`)
        if(target != null) {
                const pos = item.getBoundingClientRect();
                const targetPos = target.getBoundingClientRect();
                target.style.top = `${pos.y - targetPos.y}px`;
                target.style.left = `${pos.x - targetPos.x}px`;
        }

    }

</script> 
  </body>
</html>
sunco007 commented 1 year ago

Uhm.. let me read, understand and then apply your code

About the output, yes, I use number 2 for the second

$(".box").append('<div class="panel"><input type="text" class="boton" df-btn1 value="Si" readonly><div class="link output_1"></div></div>');

redrawNode(1);

$(".box").append('<div class="panel"><input type="text" class="boton" df-btn2 value="No" readonly><div class="link output_2"></div></div>');

editor.addNodeOutput(1);

redrawNode(1);

image

AhmedEl5WaGa commented 1 year ago

Hello, Saludos!

I think the problem is that when you add a button it is always passing "link output_1" ???

Try:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/gh/jerosoler/Drawflow/dist/drawflow.min.css"
    />
    <script src="https://cdn.jsdelivr.net/gh/jerosoler/Drawflow/dist/drawflow.min.js"></script>
    <style>
      #drawflow {
        position: relative;
        width: 100%;
        height: 800px;
        border: 1px solid red;
      }
      textarea {
          width: 100%;
          height: 70px;
      }
      button {
          width: 100%;
          height: 30px;

      }
      </style>
  </head>
  <body>
    <div>
        <div id="drawflow"></div>  
        <button onClick="addButton()">AddButon</button>
    </div>
    <script>

    var id = document.getElementById("drawflow");

    const editor = new Drawflow(id);
    editor.start();

    editor.addNode('test1', 1, 1, 200, 300, 'test1', {}, '<textarea></textarea><div id="content"></div>');

    const addButton = () => {
        const content = document.getElementById("content");
        const buttons = [...document.querySelectorAll("#content .link")].length;

        console.log(buttons);
        const button = document.createElement('button');
        if(buttons % 2) {
            button.innerText = "Si";
        } else {
            button.innerText = "No";
        }

        button.classList.add("link");
        const number = buttons+1;
        button.classList.add(`output_${number}`);
        content.appendChild(button);
        setTimeout(addConnection(number),250);

    }

    const addConnection = (number) => {
        const id = 1
        editor.addNodeOutput(id); 
        const item = document.querySelector(`#node-${id} .drawflow_content_node .link.output_${number}`);
        const target = document.querySelector(`#node-${id} .outputs .output_${number}`)
        if(target != null) {
                const pos = item.getBoundingClientRect();
                const targetPos = target.getBoundingClientRect();
                target.style.top = `${pos.y - targetPos.y}px`;
                target.style.left = `${pos.x - targetPos.x}px`;
        }

    }

</script> 
  </body>
</html>

hello @jerosoler thanks for your effort, i used this type to add outputs but when i add one it comes with wrong location here is video

https://user-images.githubusercontent.com/43081583/207222729-586c1438-6ddb-4fb1-81ea-dea6f0e8666e.mp4

jerosoler commented 1 year ago

When adding new outputs, you may have to reorder all the outputs again.

It will also use the method to force connections correctly. updateConnectionNodes('node-1')