Add input field each time function is called

Asked

Viewed 61 times

1

I have a module in a system to which I am developing, where, every click on insert, the user clicks on a photo and a marking is added on the exact location of the click.

I need every click on the image to create a input so that the user type what represents the location of the click, so that I can save in my bank.

View code:

<div class="area-imagem">
  <img src="<?= $img?>" alt="<?= $img?>" class="img-fluid">
</div>
<div class="area-opcoes">
  <button type="button" id="marcar" class="btn btn-success" onclick="marcar()">Inserir Marcação</button>
  <button type="button" id="desmarcar" class="btn btn-danger" onclick="desmarcar()">Desfazer Marcação</button>
</div>

Javascript code:

function marcar(){
    document.querySelector(".area-imagem").addEventListener("click", evento);
}

var count = 0;
var marc = 0;
function evento(){
    count++;
    marc++;
    var pos = handler(event);
    var pixel = "<div class=\"pixel\" id=\"marc"+marc+"\" name=\"marc"+marc+"\" style=\"top: " + (pos.y - this.offsetTop) + "px; left: " + (pos.x - this.offsetLeft) + "px;\">" + count + "</div>";

    this.innerHTML = this.innerHTML + pixel;
    this.removeEventListener('click', evento); // remove o event listener
}

function handler(e) {
    e = e || window.event;

    var pageX = e.pageX;
    var pageY = e.pageY;

    // IE 8
    if (pageX === undefined) {
        pageX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
        pageY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
    }

   return {x: pageX, y: pageY};
}

1 answer

2


Instead of concatenating .innerHTML with .innerHTML, would be better to create Divs with .createElement. So you can enter an input in each div keeping what was typed in the ones that were already created.

In the inputs I put name="marcas[]" so that you can receive them in array form when sending.

See in the example below the modifications I made creating elements:

function marcar(){
    document.querySelector(".area-imagem").addEventListener("click", evento);
}

var count = 0;
var marc = 0;
function evento(){
   count++;
   marc++;
   var pos = handler(event);
   var pixel = document.createElement("div");
   pixel.className = "pixel";
   pixel.id = "marc"+marc;
   pixel.style = "top: " + (pos.y - this.offsetTop) + "px; left: " + (pos.x - this.offsetLeft) + "px;";
   pixel.textContent = count;

   this.appendChild(pixel);
   
   var input = document.createElement("input");
   input.name = "marcas[]";
   document.getElementById("marc"+marc).appendChild(input);
   input.focus();
   
   var input_hidden = document.createElement("input");
   input_hidden.name = "coords[]";
   input_hidden.type = "hidden";
   input_hidden.value = (pos.x - this.offsetLeft)+"x"+ (pos.y - this.offsetTop);
   document.getElementById("marc"+marc).appendChild(input_hidden);
   
   this.removeEventListener('click', evento); // remove o event listener
}

function handler(e) {
    e = e || window.event;

    var pageX = e.pageX;
    var pageY = e.pageY;

    // IE 8
    if (pageX === undefined) {
        pageX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
        pageY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
    }

   return {x: pageX, y: pageY};
}
.area-imagem img{
   width: 300px;
}
<div class="area-imagem">
  <img src="https://www.cleverfiles.com/howto/wp-content/uploads/2016/08/mini.jpg" alt="<?= $img?>" class="img-fluid">
</div>
<div class="area-opcoes">
  <button type="button" id="marcar" class="btn btn-success" onclick="marcar()">Inserir Marcação</button>
  <button type="button" id="desmarcar" class="btn btn-danger" onclick="desmarcar()">Desfazer Marcação</button>
</div>

  • Thank you very much, Sam, it really worked. Just one more question, in case for me to register the values of the coordinates + the descriptions of the points, as I do to send this data by POST method, I would not need these elements to be inside a FORM tag?

  • 1

    Yes, everything needs to be inside a form. Now, to send the coordinates together, you would have to create inputs and put them in. I think Hidden inputs would solve and you put the coordinates on them in a pattern, which could be, say, 120x170. When you receive this input in the backend, vc breaks down by the "x" where the first value is the X axis and the second the Y axis.

  • Thank you very much, I will make this procedure, any doubt I warn.

  • 1

    I added the code to create the Hidden input.

  • Thank you very much, if I could vote 1000x as useful. Now I will proceed with data recovery by backend.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.