1

I'd like to insert an input in an adjacent div where the JS function has been fired.

JavaScript: to add an element (input in this case) jQuery: to detect where the javascript function has been fired.

The issues I'm facing :

  1. The input is created after the second click.
  2. All the inputs move from one div to another on each click ...

I don't understand why this happens! Do you guys have an idea why everything messes up? Thanks a lot.

var ct = 0; // numeric identifier for training section
var lec = 0; // numeric identifier for lectures

function addLecture() {
  lec++;

  var div = document.createElement('div');
  div.setAttribute('id', 'lecture'.concat(lec))

  var input = document.createElement('input');
  lecture.setAttribute('type', 'text')

  div.appendChild(input)

  var id;
  jQuery('.info_container').click(function(id) {
    var id = jQuery(this).attr("id");
    document.getElementById(id).querySelector('[id ^= "lectures_container"]').insertAdjacentElement('beforeend', div);
  });
}
[id^="row"] {
  padding: 10px;
  margin: 10px;
  background-color: gray;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<div id="row-4" class="info_container">
  <div id="lectures_container4">
  </div>
  <a class="btn btn-add" href="javascript:addLecture()"><span class="fa fa-plus"></span> Add an input</a>
</div>


<div id="row-5" class="info_container">
  <div id="lectures_container5">
  </div>
  <a class="btn btn-add" href="javascript:addLecture()"><span class="fa fa-plus"></span> Add an input</a>
</div>

Full code and live example in the JS fiddle right here: https://jsfiddle.net/t7x350d9/

4
  • 1
    You can see errors in console in browser or even in jsfiddle: "<a class='gotoLine' href='#64:5'>64:5</a> Uncaught ReferenceError: lecture is not defined" Commented Sep 25, 2020 at 14:31
  • 1
    hey @Jax-p thanks for the hint ! I do not understand why lecture is not defined. Lecture is not a js var in the code ... Do you have an idea ? Commented Sep 25, 2020 at 14:40
  • You use it in this line: lecture.setAttribute('type', 'text') I assume it's supposed to be input.setAttribute(... instead Commented Sep 25, 2020 at 14:41
  • 1
    Damn, I made the change but didn't save the fiddle before posting ... my bad ! thanks for the double check ! Commented Sep 25, 2020 at 14:45

1 Answer 1

2

Your code is much more complicated than it needs to be.

Firstly when dealing with repeated HTML structures do not use id attributes. Use the same class on them all to group them. If you need to identify each one, listen for the event and use the target to determine which element was interacted with. In the example below this can be done through the target property of the event which is raised.

Secondly, to achieve your goal simply use an unobtrusive event handler in your JS (not an onclick attribute in the HTML) and append() the new HTML. Try this:

jQuery($ => {
  $('.info_container .btn').on('click', e => {
    e.preventDefault();
    $(e.target).closest('.info_container').find('.lectures_container').append('<div class="lecture"><input type="text" /></div>');
  });
});
.info_container {
  padding: 10px;
  margin: 10px;
  background-color: gray;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<div class="info_container">
  <div class="lectures_container"></div>
  <a href="#" class="btn btn-add">
    <span class="fa fa-plus"></span> Add an input
  </a>
</div>
<div class="info_container">
  <div class="lectures_container"></div>
  <a href="#" class="btn btn-add">
    <span class="fa fa-plus"></span> Add an input
  </a>
</div>

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot for your edit as well as answer ! The html structure is very important in this case. Do you think it's possible to do $(e.target).closest('[id ^= "lectures_container"]').append('<div class="lecture"><input type="text" /></div>'); ? To make sure that the input ends in the div with id/class starting with lectures_container ?
I missed that part. You can use find() for that. I amended the answer to show you how

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.