1

I'm trying to build a little form, with multiple select fields. My goal is to let user multi-select some options from a first multiple select field. I then display his choice, with, in front of each result, a new select field. This is working fine.

However what I don't know is how to get the user's first and second choices together by clicking on the second button (#confirmation)

jQuery(document).ready(function($) {
  $("#yourChoice").on('click', function() {
    $("#multiple option:selected").each(function() {
      var html = '';
      html += '<p><span class="yourchoice">' + $(this).text() + '</span>';
      html += '<select id="quantity" name="quantity">';
      html += ' <option value="10">10</option> ';
      html += ' <option value="20">20</option> ';
      html += ' <option value="30">30</option> ';
      html += '</select></p>';
      $('#choice').append(html);
    })
  })

  $("#confirmation").on('click', function() {
    var group = $("#multiple option:selected").each();
    $("#quantity option:selected").each(function() {
      var finalText = '';
      finalText += '<span>' + $("#multiple option:selected").each().text() + '</span>';
      finalText += '<span class="yourchoice">' + $(this).val() + '</span>';
      $('#finalChoice').append(finalText);
    })
  })
})
.chosen-select {
  width: 300px;
}

#quantity {
  width: 300px;
  margin-left: 20px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>
  <select id="multiple" name="multiple" multiple="multiple" class="chosen-select">
    <option value="value1">Value 1</option>
    <option value="value2">Value 2</option>
    <option value="value3">Value 3</option>
    <option value="value4">Value 4</option>
    <option value="value5">Value 5</option>
    <option value="value6">Value 6</option>
  </select>
</p>

<button id="yourChoice">Add your choices</button>
<p>Choose a quantity</p>
<div id="choice"></div>

<button id="confirmation">Resume</button>
<div id="finalChoice"></div>

3
  • The issue is partly because you're using the same id on multiple elements which is invalid, and partly because you use each() with no handler function in a couple of places which is causing errors. What exactly should the output in #finalChoice look like after clicking #confirmation? Commented Apr 15, 2020 at 13:35
  • thank you for your answer. It should return the user's choices in sentences, for example value 2 :10 and Value 3 : 30. Like for the first click action.. I'm sorry, I do not feel comfortable with jquery ! So at the end I want to display user's choice and be able to send those informations in with the form Commented Apr 15, 2020 at 15:14
  • Thanks for clarifying. I added and answer for you Commented Apr 15, 2020 at 15:28

2 Answers 2

1

There's a few issues to address first, such as the repeated id attributes which are invalid, as id needs to be unique within the DOM, and should be replaced with a class. In addition you call each() with no handler in several places which is the cause of the error you see.

To make this work I'd suggest you build the HTML in the loops through the selected options. Best practice is to separate your HTML and JS as much as possible, so to achieve that you could store the template HTML structures in the DOM which are hidden until cloned, filled with relevant data and then appended in to the correct places. Try this:

jQuery(document).ready(function($) {
  $("#yourChoice").on('click', function() {
    $("#multiple option:selected").each(function() {
      let $clone = $('.choice:last').clone().appendTo('#choice')
      $clone.find('.yourchoice').text(this.value);
    });
  });

  $("#confirmation").on('click', function() {
    let $finalChoice = $('#finalChoice').empty();
    let finalChoices = $('#choice .choice').map(function() {
      let $choice = $(this);
      let $clone = $('.finalChoice:last').clone();
      $clone.find('.text').text($choice.find('.yourchoice').text());
      $clone.find('.quantity').text($choice.find('.quantity').val());
      return $clone;
    }).get();
    $finalChoice.append(finalChoices);
  })
})
.chosen-select {
  width: 300px;
}

#quantity {
  width: 300px;
  margin-left: 20px
}

.choice,
.finalChoice {
  display: none;
}

#choice .choice,
#finalChoice .finalChoice {
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>
  <select id="multiple" name="multiple" multiple="multiple" class="chosen-select">
    <option value="value1">Value 1</option>
    <option value="value2">Value 2</option>
    <option value="value3">Value 3</option>
    <option value="value4">Value 4</option>
    <option value="value5">Value 5</option>
    <option value="value6">Value 6</option>
  </select>
</p>

<button id="yourChoice">Add your choices</button>
<p>Choose a quantity</p>
<div id="choice"></div>


<button id="confirmation">Resume</button>
<div id="finalChoice"></div>

<!-- templates -->
<p class="choice">
  <span class="yourchoice"></span>
  <select class="quantity" name="quantity">
    <option value="10">10</option>
    <option value="20">20</option>
    <option value="30">30</option>
  </select>
</p>
<div class="finalChoice">
  <span class="text"></span>
  <span class="quantity"></span>
</div>

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

1 Comment

Thank you very much Rory !! It looks so easy fo you it's working perfectly !! I still have a question, looking at your code. What does $('.choice:last') mean ?Is it targetting the ".quantity" select field ? If yes, why not targeting it directly ? I don't understand..
0

Well, thanks to @Rory, I managed to limit the user selection on the first multiple select field. I add a single line, not sure if it's the best way, but it works !

jQuery(document).ready(function($) {
  $("#yourChoice").on('click', function() {
     $('#choice').empty();
    $("#multiple option:selected").each(function() {
      let $clone = $('.choice:last').clone().appendTo('#choice')
      $clone.find('.yourchoice').text(this.value);
    });
  });

  $("#confirmation").on('click', function() {
    let $finalChoice = $('#finalChoice').empty();
    let finalChoices = $('#choice .choice').map(function() {
      let $choice = $(this);
      let $clone = $('.finalChoice:last').clone();
      $clone.find('.text').text($choice.find('.yourchoice').text());
      $clone.find('.quantity').text($choice.find('.quantity').val());
      return $clone;
    }).get();
    $finalChoice.append(finalChoices);
  })
})
.chosen-select {
  width: 300px;
}

#quantity {
  width: 300px;
  margin-left: 20px
}

.choice,
.finalChoice {
  display: none;
}

#choice .choice,
#finalChoice .finalChoice {
  display: block;
}
.finalChoice{
  margin:20px auto;
}
button{
  background-color:#FF7F50;
  border:1px solid #757575;
  padding:10px 20px;
  color: #fff;
  text-transform:uppercase;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>
  <select id="multiple" name="multiple" multiple="multiple" class="chosen-select">
    <option value="value1">Value 1</option>
    <option value="value2">Value 2</option>
    <option value="value3">Value 3</option>
    <option value="value4">Value 4</option>
    <option value="value5">Value 5</option>
    <option value="value6">Value 6</option>
  </select>
</p>

<button id="yourChoice">Add your choices</button>
<p>Choose a quantity</p>
<div id="choice"></div>


<button id="confirmation">Resume</button>
<div id="finalChoice"></div>

<!-- templates -->
<p class="choice">
  <span class="yourchoice"></span>
  <select class="quantity" name="quantity">
    <option value="10">10</option>
    <option value="20">20</option>
    <option value="30">30</option>
  </select>
</p>
<div class="finalChoice">
 You asked <span class="quantity"></span> pieces
  of <span class="text"></span>
</div>

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.