1

I am creating some html:

$('#filename').append('<div id="file_'+ initial +'"><span class="fa-stack fa-lg><i class="fa fa-file fa-stack-1x "></i><strong class="fa-stack-1x" style="color:#FFF; font-size:12px; margin-top:2px;">' + counter + '</strong></span> ' + this.files[initial].name + '&nbsp;&nbsp;<span class="imgUp fa fa-times-circle fa-lg closeBtn" title="remove"></span></div>');
    }
  });

And I need to attach a click on each of them. (They will be more than one)

  var inputs = document.querySelectorAll('imgUp');

  for (var i = 0; i < inputs.length; i++) {
    inputs[i].addEventListener ("click", removeLine);
  }

But nothing happens, what am I doing wrong in attaching the eventListener?

  function removeLine(obj) {
    inputFile.val('');
    var jqObj = $(obj);
    var container = jqObj.closest('div');
    var index = container.attr("id").split('_')[1];
    container.remove(); 

    delete finalFiles[index];
    //console.log(finalFiles);
  }

var dropZoneId = "drop-zone";
  var buttonId = "clickHere";
  var mouseOverClass = "mouse-over";
var dropZone = $("#" + dropZoneId);
 var inputFile = dropZone.find("input");
 var finalFiles = {};
$(function() {
  

  
  var ooleft = dropZone.offset().left;
  var ooright = dropZone.outerWidth() + ooleft;
  var ootop = dropZone.offset().top;
  var oobottom = dropZone.outerHeight() + ootop;
 
  document.getElementById(dropZoneId).addEventListener("dragover", function(e) {
    e.preventDefault();
    e.stopPropagation();
    dropZone.addClass(mouseOverClass);
    var x = e.pageX;
    var y = e.pageY;

    if (!(x < ooleft || x > ooright || y < ootop || y > oobottom)) {
      inputFile.offset({
        top: y - 15,
        left: x - 100
      });
    } else {
      inputFile.offset({
        top: -400,
        left: -400
      });
    }

  }, true);

  if (buttonId != "") {
    var clickZone = $("#" + buttonId);

    var oleft = clickZone.offset().left;
    var oright = clickZone.outerWidth() + oleft;
    var otop = clickZone.offset().top;
    var obottom = clickZone.outerHeight() + otop;

    $("#" + buttonId).mousemove(function(e) {
      var x = e.pageX;
      var y = e.pageY;
      if (!(x < oleft || x > oright || y < otop || y > obottom)) {
        inputFile.offset({
          top: y - 15,
          left: x - 160
        });
      } else {
        inputFile.offset({
          top: -400,
          left: -400
        });
      }
    });
  }

  document.getElementById(dropZoneId).addEventListener("drop", function(e) {
    $("#" + dropZoneId).removeClass(mouseOverClass);
  }, true);


  inputFile.on('change', function(e) {
    finalFiles = {};
    $('#filename').html("");
    var fileNum = this.files.length,
      initial = 0,
      counter = 0;

    $.each(this.files,function(idx,elm){
       finalFiles[idx]=elm;
    });

    for (initial; initial < fileNum; initial++) {
      counter = counter + 1;
      $('#filename').append('<div id="file_'+ initial +'"><span class="fa-stack fa-lg><i class="fa fa-file fa-stack-1x "></i><strong class="fa-stack-1x" style="color:#FFF; font-size:12px; margin-top:2px;">' + counter + '</strong></span> ' + this.files[initial].name + '&nbsp;&nbsp;<span class="imgUp fa fa-times-circle fa-lg closeBtn" title="remove"></span></div>');
    }
  });
})

  var inputs = document.querySelectorAll('imgUp');

  for (var i = 0; i < inputs.length; i++) {
    inputs[i].addEventListener ("click", removeLine);
  }

  function removeLine(obj) {
    inputFile.val('');
    var jqObj = $(obj);
    var container = jqObj.closest('div');
    var index = container.attr("id").split('_')[1];
    container.remove(); 

    delete finalFiles[index];
    //console.log(finalFiles);
  }
#drop-zone {
  width: 100%;
  min-height: 150px;
  border: 3px dashed rgba(0, 0, 0, .3);
  border-radius: 5px;
  font-family: Arial;
  text-align: center;
  position: relative;
  font-size: 20px;
  color: #7E7E7E;
}
#drop-zone input {
  position: absolute;
  cursor: pointer;
  left: 0px;
  top: 0px;
  opacity: 0;
}
/*Important*/

#drop-zone.mouse-over {
  border: 3px dashed rgba(0, 0, 0, .3);
  color: #7E7E7E;
}
/*If you dont want the button*/

#clickHere {
  display: inline-block;
  cursor: pointer;
  color: white;
  font-size: 17px;
  width: 150px;
  border-radius: 4px;
  background-color: #4679BD;
  padding: 10px;
}
#clickHere:hover {
  background-color: #376199;
}
#filename {
  margin-top: 10px;
  margin-bottom: 10px;
  font-size: 14px;
  line-height: 1.5em;
}
.file-preview {
  background: #ccc;
  border: 5px solid #fff;
  box-shadow: 0 0 4px rgba(0, 0, 0, 0.5);
  display: inline-block;
  width: 60px;
  height: 60px;
  text-align: center;
  font-size: 14px;
  margin-top: 5px;
}
.closeBtn:hover {
  color: red;
  display:inline-block;
}
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id="drop-zone">
  <p>Drop files here...</p>
  <div id="clickHere">or click here.. <i class="fa fa-upload"></i>
    <input type="file" name="file" id="file" multiple />
  </div>
  <div id='filename'></div>
</div>
rob.m
  • 9,843
  • 19
  • 73
  • 162
  • I'm betting the problem is somewhere else in the script, can you post more of the code so that the issue is reproducible? – CertainPerformance Jun 28 '18 at 02:11
  • If you're going to include jQuery, you should use it for your event bindings. Additionally, if you're going to be attaching them to dynamically created elements, you should make use of [Event Delegation](https://learn.jquery.com/events/event-delegation/). – Tyler Roper Jun 28 '18 at 02:13
  • If `removeLine` ever run, you would also see another problem - the `obj` argument isn't the element, it's the event – CertainPerformance Jun 28 '18 at 02:14
  • @CertainPerformance updated (trying to apply what you suggested on the other question https://stackoverflow.com/questions/51073573/uncaught-referenceerror-removeline-is-not-defined) – rob.m Jun 28 '18 at 02:14
  • @CertainPerformance should I give it `inputs[i].addEventListener ("click", removeLine(i));` ? – rob.m Jun 28 '18 at 02:20
  • @TylerRoper I just tried `$(".imgUp").on("click", function(){ removeLine(this); });` but this won't run `function removeLine(obj) {` – rob.m Jun 28 '18 at 02:27
  • The only reference to `"imgUp"` string in your DOM is a class. Your current selector targets elements whose tagName are `"imgUp"` (i.e `...`. There is none, so the returned NodeList is empty and your loop doesn't iterate. VTCing as typo, since you only forgot a `.` in `querySelectorAll(".imgUp")`. But as correctly noted in other comments, you apparently have other typos. – Kaiido Jun 28 '18 at 02:28
  • @rob.m That is not event delegation. Try `$("body").on("click", ".imgUp", function(){ removeLine(this); } );`. I haven't looked at the rest of the code so there may be other issues, but you can start with that. – Tyler Roper Jun 28 '18 at 02:29
  • @Kaiido ouch, you're right! But I have now moved to jQuery as I know it better but I just tried `$(".imgUp").on("click", function(){ removeLine(this); });` but this won't run `function removeLine(obj) {` – rob.m Jun 28 '18 at 02:29
  • That's not what I read in the question. Can't answer. – Kaiido Jun 28 '18 at 02:30
  • @Kaiido right.. – rob.m Jun 28 '18 at 02:30
  • @TylerRoper oh I now understand what you meant with delegation.. I thought `.delegate(` it works fine now, thanks. Place that into an answer and I'll accept it, I mean to use jQuery and delegate.. – rob.m Jun 28 '18 at 02:32
  • I appreciate it, but this is a duplicate of a pretty common question. I'm going to mark it as a duplicate just so future readers can find a full write-up on it. – Tyler Roper Jun 28 '18 at 02:39
  • @TylerRoper ok great, marked it as solved. However it is removing it but it is removing all the files as when I then send the form, nothing is saved in the db, while I don't remove anything, then it saves all the images, which means isn't sending `this` when doing `removeLine(this);` and then reading `function removeLine(obj) {` – rob.m Jun 28 '18 at 02:40

0 Answers0