mage 456
mage 456

Reputation: 55

Create form elements with dynamic names in Javascript?

Inside my form, I have a div like this

<div>
  <button type="button" class="btn btn-seconday" onclick="addCourse()">Add Course</button>
  <div id="course_add" class="container">
    <div class="form-group">
      <label for="course name">Course Name</label>
      <input type="text" class="block rounded py-1 ml-4 text-sm" name="courses[0][course_name]"/>
    </div>
    <div class="form-group">
      <label for="no_of_students">Number of Students</label>
      <input type="text" class="block rounded py-1 ml-4 text-sm" name="courses[0][no_of_students]"/>
    </div>
  </div>
</div>

When the button is clicked, I want it to create the input fields again inside the div container. But with dynamic name. like If the button is created first time then It should be

    <div class="form-group">
      <label for="course name">Course Name</label>
      <input type="text" class="block rounded py-1 ml-4 text-sm" name="courses[1][course_name]"/>
    </div>
    <div class="form-group">
      <label for="no_of_students">Number of Students</label>
      <input type="text" class="block rounded py-1 ml-4 text-sm" name="courses[1][no_of_students]"/>
    </div>

I need

courses[1][course_name] & courses[1][no_of_students]

these names to be incremented whenever new input is created.

I am not sure what to do in the addCourse() function.

function addCourse() {
        i = 1;
        var mydiv = document.getElementById("course_add");
        console.log(mydiv);
    }

Upvotes: 0

Views: 898

Answers (4)

Nick Vu
Nick Vu

Reputation: 15520

You can try this approach

let index = 0;

function addCourse() {
  const courseHtml = generateCourse(index++);
  var mydiv = document.getElementById("course_add");
  mydiv.insertAdjacentHTML('beforeend', courseHtml);
}

function generateCourse(indexValue) {
  return `<div class="form-group">
      <label for="course name">Course Name</label>
      <input type="text" class="block rounded py-1 ml-4 text-sm" name="courses[${indexValue}][course_name]"/>
    </div>
    <div class="form-group">
      <label for="no_of_students">Number of Students</label>
      <input type="text" class="block rounded py-1 ml-4 text-sm" name="courses[${indexValue}][no_of_students]"/>
    </div>`
}

//add the first course instead of using HTML directly
addCourse()
<div>
  <button type="button" class="btn btn-seconday" onclick="addCourse()">Add Course</button>
  <div id="course_add" class="container">
  </div>
</div>

Upvotes: 1

Arbin Shrestha
Arbin Shrestha

Reputation: 155

You should try assigning ids to the inputs rather than the div.

<input id="course_name" type="text" class="block rounded py-1 ml-4 text-sm" name="courses[0][course_name]"/>

Then in your onClick function, change the name property for the input like so

function addCourse() {
        let i = 1;
        var courseName = document.getElementById("course_name"); 
        courseName.setAttribute("name", "courses["+i+"][course_name]");
    }

Also, the i counter will not update on second click, I suggest you add another property to the input indicating counter and increment it on click.

<input id="course_name" counter="1" type="text" class="block rounded py-1 ml-4 text-sm" name="courses[0][course_name]"/>

 function addCourse() {
            var courseName = document.getElementById("course_name");
            let i = courseName.attributes[0].name; 
            courseName.setAttribute("name", "courses["+i+"][course_name]");
            courseName.setAttribute("counter", (parseInt(i)+1).toString());
        }

Do the same for Number of Students input.

Upvotes: 0

DCodeMania
DCodeMania

Reputation: 1157

You can simply try this one:

let i = 1;
function addCourse() {
  var mydiv = document.getElementById("course_add");
  mydiv.innerHTML += `<div class="form-group">
    <label for="course name">Course Name</label>
    <input type="text" class="block rounded py-1 ml-4 text-sm" name="courses[${i}][course_name]" />
  </div>
  <div class="form-group">
    <label for="no_of_students">Number of Students</label>
    <input type="text" class="block rounded py-1 ml-4 text-sm" name="courses[${i}][no_of_students]" />
  </div>`;
  i++;
}
<div>
  <button type="button" class="btn btn-seconday" onclick="addCourse()">Add Course</button>
  <div id="course_add" class="container">
    <div class="form-group">
      <label for="course name">Course Name</label>
      <input type="text" class="block rounded py-1 ml-4 text-sm" name="courses[0][course_name]" />
    </div>
    <div class="form-group">
      <label for="no_of_students">Number of Students</label>
      <input type="text" class="block rounded py-1 ml-4 text-sm" name="courses[0][no_of_students]" />
    </div>
  </div>
</div>

Upvotes: 0

Peleg Haham
Peleg Haham

Reputation: 91

First of all, notice that you are using getElementById and in the html you are setting the name attribute. to do what you are willing, you need to use createElement and appending the elements.

let index = 0;
const containerDiv = document.getElementById('course_add');
function addCourse(){
    const formGroupDiv = document.createElement('div')
    formGroupDiv.setAttribute('class','form-group');
    const input = document.createElement('input');
    input.setAttribute('id',`courses[${index}][course_name]`);
    formGroupDiv.appendChild(input);
    containerDiv.appendChild(formGroupDiv);
    index++;
}

Upvotes: 0

Related Questions