jerosoler / Drawflow

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

Uncaught TypeError: Cannot read property 'offsetWidth' of undefined #154

Closed ishpreetkaurwebner closed 3 years ago

ishpreetkaurwebner commented 3 years ago

I am facing this error while importing Drawflow exported data.

image

Do you have any idea why this error?

I am adding my exported json data also. You can check why this exported data is creating this issue while importing

{"drawflow":{"Home":{"data":{"1":{"id":1,"name":"deal_action","data":{},"class":"no-border-text-style","html":"<div class=\"deal_action_div\"><input type=\"text\" name=\"deal_action_title\" class=\"form-control text-bg-active\" value=\"Update Deal\" maxlength=\"50\" style=\"display:inline;\" df-dealtitle readonly/><span style=\"float:right; cursor: pointer;\" onclick=\"openEditFlowModal()\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span></div>","typenode":false,"inputs":{},"outputs":{"output_1":{"connections":[{"node":"9","output":"input_1"}]}},"pos_x":228,"pos_y":4},"7":{"id":7,"name":"email","data":{"name":""},"class":"email_node","html":"\n <div class=\"deal_action_div\"><span><i class=\"fa fa-envelope\"></i></span><input type=\"text\" name=\"email-name\" class=\"form-control text-bg-active\" value=\"Send Email\" maxlength=\"50\" style=\"display:inline;\" df-email/>\n <div style=\"display: inline;\"><span style=\"float:right; cursor: pointer;\" onclick=\"openEditEmailModal(this)\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span>\n </div></div>\n ","typenode":false,"inputs":{"input_1":{"connections":[{"node":"9","input":"output_3"}]}},"outputs":{"output_1":{"connections":[]}},"pos_x":786,"pos_y":108},"8":{"id":8,"name":"email","data":{"name":""},"class":"email_node","html":"\n <div class=\"deal_action_div\"><span><i class=\"fa fa-envelope\"></i></span><input type=\"text\" name=\"email-name\" class=\"form-control text-bg-active\" value=\"Send Email1\" maxlength=\"50\" style=\"display:inline;\" df-email/>\n <div style=\"display: inline;\"><span style=\"float:right; cursor: pointer;\" onclick=\"openEditEmailModal(this)\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span>\n </div></div>\n ","typenode":false,"inputs":{"input_1":{"connections":[{"node":"9","input":"output_2"}]}},"outputs":{"output_1":{"connections":[]}},"pos_x":776,"pos_y":238},"9":{"id":9,"name":"decision","data":{"decisionname":"Decision","cond1":"condition1","cond2":"condition2"},"class":"decision_node","html":"\n <div class=\"deal_action_div\" style=\"width: 220px;\">\n <div class=\"decision_title_div\" style=\"padding-top: 5%;\">\n <span><i class=\"fa fa-lightbulb-o\"></i></span>\n <input type=\"text\" name=\"decision-name\" class=\"form-control text-bg-active\" maxlength=\"50\" style=\"display:inline;\" value=\"Decision\" df-decisionname=\"\">\n </div><div class=\"condition_div\" id=\"condition_div1\" style=\"padding-left:2%; margin-top: 10px;\"><input type=\"text\" name=\"cond1\" class=\"form-control\" df-cond1=\"\" value=\"condition1\"><span style=\"cursor: pointer;\" onclick=\"openEditConditionModal(this, 1)\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span></div><div class=\"condition_div\" id=\"condition_div2\" style=\"padding-left:2%; margin-top: 10px;\"><input type=\"text\" name=\"cond2\" class=\"form-control\" df-cond2=\"\" value=\"condition2\"><span style=\"cursor: pointer;\" onclick=\"openEditConditionModal(this, 2)\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span><span class=\"p-remove-condition\" data-attr-count=\"2\"><i class=\"fa fa-times\" aria-hidden=\"true\"></i></span></div><div class=\"condition_div\" id=\"condition_div3\" style=\"padding-left:2%; margin-top: 10px;\"><input type=\"text\" name=\"cond3\" class=\"form-control\" df-cond3=\"\" value=\"condition3\"><span style=\"cursor: pointer;\" onclick=\"openEditConditionModal(this, 3)\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span><span class=\"p-remove-condition\" data-attr-count=\"3\"><i class=\"fa fa-times\" aria-hidden=\"true\"></i></span></div><div class=\"condition_div\" id=\"condition_div6\" style=\"padding-left:2%; margin-top: 10px;\"><input type=\"text\" name=\"cond6\" class=\"form-control\" df-cond6=\"\" value=\"condition6\"><span style=\"cursor: pointer;\" onclick=\"openEditConditionModal(this, 6)\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span><span class=\"p-remove-condition\" data-attr-count=\"6\"><i class=\"fa fa-times\" aria-hidden=\"true\"></i></span></div><div class=\"condition_div\" id=\"condition_div7\" style=\"padding-left:2%; margin-top: 10px;\"><input type=\"text\" name=\"cond7\" class=\"form-control\" df-cond7=\"\" value=\"condition7\"><span style=\"cursor: pointer;\" onclick=\"openEditConditionModal(this, 7)\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span><span class=\"p-remove-condition\" data-attr-count=\"7\"><i class=\"fa fa-times\" aria-hidden=\"true\"></i></span></div><div class=\"condition_div\" id=\"condition_div8\" style=\"padding-left:2%; margin-top: 10px;\"><input type=\"text\" name=\"cond8\" class=\"form-control\" df-cond8=\"\" value=\"condition8\"><span style=\"cursor: pointer;\" onclick=\"openEditConditionModal(this, 8)\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span><span class=\"p-remove-condition\" data-attr-count=\"8\"><i class=\"fa fa-times\" aria-hidden=\"true\"></i></span></div><hr><p style=\"text-align:center;\">\n <span class=\"p-add-condition\"><i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i></span>\n </p>\n <hr>\n <div style=\"text-align:center; padding:2%;\">\n <label>Default</label> <br>None of the conditions satisfied\n </div>\n </div>\n ","typenode":false,"inputs":{"input_1":{"connections":[{"node":"1","input":"output_1"}]}},"outputs":{"output_1":{"connections":[]},"output_2":{"connections":[{"node":"8","output":"input_1"}]},"output_3":{"connections":[{"node":"7","output":"input_1"}]},"output_4":{"connections":[{"node":"11","output":"input_1"}]},"output_7":{"connections":[]},"output_8":{"connections":[{"node":"10","output":"input_1"}]},"output_9":{"connections":[]}},"pos_x":145.484375,"pos_y":138},"10":{"id":10,"name":"sms","data":{"name":""},"class":"sms_node","html":"\n <div class=\"deal_action_div\"><span><i class=\"fa fa-comments\"></i></span><input type=\"text\" name=\"sms-name\" class=\"form-control text-bg-active\" value=\"Send SMS\" maxlength=\"50\" style=\"display:inline;\" df-sms/>\n <div style=\"display: inline;\"><span style=\"float:right; cursor: pointer;\" onclick=\"openEditSmsModal(this)\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span>\n </div></div>\n ","typenode":false,"inputs":{"input_1":{"connections":[{"node":"9","input":"output_8"}]}},"outputs":{"output_1":{"connections":[]}},"pos_x":537.03125,"pos_y":361},"11":{"id":11,"name":"sms","data":{"name":""},"class":"sms_node","html":"\n <div class=\"deal_action_div\"><span><i class=\"fa fa-comments\"></i></span><input type=\"text\" name=\"sms-name\" class=\"form-control text-bg-active\" value=\"Send SMS1\" maxlength=\"50\" style=\"display:inline;\" df-sms/>\n <div style=\"display: inline;\"><span style=\"float:right; cursor: pointer;\" onclick=\"openEditSmsModal(this)\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span>\n </div></div>\n ","typenode":false,"inputs":{"input_1":{"connections":[{"node":"9","input":"output_4"}]}},"outputs":{"output_1":{"connections":[]}},"pos_x":555.03125,"pos_y":58}}}}}

jerosoler commented 3 years ago

The problem is that it cannot find the output at "node 9" "output_8".

I see that the exits are skipped. Have you modified the addNodeImport () function?

Can you pass the modified addNodeImport function to be able to debug?

ishpreetkaurwebner commented 3 years ago

Yes, that was due to for lines of code in addNodeImort() function:

for(var x = 0; x < Object.keys(dataNode.outputs).length; x++) {
      const output = document.createElement('div');
      output.classList.add("output");
      output.classList.add("output_"+(x+1));
      outputs.appendChild(output);
   }

I have changed above lines to following:

Object.keys(dataNode.outputs).forEach(key => {
      const output = document.createElement('div');
      output.classList.add("output");
      output.classList.add(key);
      outputs.appendChild(output);
    });

I think you can modify your for loop into forEach in your git js and minified js files because forEach will work for all cases, like for sequential order and non-sequential order both.

jerosoler commented 3 years ago

Not error with addNodeImport modify:

<!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 {
            width: 100%;
            height: 600px;
            border: 1px solid red;
        }

    </style>
</head>
<body>
    <div id="drawflow"></div>
    <script>
    var id = document.getElementById("drawflow");
    const editor = new Drawflow(id);
    editor.reroute = true;
    editor.reroute_fix_curvature = true;

    editor.addNodeImport = function(dataNode, precanvas) {
    const parent = document.createElement('div');
    parent.classList.add("parent-node");

    const node = document.createElement('div');
    node.innerHTML = "";
    node.setAttribute("id", "node-"+dataNode.id);
    node.classList.add("drawflow-node");
    if(dataNode.class != '') {
      node.classList.add(dataNode.class);
    }

    const inputs = document.createElement('div');
    inputs.classList.add("inputs");

    const outputs = document.createElement('div');
    outputs.classList.add("outputs");

    Object.keys(dataNode.inputs).map(function(input_item, index) {
      const input = document.createElement('div');
      input.classList.add("input");
      input.classList.add(input_item);
      inputs.appendChild(input);
      Object.keys(dataNode.inputs[input_item].connections).map(function(output_item, index) {

        var connection = document.createElementNS('http://www.w3.org/2000/svg',"svg");
        var path = document.createElementNS('http://www.w3.org/2000/svg',"path");
        path.classList.add("main-path");
        path.setAttributeNS(null, 'd', '');
        // path.innerHTML = 'a';
        connection.classList.add("connection");
        connection.classList.add("node_in_node-"+dataNode.id);
        connection.classList.add("node_out_node-"+dataNode.inputs[input_item].connections[output_item].node);
        connection.classList.add(dataNode.inputs[input_item].connections[output_item].input);
        connection.classList.add(input_item);

        connection.appendChild(path);
        precanvas.appendChild(connection);

      });
    });

/*
    for(var x = 0; x < Object.keys(dataNode.outputs).length; x++) {
      const output = document.createElement('div');
      output.classList.add("output");
      output.classList.add("output_"+(x+1));
      outputs.appendChild(output);
    } */
    Object.keys(dataNode.outputs).forEach(key => {
      const output = document.createElement('div');
      output.classList.add("output");
      output.classList.add(key);
      outputs.appendChild(output);
    });

    const content = document.createElement('div');
    content.classList.add("drawflow_content_node");
    //content.innerHTML = dataNode.html;

    if(dataNode.typenode === false) {
      content.innerHTML = dataNode.html;
    } else if (dataNode.typenode === true) {
      content.appendChild(this.noderegister[dataNode.html].html.cloneNode(true));
    } else {
      if(parseInt(this.render.version) === 3 ) {
        //Vue 3
        let wrapper = this.render.createApp({
          render: h => this.render.h(this.noderegister[dataNode.html].html, this.noderegister[dataNode.html].props, this.noderegister[dataNode.html].options)
        }).mount(content)
      } else {
        //Vue 2
        let wrapper = new this.render({
          render: h => h(this.noderegister[dataNode.html].html, { props: this.noderegister[dataNode.html].props }),
          ...this.noderegister[dataNode.html].options
        }).$mount()
        content.appendChild(wrapper.$el);
      }
    }

    Object.entries(dataNode.data).forEach(function (key, value) {
      if(typeof key[1] === "object") {
        insertObjectkeys(null, key[0], key[0]);
      } else {
        var elems = content.querySelectorAll('[df-'+key[0]+']');
          for(var i = 0; i < elems.length; i++) {
            elems[i].value = key[1];
          }
      }
    })

    function insertObjectkeys(object, name, completname) {
      if(object === null) {
        var object = dataNode.data[name];
      } else {
        var object = object[name]
      }
      if(object !== null) {
        Object.entries(object).forEach(function (key, value) {
          if(typeof key[1] === "object") {
            insertObjectkeys(object, key[0], name+'-'+key[0]);
          } else {
            var elems = content.querySelectorAll('[df-'+completname+'-'+key[0]+']');
              for(var i = 0; i < elems.length; i++) {
                elems[i].value = key[1];
              }
          }
        });
      }
    }
    node.appendChild(inputs);
    node.appendChild(content);
    node.appendChild(outputs);
    node.style.top = dataNode.pos_y + "px";
    node.style.left = dataNode.pos_x + "px";
    parent.appendChild(node);
    this.precanvas.appendChild(parent);
  }

    editor.start();

    editor.import({"drawflow":{"Home":{"data":{"1":{"id":1,"name":"deal_action","data":{},"class":"no-border-text-style","html":"<div class=\"deal_action_div\"><input type=\"text\" name=\"deal_action_title\" class=\"form-control text-bg-active\" value=\"Update Deal\" maxlength=\"50\" style=\"display:inline;\" df-dealtitle readonly/><span style=\"float:right; cursor: pointer;\" onclick=\"openEditFlowModal()\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span></div>","typenode":false,"inputs":{},"outputs":{"output_1":{"connections":[{"node":"9","output":"input_1"}]}},"pos_x":228,"pos_y":4},"7":{"id":7,"name":"email","data":{"name":""},"class":"email_node","html":"\n <div class=\"deal_action_div\"><span><i class=\"fa fa-envelope\"></i></span><input type=\"text\" name=\"email-name\" class=\"form-control text-bg-active\" value=\"Send Email\" maxlength=\"50\" style=\"display:inline;\" df-email/>\n <div style=\"display: inline;\"><span style=\"float:right; cursor: pointer;\" onclick=\"openEditEmailModal(this)\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span>\n </div></div>\n ","typenode":false,"inputs":{"input_1":{"connections":[{"node":"9","input":"output_3"}]}},"outputs":{"output_1":{"connections":[]}},"pos_x":786,"pos_y":108},"8":{"id":8,"name":"email","data":{"name":""},"class":"email_node","html":"\n <div class=\"deal_action_div\"><span><i class=\"fa fa-envelope\"></i></span><input type=\"text\" name=\"email-name\" class=\"form-control text-bg-active\" value=\"Send Email1\" maxlength=\"50\" style=\"display:inline;\" df-email/>\n <div style=\"display: inline;\"><span style=\"float:right; cursor: pointer;\" onclick=\"openEditEmailModal(this)\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span>\n </div></div>\n ","typenode":false,"inputs":{"input_1":{"connections":[{"node":"9","input":"output_2"}]}},"outputs":{"output_1":{"connections":[]}},"pos_x":776,"pos_y":238},"9":{"id":9,"name":"decision","data":{"decisionname":"Decision","cond1":"condition1","cond2":"condition2"},"class":"decision_node","html":"\n <div class=\"deal_action_div\" style=\"width: 220px;\">\n <div class=\"decision_title_div\" style=\"padding-top: 5%;\">\n <span><i class=\"fa fa-lightbulb-o\"></i></span>\n <input type=\"text\" name=\"decision-name\" class=\"form-control text-bg-active\" maxlength=\"50\" style=\"display:inline;\" value=\"Decision\" df-decisionname=\"\">\n </div><div class=\"condition_div\" id=\"condition_div1\" style=\"padding-left:2%; margin-top: 10px;\"><input type=\"text\" name=\"cond1\" class=\"form-control\" df-cond1=\"\" value=\"condition1\"><span style=\"cursor: pointer;\" onclick=\"openEditConditionModal(this, 1)\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span></div><div class=\"condition_div\" id=\"condition_div2\" style=\"padding-left:2%; margin-top: 10px;\"><input type=\"text\" name=\"cond2\" class=\"form-control\" df-cond2=\"\" value=\"condition2\"><span style=\"cursor: pointer;\" onclick=\"openEditConditionModal(this, 2)\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span><span class=\"p-remove-condition\" data-attr-count=\"2\"><i class=\"fa fa-times\" aria-hidden=\"true\"></i></span></div><div class=\"condition_div\" id=\"condition_div3\" style=\"padding-left:2%; margin-top: 10px;\"><input type=\"text\" name=\"cond3\" class=\"form-control\" df-cond3=\"\" value=\"condition3\"><span style=\"cursor: pointer;\" onclick=\"openEditConditionModal(this, 3)\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span><span class=\"p-remove-condition\" data-attr-count=\"3\"><i class=\"fa fa-times\" aria-hidden=\"true\"></i></span></div><div class=\"condition_div\" id=\"condition_div6\" style=\"padding-left:2%; margin-top: 10px;\"><input type=\"text\" name=\"cond6\" class=\"form-control\" df-cond6=\"\" value=\"condition6\"><span style=\"cursor: pointer;\" onclick=\"openEditConditionModal(this, 6)\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span><span class=\"p-remove-condition\" data-attr-count=\"6\"><i class=\"fa fa-times\" aria-hidden=\"true\"></i></span></div><div class=\"condition_div\" id=\"condition_div7\" style=\"padding-left:2%; margin-top: 10px;\"><input type=\"text\" name=\"cond7\" class=\"form-control\" df-cond7=\"\" value=\"condition7\"><span style=\"cursor: pointer;\" onclick=\"openEditConditionModal(this, 7)\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span><span class=\"p-remove-condition\" data-attr-count=\"7\"><i class=\"fa fa-times\" aria-hidden=\"true\"></i></span></div><div class=\"condition_div\" id=\"condition_div8\" style=\"padding-left:2%; margin-top: 10px;\"><input type=\"text\" name=\"cond8\" class=\"form-control\" df-cond8=\"\" value=\"condition8\"><span style=\"cursor: pointer;\" onclick=\"openEditConditionModal(this, 8)\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span><span class=\"p-remove-condition\" data-attr-count=\"8\"><i class=\"fa fa-times\" aria-hidden=\"true\"></i></span></div><hr><p style=\"text-align:center;\">\n <span class=\"p-add-condition\"><i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i></span>\n </p>\n <hr>\n <div style=\"text-align:center; padding:2%;\">\n <label>Default</label> <br>None of the conditions satisfied\n </div>\n </div>\n ","typenode":false,"inputs":{"input_1":{"connections":[{"node":"1","input":"output_1"}]}},"outputs":{"output_1":{"connections":[]},"output_2":{"connections":[{"node":"8","output":"input_1"}]},"output_3":{"connections":[{"node":"7","output":"input_1"}]},"output_4":{"connections":[{"node":"11","output":"input_1"}]},"output_7":{"connections":[]},"output_8":{"connections":[{"node":"10","output":"input_1"}]},"output_9":{"connections":[]}},"pos_x":145.484375,"pos_y":138},"10":{"id":10,"name":"sms","data":{"name":""},"class":"sms_node","html":"\n <div class=\"deal_action_div\"><span><i class=\"fa fa-comments\"></i></span><input type=\"text\" name=\"sms-name\" class=\"form-control text-bg-active\" value=\"Send SMS\" maxlength=\"50\" style=\"display:inline;\" df-sms/>\n <div style=\"display: inline;\"><span style=\"float:right; cursor: pointer;\" onclick=\"openEditSmsModal(this)\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span>\n </div></div>\n ","typenode":false,"inputs":{"input_1":{"connections":[{"node":"9","input":"output_8"}]}},"outputs":{"output_1":{"connections":[]}},"pos_x":537.03125,"pos_y":361},"11":{"id":11,"name":"sms","data":{"name":""},"class":"sms_node","html":"\n <div class=\"deal_action_div\"><span><i class=\"fa fa-comments\"></i></span><input type=\"text\" name=\"sms-name\" class=\"form-control text-bg-active\" value=\"Send SMS1\" maxlength=\"50\" style=\"display:inline;\" df-sms/>\n <div style=\"display: inline;\"><span style=\"float:right; cursor: pointer;\" onclick=\"openEditSmsModal(this)\"><i class=\"fa fa-pencil\" aria-hidden=\"true\"></i></span>\n </div></div>\n ","typenode":false,"inputs":{"input_1":{"connections":[{"node":"9","input":"output_4"}]}},"outputs":{"output_1":{"connections":[]}},"pos_x":555.03125,"pos_y":58}}}}})

    </script>
</body>
</html>
ishpreetkaurwebner commented 3 years ago

@jerosoler : Thanks a lot. You are awesome. You have build an awesome library and you gives reply quickly.