0

Essentially this is what I am trying to do

I have a button, by triggering it, a dropdown of books is displayed to the user. With each trigger, a new dropdown is loaded.

The way I have kept loading them to the user is by cloning a hidden div. Like so

<form action="POST">
  <div id="books"></div>
  <button onclick="addBook()"></button>
  <input type="submit" value="Submit">
</form> 

<select id="book" name="books[]" style="display: none;">
  <option value="A">A</option>
  <option value="B">B</option>
  <option value="C">C</option>
</select>


<script>
$count = 0;

function addBook() {
     $clone = $("#book").clone().show();
     clone.find("#book").attr('id','book-' + $count);
     clone.appendTo("#books");
     $count += 1;
 }

For example, after clicking the button 3 times, this will be my html display (i have obviously changed the selected value)

  <form action="POST">
    <div id="books">
    <select id="book-0" name="books[]">
    <option value="A">A</option>
    <option value="B">B</option>
    <option value="C" selected>C</option>
  </select>

 <select id="book-1" name="books[]">
  <option value="A">A</option>
  <option value="B" selected>B</option>
  <option value="C">C</option>
  </select>

<select id="book-3" name="books[]">
  <option value="A" selected>A</option>
  <option value="B">B</option>
  <option value="C">C</option>
</select>

  </div>
  <button onclick="addBook()"></button>
  <input type="submit" value="Submit">
</form> 

 <select id="book" name="books[]" style="display: none;">
  <option value="A">A</option>
  <option value="B">B</option>
  <option value="C">C</option>
   </select>

The issue is now.. when i hit submit, I'm collecting their data using the name field (i.e. books[]) which should be something like books[C, B, A]. However when I print the books[] values, I get books[C, B, A, A]. The last A seems to be coming from the hidden div! eventhough it is hidden.

var books = $("select[name='books[]']").map(function(){return $(this).val();}).get();

console.log(books);

I have tried disabling, making it readonly etc etc, but everytime the value of the hidden div seem to be attached to my element of arrays (which i don't want)

Malcolm
  • 1
  • 1
  • `console.log(books[])` will result in `Uncaught SyntaxError: Unexpected token ]`, not `books[C, B, A, A]`..? – CertainPerformance Sep 10 '18 at 21:01
  • 1
    Sounds like a job for [` – Joseph Marikle Sep 10 '18 at 21:25
  • I believe many browsers will not post inputs with `display:none` applied directly to them, though [I'm not sure how reliable that behavior is](https://stackoverflow.com/questions/28730834/does-display-none-disable-an-input). You might want to [disable the inputs](https://stackoverflow.com/questions/1374147/how-to-avoid-sending-input-fields-which-are-hidden-by-displaynone-to-a-server) (and re-enable them upon cloning), in addition to setting them to `display:none`. That being said, I agree with @JosephMarikle that a template might be a better way to go. – showdev Sep 10 '18 at 21:41
  • are you submitting form or collection values by loop? – Farhan Sep 10 '18 at 21:42
  • seems to have solved it! thanks everyone – Malcolm Sep 11 '18 at 15:45

1 Answers1

0

Slightly change in code, working fine for me. I am assuming that you are getting hidden select(from where you use to clone) value with form data also. Submit or $("#myForm").serialize() both are giving correct values no additional.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<button id="addBook" onclick="addBook()">Add Book</button>
<form action="POST" id="myForm">
  <div id="books"></div>
  <input type="submit" value="Submit">
</form> 

<select id="book" name="books[]" style="display: none;">
  <option value="A">A</option>
  <option value="B">B</option>
  <option value="C">C</option>
</select>


<script>
$count = 0;
function addBook() {
     $clone = $("#book").clone().show();
     $clone.appendTo("#books");
     $("#books select:last-child").attr('id','book-' + $count);
     $count += 1;
 }
 </script>
Farhan
  • 1,453
  • 2
  • 15
  • 20