If the user decides to change their answer, the current line between the two DIVs will be removed

After clicking on two DIVs, I created two lines. Now, I am facing an issue with resetting the unwanted line when changing my answer.

To reset the line, you can refer to the code snippet below:


                var lastSelection;

                // Add click listener for answer-container
                function listenToClick() {
                    var rows = document.querySelectorAll('.row'),
                        row;
                    var cols, col;

                    for (row = 0; row < rows.length; row++) {
                        cols = rows[row].children;

                        for (col = 0; col < cols.length; col++) {
                            // Bind information about which answer is this,
                            // so we can prevent from connecting two answers on
                            // same column.
                            cols[col].addEventListener('click', selectAnswer.bind({
                                row: row,
                                col: col,
                                element: cols[col]
                            }));
                        }
                    }
                }

                // This is fired when a answer-container is clicked.
                function selectAnswer(event) {
                    if (lastSelection) {
                        lastSelection.element.classList.remove('selected');
                    }

                    if (!lastSelection || lastSelection.col === this.col) {
                        lastSelection = this;
                        this.element.classList.add('selected');
                    } else {
                        drawLine(getPoint(this.element), getPoint(lastSelection.element));
                        lastSelection = null;
                    }
                }

                function getPoint(answerElement) {
                    var roundPointer = answerElement.lastElementChild;

                    return {
                        y: answerElement.offsetTop + roundPointer.offsetTop + roundPointer.offsetHeight / 2,
                        x: answerElement.offsetLeft + roundPointer.offsetLeft + roundPointer.offsetWidth / 2
                    };
                }

                function drawLine(p1, p2) {
                    var canvas = document.getElementById("connection-canvas");
                    var ctx = canvas.getContext("2d");

                    ctx.beginPath();
                    ctx.moveTo(p1.x, p1.y);
                    ctx.lineTo(p2.x, p2.y);
                    ctx.stroke();
                }

                function resizeCanvas() {
                    var canvas = document.getElementById("connection-canvas");
                    var ctx = canvas.getContext("2d");

                    ctx.canvas.width  = window.innerWidth;
                    ctx.canvas.height = window.innerHeight;
                }

                listenToClick();
                resizeCanvas();
            

                .padding-answer-line-mapping
                {
                    padding-bottom: 8px;
                }

                .answer-container
                {
                    width: 40px;
                    height: 40px;
                    background-color: #ccc;
                    border: 1px solid #ccc;
                    margin: 2px;
                    float: left;
                    text-align: center;
                    padding-top: 8px;
                    cursor: pointer;
                    position: relative;
                }

                .answer-container:hover, .answer-container:focus, .answer-container:active
                {
                    background-color: #0076e9;
                    color: white;
                    border: 1px solid #0076e9;
                }

                .round-pointer-right
                {
                    position: absolute;
                    background-color: #ccc;
                    cursor: pointer;
                    width: 10px;
                    height: 10px;
                    border-radius: 50%;
                    right: 0px;
                    top: 14px;
                    margin-right: -20px;
                }

                .round-pointer-left
                {
                    position: absolute;
                    background-color: #ccc;
                    cursor: pointer;
                    width: 10px;
                    height: 10px;
                    border-radius: 50%;
                    left: 0px;
                    top: 14px;
                    margin-left: -20px;
                }

                .selected {
                    background-color: red;
                }
            
<link href="//code.ionicframework.com/1.3.1/css/ionic.css" rel="stylesheet"/>
            Match the following items.

             <canvas id="connection-canvas" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0"></canvas>
            <div class="row padding-answer-line-mapping">
                <div class="col answer-container">
                    One
                    <div class="round-pointer-right"></div>
                </div>
                <div class="col">

                </div>
                <div class="col answer-container">
                    2
                    <div class="round-pointer-left"></div>
                </div>
            </div>
            <div class="row padding-answer-line-mapping">
                <div class="col answer-container">
                    Two
                    <div class="round-pointer-right"></div>
                </div>
                <div class="col">

                </div>
                <div class="col answer-container">
                    1
                    <div class="round-pointer-left"></div>
                </div>
            </div>

Answer â„–1

Let me know if you encounter any problems.

var lastSelection;
var p = 0;
var canvasPoints = [];

function listenToClick() {
  var rows = document.querySelectorAll('.row'),
    row;
  var cols, col;

  for (row = 0; row < rows.length; row++) {
    cols = rows[row].children;

    for (col = 0; col < cols.length; col++) {
      cols[col].addEventListener('click', selectAnswer.bind({
        row: row,
        col: col,
        element: cols[col]
      }));
    }
  }
}
var question = null;
var answer = null;

// This function is triggered when an answer-container is clicked.
function selectAnswer(event) {

  if (this.element.classList.contains("answer")) {
    answer = this.element;
  } else if (this.element.classList.contains("question")) {
    question = this.element;
    answer = null;
  }
  if (question && answer) {
    if (!removeObjects()) {
      var points = {};
      points.answer = getPoint(answer);
      points.question = getPoint(question);
      canvasPoints.push(points);
    }
  } else if (answer) {
    console.log("Please select the Left option");
  }
  resizeCanvas();
}

function getPoint(answerElement) {
  var roundPointer = answerElement.lastElementChild;
  return {
    y: answerElement.offsetTop + roundPointer.offsetTop + roundPointer.offsetHeight / 2,
    x: answerElement.offsetLeft + roundPointer.offsetLeft + roundPointer.offsetWidth / 2,
    text: answerElement.innerText
  };
}

function drawLine(p1, p2) {
  var canvas = document.getElementById("connection-canvas");
  var ctx = canvas.getContext("2d");
  ctx.beginPath();
  ctx.moveTo(p1.x, p1.y);
  ctx.lineTo(p2.x, p2.y);
  ctx.stroke();
}

function resizeCanvas() {
  var canvas = document.getElementById("connection-canvas");
  var ctx = canvas.getContext("2d");
  ctx.canvas.width = window.innerWidth;
  ctx.canvas.height = window.innerHeight;

  for (var i = 0; i < canvasPoints.length; i++) {
    drawLine(canvasPoints[i].answer, canvasPoints[i].question);
  }
  output();
}

function removeObjects() {

  var answerPoints = getPoint(answer);
  var questionPoints = getPoint(question);
  for (var i = 0; i < canvasPoints.length; i++) {

    if (canvasPoints[i].answer.x == answerPoints.x && canvasPoints[i].answer.y == answerPoints.y && canvasPoints[i].question.x == questionPoints.x && canvasPoints[i].question.y == questionPoints.y) {
      canvasPoints.splice(i, 1);
      return true;
    }
  }
  return false;
}
listenToClick();
resizeCanvas();

function output() {
  var outputObject = [];
  for (var i = 0; i < canvasPoints.length; i++) {
    var obj = {
      "left": canvasPoints[i].question.text,
      right: []
    };
    for (var j = 0; j < outputObject.length; j++) {
      if (outputObject[j].left == canvasPoints[i].question.text) {
        obj = outputObject[j];
        outputObject.splice(j, 1);
      }
    }
    obj.right.push(canvasPoints[i].answer.text)
    outputObject.push(obj);
  }
  console.log(outputObject);
}
.padding-answer-line-mapping {
  padding-bottom: 8px;
}
.answer-container {
  width: 40px;
  height: 40px;
  background-color: #ccc;
  border: 1px solid #ccc;
  margin: 2px;
  float: left;
  text-align: center;
  padding-top: 8px;
  cursor: pointer;
  position: relative;
}
.answer-container:hover,
.answer-container:focus,
.answer-container:active {
  background-color: #0076e9;
  color: white;
  border: 1px solid #0076e9;
}
.round-pointer-right {
  position: absolute;
  background-color: #ccc;
  cursor: pointer;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  right: 0px;
  top: 14px;
  margin-right: -20px;
}
.round-pointer-left {
  position: absolute;
  background-color: #ccc;
  cursor: pointer;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  left: 0px;
  top: 14px;
  margin-left: -20px;
}
.selected {
  background-color: red;
}
<link href="//code.ionicframework.com/1.3.1/css/ionic.css" rel="stylesheet" />Match the following items.

<canvas id="connection-canvas" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0"></canvas>
<div class="row padding-answer-line-mapping" id="id1">
  <div class="col answer-container question" id="id1-One">
    One
    <div class="round-pointer-right"></div>
  </div>
  <div class="col" id="id1-cols">

  </div>
  <div class="col answer-container answer" id="id1-2">
    2
    <div class="round-pointer-left"></div>
  </div>
</div>
<div class="row padding-answer-line-mapping" id="id2">
  <div class="col answer-container question" id="id2-two">
    Two
    <div class="round-pointer-right"></div>
  </div>
  <div class="col" id="id2-cols">

  </div>
  <div class="col answer-container answer" id="id2-1">
    1
    <div class="round-pointer-left"></div>
  </div>
</div>

Answer â„–2

Based on this response, the recommended approach to erasing a line is by clearing the entire canvas and then redrawing all elements.

In my proposed solution, I suggest utilizing an array that stores active lines and implementing a validation check before drawing a line to determine whether it should be drawn or erased.

I propose adding an array called lines, along with functions redrawAll and checkLine, as demonstrated in your code snippet:

var lastSelection;
var lines = new Array();

// Add click listener for answer-container
function listenToClick() {
    var rows = document.querySelectorAll('.row'),
        row;
    var cols, col;

    for (row = 0; row < rows.length; row++) {
        cols = rows[row].children;

        for (col = 0; col < cols.length; col++) {
            // Bind information about which answer is this,
            // so we can prevent from connecting two answers on
            // same column.
            cols[col].addEventListener('click', selectAnswer.bind({
                row: row,
                col: col,
                element: cols[col]
            }));
        }
    }
}

function checkLine(p1, p2)
{
var line;
for (var i = 0; i < lines.length; i++)
    {
    line = lines[i];
    if (line.p1.x == p1.x && line.p1.y == p1.y
           && line.p2.x == p2.x && line.p2.y == p2.y)
        {
            //line exists, remove it from lines
            lines.splice(i, 1);
        return true;
        }
        else if (line.p1.x == p2.x && line.p1.y == p2.y
           && line.p2.x == p1.x && line.p2.y == p1.y)
        {
            //line exists, remove it from lines
            lines.splice(i, 1);
        return true;
        }
    }
    return false;
}

function redrawAll()
{
    for (var i = 0; i < lines.length; i++)
    {
        drawLine(lines[i].p1, lines[i].p2);
    }
}

// This is fired when a answer-container is clicked.
function selectAnswer(event) {
    if (lastSelection) {
       lastSelection.element.classList.remove('selected');
    }

    if (!lastSelection || lastSelection.col === this.col)
    {
        lastSelection = this;
        this.element.classList.add('selected');
    } 
    else 
    {
        if ( checkLine(getPoint(lastSelection.element), getPoint(this.element)) )
        {
            var canvas = document.getElementById("connection-canvas");
            var ctx = canvas.getContext("2d");
            ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
            redrawAll();
        }
        else
        {
            var line = {
            'p1': getPoint(this.element), 
            'p2': getPoint(lastSelection.element)
        };
        drawLine(line.p1, line.p2);
            lines.push(line);
        }
        console.log(lines);
        lastSelection = null;
    }
}

function getPoint(answerElement) {
    var roundPointer = answerElement.lastElementChild;
    return {
        y: answerElement.offsetTop + roundPointer.offsetTop + roundPointer.offsetHeight / 2,
        x: answerElement.offsetLeft + roundPointer.offsetLeft + roundPointer.offsetWidth / 2
    };
}

function drawLine(p1, p2) {
    var canvas = document.getElementById("connection-canvas");
    var ctx = canvas.getContext("2d");

    ctx.beginPath();
    ctx.moveTo(p1.x, p1.y);
    ctx.lineTo(p2.x, p2.y);
    ctx.stroke();
}

function resizeCanvas() {
    var canvas = document.getElementById("connection-canvas");
    var ctx = canvas.getContext("2d");

    ctx.canvas.width  = window.innerWidth;
    ctx.canvas.height = window.innerHeight;
}

listenToClick();
resizeCanvas();
.padding-answer-line-mapping
{
    padding-bottom:8px;
}

.answer-container
{
    width:40px;
    height:40px;
    background-color:#ccc;
    border:1px solid #ccc;
    margin:2px;
    float:left;
    text-align:center;
    padding-top:8px;
    cursor:pointer;
    position:relative;
}

.answer-container:hover, .answer-container:focus, .answer-container:active
{
    background-color: #0076e9;
    color: white;
    border: 1px solid #0076e9;
}

.round-pointer-right
{
    position: absolute;
    background-color:#ccc;
    cursor:pointer;
    width:10px;
    height:10px;
    border-radius: 50%;
    right:0px;
    top:14px;
    margin-right:-20px;
}

.round-pointer-left
{
    position: absolute;
    background-color:#ccc;
    cursor:pointer;
    width:10px;
    height:10px;
    border-radius: 50%;
    left:0px;
    top:14px;
    margin-left:-20px;
}

.selected {
    background-color: red;
}
<link href="//code.ionicframework.com/1.3.1/css/ionic.css" rel="stylesheet"/>
Match the following items.

 <canvas id="connection-canvas" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0"></canvas>
<div class="row padding-answer-line-mapping">
    <div class="col answer-container">
        One
        <div class="round-pointer-right"></div>
    </div>
    <div class="col">
        
    </div>
    <div class="col answer-container">
        2
        <div class="round-pointer-left"></div>
    </div>
</div>
<div class="row padding-answer-line-mapping">
    <div class="col answer-container">
        Two
        <div class="round-pointer-right"></div>
    </div>
    <div class="col">
        
    </div>
    <div class="col answer-container">
        1
        <div class="round-pointer-left"></div>
    </div>
</div>

Answer â„–3

I have incorporated your code with some modifications. Please take a look at this snippet and confirm if it meets your requirements.

var lastSelection;
    var p = 0;
// Implementing click listener for answer-container
    function listenToClick() {
        var rows = document.querySelectorAll('.row'),
                row;
        var cols, col;

        for (row = 0; row < rows.length; row++) {
            cols = rows[row].children;

            for (col = 0; col < cols.length; col++) {
                // Attaching information about the current answer to avoid linking two answers in the same column.
                cols[col].addEventListener('click', selectAnswer.bind({
                    row: row,
                    col: col,
                    element: cols[col]
                }));
            }
        }
    }

// This function triggers when an answer-container is clicked.
    function selectAnswer(event) {
        
        if (lastSelection) {
            lastSelection.element.classList.remove('selected');
        }        
        
        if (!lastSelection || lastSelection.col === this.col) {
            lastSelection = this;
            this.element.classList.add('selected');
            
            if(p%2==0){
                resizeCanvas();
            }
            p++;
        } else {
           
            drawLine(getPoint(this.element), getPoint(lastSelection.element));
            lastSelection = null;
        }
        
    }

    function getPoint(answerElement) {
      //  console.log('getpoint : ' + JSON.stringify(answerElement));

        var roundPointer = answerElement.lastElementChild;
        //console.log('roundPointer : ' + JSON.stringify(roundPointer));

        return {
            y: answerElement.offsetTop + roundPointer.offsetTop + roundPointer.offsetHeight / 2,
            x: answerElement.offsetLeft + roundPointer.offsetLeft + roundPointer.offsetWidth / 2
        };
    }

    function drawLine(p1, p2) {


        var canvas = document.getElementById("connection-canvas");
        var ctx = canvas.getContext("2d");

        ctx.beginPath();
        ctx.moveTo(p1.x, p1.y);
        ctx.lineTo(p2.x, p2.y);
        ctx.stroke();
    }

    function resizeCanvas() {
        var canvas = document.getElementById("connection-canvas");
        var ctx = canvas.getContext("2d");

        ctx.canvas.width = window.innerWidth;
        ctx.canvas.height = window.innerHeight;
    }

    listenToClick();
    resizeCanvas();
.padding-answer-line-mapping
{
    padding-bottom:8px;
}

.answer-container
{
    width:40px;
    height:40px;
    background-color:#ccc;
    border:1px solid #ccc;
    margin:2px;
    float:left;
    text-align:center;
    padding-top:8px;
    cursor:pointer;
    position:relative;
}

.answer-container:hover, .answer-container:focus, .answer-container:active
{
    background-color: #0076e9;
    color: white;
    border: 1px solid #0076e9;
}

.round-pointer-right
{
    position: absolute;
    background-color:#ccc;
    cursor:pointer;
    width:10px;
    height:10px;
    border-radius: 50%;
    right:0px;
    top:14px;
    margin-right:-20px;
}

.round-pointer-left
{
    position: absolute;
    background-color:#ccc;
    cursor:pointer;
    width:10px;
    height:10px;
    border-radius: 50%;
    left:0px;
    top:14px;
    margin-left:-20px;
}

.selected {
    background-color: red;
}
<link href="//code.ionicframework.com/1.3.1/css/ionic.css" rel="stylesheet"/>
Match the following items.

<canvas id="connection-canvas" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0"></canvas>
<div class="row padding-answer-line-mapping" id="id1">
    <div class="col answer-container" id="id1-One">
        One
        <div class="round-pointer-right"></div>
    </div>
    <div class="col" id="id1-cols">

    </div>
    <div class="col answer-container" id="id1-2">
        2
        <div class="round-pointer-left"></div>
    </div>
</div>
<div class="row padding-answer-line-mapping" id="id2">
    <div class="col answer-container" id="id2-two">
        Two
        <div class="round-pointer-right"></div>
    </div>
    <div class="col"  id="id2-cols">

    </div>
    <div class="col answer-container" id="id2-1">
        1
        <div class="round-pointer-left"></div>
    </div>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Apply a CSS class to the selected radio button when retrieving row data from the table

How can I dynamically add a CSS class to a snippet of code when a radio button is selected? Here's the jQuery Snippet: $(document).ready(function (){ $("input:radio").click(function () { if ($(this).is(":checked")) { var empid ...

Customizing the appearance and dimensions of JWPlayer Audio Player with percentage-based styling

I'm currently attempting to set up an audio embed using JWPlayer, following the instructions provided in this particular article. The article suggests setting it up with the following code: <div id="myElement">Loading the player...</div> ...

Fresh React framework

I haven't worked on a React app in a while, but when I decided to start a new one and import my old function, I encountered the following error: C:/Users/Hello/Documents/Dev/contacts/client/src/App.tsx TypeScript error in C:/Users/Hello/Documents/Dev ...

AngularJS Data table: unresponsive feature not functioning

I'm currently utilizing the angular-datatables plugin along with the responsive table feature, but unfortunately it's not functioning as expected: the table appears without the responsive design. Module: (function () { 'use strict&apos ...

What could be causing my bounce animation to begin 50 pixels higher than its intended starting point?

Trying to create a bouncing effect on text Check out my attempt here. It seems like the bug is in this area. @keyframes bounce{ 0%, 40%{ transform:scale(2,.5) translate(0,100px); } 45%,55%{ transform:translate(0,-50px); } 55%, 100%{ ...

Enhance your website's performance by optimizing Javascript page loading time when using

I've implemented a simple JavaScript function that calculates the loading time of a URL: var beforeLoad = (new Date()).getTime(); $('#myiframe').one('load', function() { var afterLoad = (new Date()).getTime(); var result = ...

Incorrect data for minimal values within Google charts

Currently, I am utilizing a Google chart found at the following link: In my data set, I have significantly high values for the line chart and relatively low values for the bar chart. In order to make both types of data more easily readable, I would like t ...

Retrieving JSON data with Node.js

Receiving a JSON response from TMDB: { "id": 283350, "results": [ { "iso_3166_1": "BR", "release_dates": [ { "certification": "12", "iso_639_1": "pt", "note": "Streaming", "release_date": ...

Showcasing top performers via JavaScript tabs

I have two tabs on my webpage: "Overall Leaderboard" and "Weekly Leaderboard". Each tab displays a leaderboard with different scores. When I click on the "Overall Leaderboard" tab, it shows a leaderboard with specific scores. Now, my question is how can ...

"Exploring the Functionality of Dropdown Menus in ASP.NET Core 1

Looking for a unique way to create a dropdown menu in ASP.Net Core 1.0? I've scoured the internet but haven't found a solution specifically tailored to this new platform. Can anyone provide guidance on how to build a large dropdown menu in Core 1 ...

Crafting a Visual Storybook with Express.js

I am currently working on developing a photo album app using MEVN. In this project, the value of req.body.ALBUM is used as the folder name and req.body.DESCRIPTION is designated for describing the content. The issue I have encountered so far is that whil ...

"Error occurs when passing data back to main thread from a web worker: undefined data received

Hello, I’ve been experimenting with using a web worker to retrieve data and send it back to the main thread. However, I've encountered an issue with my code not working as expected. onmessage = (e) => { console.log(e); if( e.data[0] === &apos ...

Issues with select options not functioning correctly in knockout framework

Currently, I am engaged in a project where data is being retrieved from an API. The main task at hand is to create a dropdown list using select binding. In order to do so, I have defined an observable object to hold the selected value within my data model. ...

Changes made in React are not reflected in the DOM

import React, { Component } from "react"; import ReactDOM from "react-dom"; import "./index.css"; class App extends Component { constructor(props) { super(props); this.state = { text: "", listItem: [] } this.onChangeInpu ...

When implementing multer in an express application, I encountered an issue where req.files appeared empty

Currently, I am facing some issues while attempting to upload various file types to the server using multer in an express application. Whenever I make the request, the server responds with a TypeError: req.files is not iterable. Upon investigation, I notic ...

The alignment of bullets in CSS property list-style-position is off

I'm encountering an issue with aligning the list items. I've been using the CSS property list-style-position: inside; Typically, the bullet points appear outside of the text, like this: https://i.stack.imgur.com/LcVB0.png This doesn't seem ...

Is it possible for jquery JSON AJAX to block all users?

On my website, I use AJAX to load an RSS feed on the client side when the page loads. If a user repeatedly presses F5, could the owner of the RSS feed ban my entire website instead of just that one user? This would prevent others from loading the RSS feed ...

Arrangement of HTML divs and styling classes

I have been experimenting with divs and classes in order to achieve proper alignment of text on my website. Currently, I am working with 2 classes that I would like to display side by side to create 2 columns. However, the right column containing the text ...

When the value is blank, do not include the class attribute when appending

http://jsbin.com/guvixara/1/edit I have a situation where I am dynamically inserting a button... $(".confirm-add-button").on("click", function() { var $ctrl = $('<button/>').attr({ class: $('.newbtnclassname').val()}).html($(& ...

Desiring to iterate through an array of identification numbers in order to retrieve information from an external API

I have been working on an app where I retrieve IDs from one API and pass them into a second API to display the property overviewList.overview.lifeTimeData.energy for each ID. However, in my current setup, I am only able to display the property of the fir ...