Jeb675
Jeb675

Reputation: 45

jQuery adding dynamic form elements

I want to create two dynamic form elements so that when the user clicks "add another question" they get a new question field and a answer field and the html is manipulated to "Q2", "A2" etc. I was able to create a dynamic form element to add a new question input based on this blog but can't manage to add an answer field too.

//disable delete question
$(document).ready(function() {
  $('#btnDel').prop('disabled', 'disabled');
});

//add question
$('#btnAdd').click(function() {
  var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
  var newNum = new Number(num + 2); // the numeric ID of the new Q input field being added
  var newNumA = new Number(num + 3); // the numeric ID of the new A input field being added

  // Question Input

  // create the new element via clone(), and manipulate it's ID using newNum value
  var newElem = $('#qInput' + num).clone().prop('id', 'qInput' + newNum);

  // manipulate the name/id/html of the span inside the new element
  newElem.children(':first').prop('id', 'spanQ' + newNum).html("Q" + newNum);

  // manipulate the name/id/val values of the input inside the new element 
  newElem.children().eq(1).prop('id', 'question' + newNum).prop('name', 'question' + newNum).val("");


  //Answer Input

  // create the new element via clone(), and manipulate it's ID using newNumA value
  var newElemA = $('#aInput' + num).clone().prop('id', 'aInput' + newNumA);

  // manipulate the name/id/html of the span inside the new element
  newElemA.children(':first').prop('id', 'spanA' + newNumA).html("A" + newNumA);

  // manipulate the name/id/val values of the input inside the new element 
  newElemA.children().eq(1).prop('id', 'answer' + newNumA).prop('name', 'answer' + newNumA).val("");


  // insert the new element after the last "duplicatable" input field
  $('#aInput' + num).after(newElem, newElemA);

  // enable the "remove" button
  $('#btnDel').prop('disabled', '');

  // business rule: you can only add 19 questions
  if (newNum == 19)
    $('#btnAdd').prop('disabled', 'disabled');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="createWorksheet">

  <div>
    <div id="qInput1" class="styleOne clonedInput">
      <span id="span1Q"> Q1 </span>
      <input type="text" name="question1" id="question1" />
    </div>
    <div id="aInput2" class="styleTwo">
      <span id="span1A"> A1 </span>
      <input type="text" name="answer1" id="answer1" />
    </div>
  </div>


  <div class="buttonGroup">
    <input type="button" id="btnDel" value="Remove Question" class="btnCreate" />
    <input type="button" id="btnAdd" value="Add another question" class="btnCreate" />
  </div>

  <div class="buttonGroup">
    <input type="submit" id="btnSub" value="Submit" class="btnCreate">
  </div>

</form>

Upvotes: 0

Views: 109

Answers (3)

Hikarunomemory
Hikarunomemory

Reputation: 4305

This is just a simplified version of what you attempt to do. I added a class QAset and modified some attributes of your original HTML elements to make the create new inputs process easier.

$(document).ready(function() {
  $('#btnDel').prop('disabled', 'disabled');
});

const QAset = $('.QAset')[0].outerHTML;
var num = /\$\{num\}/g;
$('.QAset').remove()
$('#btnAdd').click(function() {
  var currentQAset = $('.QAset').length
  var html = QAset.replace(num, currentQAset + 1)
  $('.buttonGroup:first').before(html)

  if (currentQAset + 1 > 1)
    $('#btnDel').prop('disabled', '');

  if (currentQAset == 19)
    $('#btnAdd').prop('disabled', 'disabled');
});

$('#btnAdd').click()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="createWorksheet">
  <div class="QAset">
    <div id="qInput${num}" class="styleOne">
      <span id="span${num}Q"> Q${num} </span>
      <input type="text" name="question${num}" id="question${num}" />
    </div>
    <div id="aInput${num}" class="styleTwo">
      <span id="span${num}A"> A${num} </span>
      <input type="text" name="answer${num}" id="answer${num}" />
    </div>
  </div>

  <div class="buttonGroup">
    <input type="button" id="btnDel" value="Remove Question" class="btnCreate" />
    <input type="button" id="btnAdd" value="Add another question" class="btnCreate" />
  </div>

  <div class="buttonGroup">
    <input type="submit" id="btnSub" value="Submit" class="btnCreate">
  </div>
</form>

Upvotes: 1

Wils
Wils

Reputation: 1231

$(document).ready(function() {
  $('#btnDel').prop('disabled', 'disabled');
});

var currentQ=1;
var ids = [];

$('#btnAdd').click(function() {
newgen= $( ".clone" ).clone();
ids.push(newgen);
newgen.insertBefore(  $('.insertabove'));
newgen.removeClass("clone");
newgen.find('.spanQ').html('Q'+ ++currentQ);
newgen.find('.spanA').html('A'+ currentQ);
newgen.find('.question').attr('name', 'question_'+currentQ);
newgen.find('.answer').attr('name', 'answer_'+currentQ);
$('#btnDel').prop('disabled', '');
if (currentQ > 19)    $('#btnAdd').prop('disabled', 'disabled');
});

$('#btnDel').click(function(){
if (!newgen){alert('You need to have at least one question');}else{
newgen.remove();
ids.splice(-1,1);
newgen = ids[ids.length-1];

currentQ--;}



});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<form id="createWorksheet">

  <div class="clone">
    <div class="qInput1" class="styleOne clonedInput">
      <span class="spanQ"> Q1 </span>
      <input type="text" name="question_1" class="question" />
    </div>
    <div class="aInput2" class="styleTwo">
      <span class="spanA"> A1 </span>
      <input type="text" name="answer_1" class="answer" />
    </div>
  </div>

<span class="insertabove"></span>

  <div class="buttonGroup">
    <input type="button" id="btnDel" value="Remove Question" class="btnCreate" />
    <input type="button" id="btnAdd" value="Add another question" class="btnCreate" />
  </div>

  <div class="buttonGroup">
    <input type="submit" id="btnSub" value="Submit" class="btnCreate">
  </div>

</form>

I've modified the HTML as well, please see if it suits your need.

Upvotes: 1

Jameson the dog
Jameson the dog

Reputation: 1806

Looking into your code, the issue is simple - you are calling the question and the answer using the same index ('#qInput' + num and '#aInput' + num) when in fact - the question is #qInput1 and the answer is #aInput2

just add num++ between the stages and it should work

EDIT - looking deeper, might be best if you change the id of the answer to aInput1, also - newNum and newNumA should both just be num + 1

//disable delete question
$(document).ready(function() {
  $('#btnDel').prop('disabled', 'disabled');
});

//add question
$('#btnAdd').click(function() {
  var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
  var newNum = new Number(num + 1); // the numeric ID of the new Q input field being added
  var newNumA = new Number(num + 1); // the numeric ID of the new A input field being added

  // Question Input

  // create the new element via clone(), and manipulate it's ID using newNum value
  var newElem = $('#qInput' + num).clone().prop('id', 'qInput' + newNum);

  // manipulate the name/id/html of the span inside the new element
  newElem.children(':first').prop('id', 'spanQ' + newNum).html("Q" + newNum);

  // manipulate the name/id/val values of the input inside the new element 
  newElem.children().eq(1).prop('id', 'question' + newNum).prop('name', 'question' + newNum).val("");

  // num++; // this is the new line
  //Answer Input

  // create the new element via clone(), and manipulate it's ID using newNumA value
  var newElemA = $('#aInput' + num).clone().prop('id', 'aInput' + newNumA);

  // manipulate the name/id/html of the span inside the new element
  newElemA.children(':first').prop('id', 'spanA' + newNumA).html("A" + newNumA);

  // manipulate the name/id/val values of the input inside the new element 
  newElemA.children().eq(1).prop('id', 'answer' + newNumA).prop('name', 'answer' + newNumA).val("");


  // insert the new element after the last "duplicatable" input field
  $('#aInput' + num).after(newElem, newElemA);

  // enable the "remove" button
  $('#btnDel').prop('disabled', '');

  // business rule: you can only add 19 questions
  if (newNum == 19)
    $('#btnAdd').prop('disabled', 'disabled');
});
<script
  src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
  integrity="sha256-3edrmyuQ0w65f8gfBsqowzjJe2iM6n0nKciPUp8y+7E="
  crossorigin="anonymous"></script>
<form id="createWorksheet">

  <div>
    <div id="qInput1" class="styleOne clonedInput">
      <span id="span1Q"> Q1 </span>
      <input type="text" name="question1" id="question1" />
    </div>
    <div id="aInput1" class="styleTwo">
      <span id="span1A"> A1 </span>
      <input type="text" name="answer1" id="answer1" />
    </div>
  </div>


  <div class="buttonGroup">
    <input type="button" id="btnDel" value="Remove Question" class="btnCreate" />
    <input type="button" id="btnAdd" value="Add another question" class="btnCreate" />
  </div>

  <div class="buttonGroup">
    <input type="submit" id="btnSub" value="Submit" class="btnCreate">
  </div>

</form>

Upvotes: 0

Related Questions