dimanche 24 mai 2020

How to access div's id from if/else statement in React Js?

I'm trying to add a responsive connecting line between 3 divs in a React Js project, I was able to add a line between elements, but when I'm using Axios to fetch the data and display it with if/else statement, my React project gives me an error saying "Cannot read property 'left' of undefined -var originX = this.ele1.offset().left + this.ele1.outerWidth() / 2;

This is my code with axios:

import React, { useState, useEffect } from "react";
import "./styles.css";
import $ from "jquery";
import axios from "axios";

export default function App() {
  const [solutions, setSolutions] = useState([]);

  const getSolutions = async () => {
    const response = await axios.get("./data.json");
    setSolutions(response.data.home);
  };
  useEffect(() => {
    getSolutions();
  }, []);

  var Connector = function(params) {
    if (typeof params === "undefined") {
      return false;
    }
    var ele1 = params.ele1 || "";
    var ele2 = params.ele2 || "";
    if (ele1.length === 0 || ele2.length === 0) {
      return false;
    }

    var className = params.class || "Connector";

    this.gapX1 = params.gapX1 || 0;
    this.gapY1 = params.gapY1 || 0;
    this.gapX2 = params.gapX2 || 0;
    this.gapY2 = params.gapY2 || 0;

    this.gap = params.gap || 0;
    if (this.gap > 0) {
      this.gapX1 = this.gap;
      this.gapY1 = this.gap;
      this.gapX2 = this.gap;
      this.gapY2 = this.gap;
    }

    var pos = function() {
      this.left = 0;
      this.top = 0;
    };

    this.PseudoGuid = new function() {
      this.empty = "00000000-0000-0000-0000-000000000000";
      this.GetNew = function() {
        var fC = function() {
          return (((1 + Math.random()) * 0x10000) | 0)
            .toString(16)
            .substring(1)
            .toUpperCase();
        };
        return (
          fC() +
          fC() +
          "-" +
          fC() +
          "-" +
          fC() +
          "-" +
          fC() +
          "-" +
          fC() +
          fC() +
          fC()
        );
      };
    }();

    this.id = this.PseudoGuid.GetNew();
    this.ele1 = $("#" + ele1);
    this.ele2 = $("#" + ele2);

    this.lineID = "L" + this.id;
    $("body").append(
      "<div id='" + this.lineID + "' class='" + className + "' style=  ></div>"
    );
    this.line = $("#L" + this.id);
    this.line.css({
      position: "absolute",
      "border-left": this.lineStyle,
      "z-index": -100
    });

    this.offsets = [];
    this.offsets[ele1] = new pos();
    this.offsets[ele2] = new pos();

    this.link(); //
  };

  Connector.prototype.link = function link() {
    var originX = this.ele1.offset().left + this.ele1.outerWidth() / 2;
    var originY = this.ele1.offset().top + this.ele1.outerHeight() / 2;

    var targetX = this.ele2.offset().left + this.ele2.outerWidth() / 2;
    var targetY = this.ele2.offset().top + this.ele2.outerHeight() / 2;

    var l = this.hyp(targetX - originX, targetY - originY);
    var angle = (180 / 3.1415) * Math.acos((targetY - originY) / l);
    if (targetX > originX) {
      angle = angle * -1;
    }

    var adj1 = this.edgeAdjust(
      angle,
      this.gapX1 + this.ele1.width() / 2,
      this.gapY1 + this.ele1.height() / 2
    );
    var adj2 = this.edgeAdjust(
      angle,
      this.gapX2 + this.ele2.width() / 2,
      this.gapY2 + this.ele2.height() / 2
    );

    l = l - (adj1.hp + adj2.hp);

    this.line
      .css({ left: originX, height: l, width: 0, top: originY + adj1.hp })
      .css("-webkit-transform", "rotate(" + angle + "deg)")
      .css("-moz-transform", "rotate(" + angle + "deg)")
      .css("-o-transform", "rotate(" + angle + "deg)")
      .css("-ms-transform", "rotate(" + angle + "deg)")
      .css("transform", "rotate(" + angle + "deg)")
      .css("transform-origin", "0 " + -1 * adj1.hp + "px");
  };

  Connector.prototype.Round = function(value, places) {
    var multiplier = Math.pow(10, places);
    return Math.round(value * multiplier) / multiplier;
  };

  Connector.prototype.edgeAdjust = function(a, w1, h1) {
    var w = 0,
      h = 0;

    var ca = [];
    ca[0] = (Math.atan(w1 / h1) * 180) / 3.1415926;
    ca[1] = 180 - ca[0];
    ca[2] = ca[0] + 180;
    ca[3] = ca[1] + 180;

    if (this.Round(a, 0) === 0) {
      h = h1;
      w = 0;
    } else if (this.Round(a, 0) === 180) {
      h = h1;
      w = 0;
    } else if ((a > 0 && a <= ca[0]) || (a < 0 && a >= -1 * ca[0])) {
      h = h1;
      w = -1 * Math.tan(a * (3.1415926 / 180)) * h1;
    } else if (a > ca[0] && a <= 90) {
      h = Math.tan((90 - a) * (3.1415926 / 180)) * w1;
      w = w1;
    } else if (a > 90 && a <= ca[1]) {
      h = -1 * Math.tan((a - 90) * (3.1415926 / 180)) * w1;
      w = w1;
    } else if (a > ca[1] && a <= 180) {
      h = h1;
      w = -1 * Math.tan((180 - a) * (3.1415926 / 180)) * h1;
    } else if (a > -180 && a <= -1 * ca[1]) {
      h = h1;
      w = Math.tan((a - 180) * (3.1415926 / 180)) * h1;
    } else if (a > -1 * ca[1] && a <= 0) {
      h = Math.tan((a - 90) * (3.1415926 / 180)) * w1;
      w = w1;
    }

    // We now have the width and height offsets - compute the hypotenuse.
    var hp = this.hyp(w, h);

    return { hp: hp };
  };

  Connector.prototype.hyp = function hyp(X, Y) {
    return Math.abs(Math.sqrt(X * X + Y * Y));
  };

  Connector.prototype.moved = function moved(e, ele) {
    this.link();
  };

  $(document).ready(function() {
    var c1 = new Connector({
      ele1: "a",
      ele2: "b",
      lineStyle: "1px solid #b8c6f2"
    });
    Setup(c1, "a");
    Setup(c1, "b");

    var c2 = new Connector({
      ele1: "b",
      ele2: "c",
      lineStyle: "1px solid ##b8c6f2"
    });
    Setup(c2, "b");
    Setup(c2, "c");

    function Setup(connector, id) {
      var ele = $("#" + id);
      ele.on("mousedown.Connector", function(e) {
        //#critical: tell the connector about the starting position when the mouse goes down.
        connector.offsets[id].left = e.pageX - ele.offset().left;
        connector.offsets[id].top = e.pageY - ele.offset().top;

        e.preventDefault();
      });
    }
  });
  if (solutions.length) {
    return (
      <div className="App">
        <div className="App">
          <div className="divs">
            {solutions.map(({ id, text, title }) => {
              return <h1>{title}</h1>;
            })}
            <div id="a"> 1 </div>
            <div id="b"> 2</div>
            <div id="c"> 3</div>
          </div>
        </div>
      </div>
    );
  } else {
    return null;
  }
}

This is a link to codesandbox's example with a working line (without Axios) : working

This is a link to the Axios version of this code : not working

If anyone can explain why using if/else statement is blocking code from drawing a line between divs and how to fix it, I'll be very grateful.

P.s. code to draw a line is not mine, I just modified it for my project.

Aucun commentaire:

Enregistrer un commentaire