skip to Main Content

I’ve created a multi-page form (5 pages) – each page has radio inputs and only one selection can be made per page (all fields are marked as required). Most answers will be assigned a ‘product’, some answers will be assigned the same product – I need to output the recommended assigned products on the confirmation page. at minimum, one product will be recommended as all questions on the first page have a product assigned, maximum there could be 5 products recommended if the user makes selections where the answer is associated to a product.

Simplified tables for context:

page 1 answers page 1 products
Choice A Product 1
Choice B Product 1
Choice C Product 2
Choice D Product 3
Choice E Product 1
Choice F Product 4
page 2 answers page 2 products
Choice A Product 1
Choice B Product 2
Choice C Product 3
Choice D no product
Choice E no product

and so on…

I sourced some jQuery(?) on another post, and made some edits to interact with the IDs association to my options

<script>

$('input[type=radio]').on("change", buttonChanged);

function buttonChanged() {
  if ($("#7_1").is(':checked') && $("#14_12").is(':checked') && $("#12_12").is(':checked') && $("#10_12").is(':checked') && $("#22_12").is(':checked')) {
    $(".test-display1").show();
  } else if ($("#7_2").is(':checked') && $("#14_13").is(':checked') && $("#12_13").is(':checked') && $("#10_13").is(':checked') && $("#22_13").is(':checked')) {
    $(".test-display2").show();
  }
}

</script>

The above works just fine, and the correct confirmation block displays – however, I’m just guessing there has to be an easier way to calculate/generate all possible combinations rather than writing each possible combo and having a lot of confirmation blocks in the code… I can use jQuery or JavaScript with the form tool I’m using – how to write this a bit easier?

Some of the HTML form code also (build is in progress still):

<form>
  <!-- **PAGE 1** -->
  <div class="option-wrapper">
    <div class="ee_list_item_label">
      <span class="input"><input type="radio" name="7" id="7_1" value="1" required="required"></span>
      <label class="ee_editable ee_answertext" for="7_1">Improved Hair, Skin &amp; Nails</label>
    </div>
  </div>
  <div class="option-wrapper">
    <div class="ee_list_item_label">
      <span class="input"><input type="radio" name="7" id="7_2" value="2" required="required"></span>
      <label class="ee_editable ee_answertext" for="7_2"><span>Bones &amp; Joint Support</span>
        </label>
    </div>
  </div>
  <div class="option-wrapper">
    <div class="ee_list_item_label">
      <span class="input"><input type="radio" name="7" id="7_3" value="3" required="required"></span>
      <label class="ee_editable ee_answertext" for="7_3"><span>Healthy Energy</span>
        </label>
    </div>
  </div>
  <div class="option-wrapper">
    <div class="ee_list_item_label">
      <span class="input"><input type="radio" name="7" id="7_4" value="4" required="required"></span>
      <label class="ee_editable ee_answertext" for="7_4"><span>Exercise Support</span>
        </label>
    </div>
  </div>
  <div class="option-wrapper">
    <div class="ee_list_item_label">
      <span class="input"><input type="radio" name="7" id="7_5" value="5" required="required"></span>
      <label class="ee_editable ee_answertext" for="7_5"><span>Anti-Aging Support</span>
        </label>
    </div>
  </div>
  <div class="option-wrapper">
    <div class="ee_list_item_label">
      <span class="input"><input type="radio" name="7" id="7_8" value="8" required="required"></span>
      <label class="ee_editable ee_answertext" for="7_8"><span>General Wellness</span>
        </label>
    </div>

    <hr />
    <!-- **PAGE 2** -->
    <div class="ee_list_item_label">
      <span class="input"><input type="radio" name="14" id="14_12" value="12" required="required"></span>
      <label class="ee_editable ee_answertext" for="14_12"><span>30 mins or more intense exercise 5-7 times a week</span>
        </label>
    </div>
  </div>
  <div class="option-wrapper">
    <div class="ee_list_item_label">
      <span class="input"><input type="radio" name="14" id="14_13" value="13" required="required"></span>
      <label class="ee_editable ee_answertext" for="14_13"><span>30 mins or more moderate exercise daily</span>
        </label>
    </div>
  </div>
  <div class="option-wrapper">
    <div class="ee_list_item_label">
      <span class="input"><input type="radio" name="14" id="14_14" value="14" required="required"></span>
      <label class="ee_editable ee_answertext" for="14_14"><span>30 mins exercise 3-4 times a week</span></label>
    </div>
  </div>
  <div class="option-wrapper">
    <div class="ee_list_item_label">
      <span class="input"><input type="radio" name="14" id="14_15" value="15" required="required"></span>
      <label class="ee_editable ee_answertext" for="14_15"><span>Daily walking</span></label>
    </div>
  </div>
  <div class="option-wrapper">
    <div class="ee_list_item_label">
      <span class="input"><input type="radio" name="14" id="14_16" value="16" required="required"></span>
      <label class="ee_editable ee_answertext" for="14_16"><span>Little to no exercise</span>
        </label>
    </div>
  </div>
</form>

2

Answers


  1. Something like this?

    I am not 100% sure of the mapping, but the code can be changed to handle alternatives

    Note the delegation

    // Map answers to products
    const answerToProductMap = {
      "7_1": "Product 1",
      "7_2": "Product 1",
      "7_3": "Product 2",
      "7_4": "Product 3",
      "7_5": "Product 1",
      "7_8": "Product 4",
      "14_12": "Product 1",
      "14_13": "Product 2",
      "14_14": "Product 3",
      "14_15": null, // No product
      "14_16": null, // No product
    };
    
    window.addEventListener('load', () => {
      const form = document.getElementById("multiPageForm");
      const recommendationsContainer = document.createElement("div");
      recommendationsContainer.classList.add("test-display");
      recommendationsContainer.hidden = true;
      form.appendChild(recommendationsContainer);
      const getSelectedProducts = () => {
        const selectedProducts = new Set();
    
        // Loop through checked radio inputs and map to products
        form.querySelectorAll("input[type='radio']:checked").forEach((input) => {
          const product = answerToProductMap[input.id];
          console.log(input.id, product)
          if (product) selectedProducts.add(product);
        });
    
        return Array.from(selectedProducts);
      };
    
      // Update recommendations
      const updateRecommendations = () => {
        const products = getSelectedProducts();
        console.log(products)
        recommendationsContainer.hidden = products.length === 0;
        recommendationsContainer.innerHTML = products.map((product) => `<div>${product}</div>`).join("");
      };
      // Event delegation: Listen for changes on radio buttons
      form.addEventListener("change", (event) => {
        if (event.target.matches("input[type='radio']")) {
          updateRecommendations();
        }
      });
    
      updateRecommendations();
    });
    <form id="multiPageForm">
      <!-- **PAGE 1** -->
      <div class="option-wrapper">
        <div class="ee_list_item_label">
          <span class="input"><input type="radio" name="7" id="7_1" value="1" required="required"></span>
          <label class="ee_editable ee_answertext" for="7_1">Improved Hair, Skin &amp; Nails</label>
        </div>
      </div>
      <div class="option-wrapper">
        <div class="ee_list_item_label">
          <span class="input"><input type="radio" name="7" id="7_2" value="2" required="required"></span>
          <label class="ee_editable ee_answertext" for="7_2"><span>Bones &amp; Joint Support</span>
            </label>
        </div>
      </div>
      <div class="option-wrapper">
        <div class="ee_list_item_label">
          <span class="input"><input type="radio" name="7" id="7_3" value="3" required="required"></span>
          <label class="ee_editable ee_answertext" for="7_3"><span>Healthy Energy</span>
            </label>
        </div>
      </div>
      <div class="option-wrapper">
        <div class="ee_list_item_label">
          <span class="input"><input type="radio" name="7" id="7_4" value="4" required="required"></span>
          <label class="ee_editable ee_answertext" for="7_4"><span>Exercise Support</span>
            </label>
        </div>
      </div>
      <div class="option-wrapper">
        <div class="ee_list_item_label">
          <span class="input"><input type="radio" name="7" id="7_5" value="5" required="required"></span>
          <label class="ee_editable ee_answertext" for="7_5"><span>Anti-Aging Support</span>
            </label>
        </div>
      </div>
      <div class="option-wrapper">
        <div class="ee_list_item_label">
          <span class="input"><input type="radio" name="7" id="7_8" value="8" required="required"></span>
          <label class="ee_editable ee_answertext" for="7_8"><span>General Wellness</span>
            </label>
        </div>
    
        <hr />
        <!-- **PAGE 2** -->
        <div class="ee_list_item_label">
          <span class="input"><input type="radio" name="14" id="14_12" value="12" required="required"></span>
          <label class="ee_editable ee_answertext" for="14_12"><span>30 mins or more intense exercise 5-7 times a week</span>
            </label>
        </div>
      </div>
      <div class="option-wrapper">
        <div class="ee_list_item_label">
          <span class="input"><input type="radio" name="14" id="14_13" value="13" required="required"></span>
          <label class="ee_editable ee_answertext" for="14_13"><span>30 mins or more moderate exercise daily</span>
            </label>
        </div>
      </div>
      <div class="option-wrapper">
        <div class="ee_list_item_label">
          <span class="input"><input type="radio" name="14" id="14_14" value="14" required="required"></span>
          <label class="ee_editable ee_answertext" for="14_14"><span>30 mins exercise 3-4 times a week</span></label>
        </div>
      </div>
      <div class="option-wrapper">
        <div class="ee_list_item_label">
          <span class="input"><input type="radio" name="14" id="14_15" value="15" required="required"></span>
          <label class="ee_editable ee_answertext" for="14_15"><span>Daily walking</span></label>
        </div>
      </div>
      <div class="option-wrapper">
        <div class="ee_list_item_label">
          <span class="input"><input type="radio" name="14" id="14_16" value="16" required="required"></span>
          <label class="ee_editable ee_answertext" for="14_16"><span>Little to no exercise</span>
            </label>
        </div>
      </div>
    </form>
    Login or Signup to reply.
  2. This is another approach using data embedded inside the html itself as data attributes so that each input[type="radio"] meant to recommend a given product, holds its name inside a dedicated data-product attribute.

    I crafted a function getProducts that when invoked will fetch all of those options when checked and will return the list of corresponding product names bound to them (discarding duplicates and ignoring empty values).

    Then each of those .option > input[type="radio"] will have its own change event handler (yet the delegation would be more appropriate to scale better) that will each time clear the #recommend container and fill it with the list of recommended products resulting from the current choices made.

    //returns the list of products bound to the selected options
    function getProducts(){
      //return result as a Set (so discarding duplicated values) converted to plain array
      return [...new Set(  
          //select all the input radio checked
          $('input[type=radio]:checked')
            //and transform such list in the corresponding list of data-product values
            .map(function () {
              return $(this).data('product');
            })
            .get() // to plain array
            .filter(value => value !== '') // Filter out empty strings
        )];
    }
    
    //attach a change event handler to all the .option > input[type=radio]
    $('.option > input[type="radio"]').on("change", ()=>{
      //get the list of products according to selected options
      const productNames = getProducts();    
      //convert the list of string to a list of elements wrapping those strings
      //here it handles the possibility that the product name contains special characters
      const products = productNames.map(productName => $('<div>').text(productName));  
      $('#recommended').empty().append(products);
    });
    .choice{
      border: solid 1px #ccc;
      padding: 1em;
      width: fit-content;
      margin-bottom: 1em;
    }
    
    .option input[type="radio"],
    .option label{
      cursor: pointer;
    }
    
    #recommended{
      border: solid 1px;  
      margin-bottom: 1em;
      padding: 1em;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    
    <div id="recommended"></div>
    
    <div class="choice">
      <div class="option">
        <input type="radio" name="7" id="7_1" value="1" required="required" data-product="Product 1">
        <label for="7_1">Improved Hair, Skin &amp; Nails</label>
      </div>
      <div class="option">
        <input type="radio" name="7" id="7_2" value="2" required="required" data-product="Product 1">
        <label for="7_2">Bones &amp; Joint Support</label>
      </div>
      <div class="option">
        <input type="radio" name="7" id="7_3" value="3" required="required" data-product="Product 2">
        <label for="7_3">Healthy Energy</label>
      </div>
      <div class="option">
        <input type="radio" name="7" id="7_4" value="4" required="required" data-product="Product 3">
        <label for="7_4">Exercise Support</label>
      </div>
      <div class="option">
        <input type="radio" name="7" id="7_5" value="5" required="required" data-product="Product 1">
        <label for="7_5">Anti-Aging Support</label>
      </div>
      <div class="option">
        <input type="radio" name="7" id="7_8" value="8" required="required" data-product="Product 4">
        <label for="7_8">General Wellness</label>
      </div>  
    </div>
    
    <div class="choice">
      <div class="option">
        <input type="radio" name="14" id="14_12" value="12" required="required" data-product="Product 1">
        <label for="14_12">30 mins or more intense exercise 5-7 times a week</label>
      </div>
      <div class="option">
        <input type="radio" name="14" id="14_13" value="13" required="required" data-product="Product 2">
        <label for="14_13">30 mins or more moderate exercise daily</label>
      </div>
      <div class="option">
        <input type="radio" name="14" id="14_14" value="14" required="required" data-product="Product 3">
        <label for="14_14">30 mins exercise 3-4 times a week</label>
      </div>
      <div class="option">
        <input type="radio" name="14" id="14_15" value="15" required="required" data-product="">
        <label for="14_15">Daily walking</label>
      </div>
      <div class="option">
        <input type="radio" name="14" id="14_16" value="16" required="required" data-product="">
        <label for="14_16">Little to no exercise</label>
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search