Tips for building a form that allows for list submissions

I am working on creating a form where users can input a list of 1-10 items. Subsequently, they will be prompted to provide an explanation (in a text box) for each item on the list. However, I am facing challenges in implementing this dynamically.

For a single question, I currently have:

<form id="myform">
    <input id="choice1" type="text" name="item1" placeholder="" />
    <input type="submit" name="submit" value="Next" />
</form>

If there were two items in the list:

<form id="myform">
    <input id="choice1" type="text" name="item1" placeholder="" />
    <input id="choice2" type="text" name="item2" placeholder="" />
    <input type="submit" name="submit" value="Next" />
</form>

The follow-up question would be:

<h3 class="fs-subtitle">Explain why {listChoice1} is included in your list</h3>
    <textarea id="explanation1" type="text" name="explanation1"></textarea>
    <input type="submit" name="submit" class="submit action-button next" value="Next" />

I am looking for a way to allow users to easily expand the list size as needed and dynamically generate follow-up questions for each item on the list. Any suggestions on how to achieve this seamlessly?

Answer №1

Utilize a template and then apply cloneNode while keeping track of the index.

var indexForm = 1;
var submit = document.querySelector("input[name='submit']");

submit.addEventListener("click", function(e){
  // Start by adding explanation
  var div = document.querySelector("div.template");
  var title = div.children[1].cloneNode(true); // Remember to include textnode when copying!
  var textarea = div.children[2].cloneNode();
  
  // Update the values
  title.innerHTML = title.innerHTML.replace("{listChoice}", document.querySelector("#choice"+indexForm).value);
  textarea.id = "explanation" + indexForm;
  textarea.name = "explanation" + indexForm;
  
  // Add the explanation to the DOM
  // Select the input submit
  submit.parentNode.insertBefore(title, submit);
  submit.parentNode.insertBefore(textarea, submit);
  
  // Increment indexForm by 1
  indexForm++;
  // Add new input
  var newinput = div.children[0].cloneNode();
  newinput.id = "choice" + indexForm;
  newinput.name = "choice" + indexForm;
  submit.parentNode.insertBefore(newinput, submit);
  
  
  // Prevent form from getting executed
  e.preventDefault();
})
div.hidden {
 display: none;
}
<form id="myform">
    <input id="choice1" type="text" name="item1" placeholder="" />
    <input type="submit" name="submit" value="Next" />
</form>

<div class="template hidden">
<input id="choice_template" type="text" name="item" placeholder="" />
<h3 class="fs-subtitle">Explain why {listChoice} is on your list</h3>
    <textarea id="explanation_template" type="text" name="explanation"></textarea>
</div>

Answer №2

Upon triggering the blur event on an input, you have the opportunity to verify if it contains a value. If it does, you can leverage jQuery's insertAfter function to dynamically append a textarea after the input, prompting for further details.

<form id="myform">
  <input type="text" name="item1" />
  <input type="submit" name="submit" value="Next" />
</form>

Achieve this behavior with just these 4 lines of jQuery:

$(function() {
  /* Listen for blur event on text input fields */
  $('body').on('blur', 'input[type="text"]', function(e){
    /* Check if next element is not a textarea and current input is not empty */
    if(!$(this).next().is('textarea') && $(this).val() != '') {
      /* Generate a textarea with a similar name attribute */
      var textarea = "<textarea name='textarea_"+$(this).attr('name')+"' placeholder='Explain why this is on your list'></textarea>";
      /* Insert the textarea after the current input */
      $( textarea ).insertAfter( this );
    }
  });
});

In addition to that, consider adding another text input for their subsequent list item using the following 6 lines of jQuery:

$(function() {
  /* Listen for blur event on text input fields */
  $('body').on('blur', 'input[type="text"]', function(e){
    /* Check if next element is not a textarea and current input is not empty */
    if(!$(this).next().is('textarea') && $(this).val() != '') {
      /* Generate a textarea with a somewhat analogous name */
      var textarea = "<textarea name='textarea_"+$(this).attr('name')+"' placeholder='Explain why this is on your list'></textarea>";
      /* Insert the textarea after the current input */
      $( textarea ).insertAfter( this );
      /* Create a new text input field */
      var newinput = "<input name='item"+(parseInt($(this).attr('name').substring(4))+1)+"' type='text' />";
      /* Insert the new input before the submit button */
      $( newinput ).insertBefore( $("input[type='submit']") );
    }
  });
});

For a working example and code snippet, refer to: https://codepen.io/anon/pen/OjmaxY/?editors=1010

This approach simplifies the form structure by utilizing only 1 form, minimizes the jQuery code to just 6 lines, and eliminates the need for CSS styling.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Inconsistency in css asset URLs across various pages discovered while working with Rails

When using assets stylesheet to load a CSS file, I noticed that it only loads on the index page. Upon inspecting with F12, the console shows the URL for other pages as well, which appends "/cloths" to the asset path. I am currently utilizing the default la ...

Updating class after refresh of ng-repeat in AngularJS/Javascript

I am currently using angularJs in conjunction with cordova. Within my ng-repeat loop, each item has an ng-click event that stores the value of the item in an array. Additionally, when I click on an item, it toggles a class on the corresponding div (using ...

The JQuery scroll function is not triggered right after a page refresh

Recently, I encountered an issue with my jQuery function that is designed to keep a div at the top of the page after scrolling beyond its original position. Strangely, following a button click (postback), the functionality seems to break and requires users ...

The synchronization of template stamping with the connectedCallback function

Issue Explanation It appears that there is a timing discrepancy with Polymer (2.x) when querying for nodes contained within a template element immediately after the connectedCallback() function has been executed. Ideally, the initial call of this.shadowRo ...

Accessing the text content of the clicked element using vanilla JavaScript

Retrieve an item from the dropdown list and insert it into a button's value. function updateButton() { document.getElementById("ul").classList.toggle("show"); } var dropdown = document.getElementById('ul'); var items = ["HTML", "CSS", "Ja ...

Asynchronous binding within a dynamic form

After following the Angular guide on creating dynamic forms, I have developed a series of classes to generate forms dynamically. While this approach is effective, it doesn't offer much efficiency unless the forms can be dynamically generated based on ...

Is it possible to retrieve an element styled inline, such as an input?

Is it possible to style elements with inline styling using a selector such as div[style=float:right;] {}? For example: <div style="float: right;"></div> ...

The terminal does not recognize the nodemon command

My goal is to automate server reloads using nodemon. I have successfully installed it locally and set the start command as nodemon app.js with this code: "scripts": { "start": "nodemon app.js" } Initially, everything was running smoothly. However, ...

Images added with JavaScript are not displaying on the webpage

On the website I'm working on, I am attempting to use Javascript to insert an image. My method involves using createElement and setAttribute to specify the image location in my file directory. Below is a snippet of the code I've been using: var l ...

The local data storage function in chrome does not effectively store data as intended

I'm currently working on developing a chrome extension that requires storing data locally. However, I am facing an issue with the code in my popup.html file as it is not setting values in local storage as expected. My manifest.json file has both "stor ...

Display or conceal various objects using a single button in HTML

I've been working on creating a chatbot widget for my website, but I've run into an issue. The "Chat with us" button only shows the bot and not the close button as well. Here's what I've attempted: <input id="chat" type="button" on ...

Include an icon in the header of a jumbotron

Here is the jumbotron configuration I am working with: https://i.stack.imgur.com/JQGpA.png This jumbotron was generated using the following code: <div class="col-sm-2"> <div class="jumbotron jumbotron-fluid top-space"> <div ...

In the world of React in Meteor, the command event.preventDefault() doesn't seem

I have encountered an issue with my application development. I am utilizing a submit form in Meteor with React, and although I am using event.preventDefault(), the page continues to reload every time the submit button is clicked. Following a brief delay, i ...

Unable to load the header file as required

As I work on developing my website, I have implemented PHP to include a standard header page across all subsequent pages. The header is basic, containing the navigation bar, logo, and other elements. While the require("header.php") function works for most ...

Stop users from swiping down on Lockscreen/Notification Center in a react-native app

With the release of iOS 11, there was a change in how the system prioritizes gestures on screen edges versus user-defined gestures. Previously, when the status bar was hidden, iOS would give priority to custom gestures on screen edges. Now, in order to ac ...

Harnessing the power of jQuery ajax in conjunction with the versatile knockout.js mapping

I'm currently attempting to utilize jquery's $.ajax function along with the knockout.js mapping plugin. The test api being used can be found here: However, I seem to be encountering an issue where the data retrieved is not in the expected format ...

Optimizing row performance for Angular grids in the Chrome browser

When creating a component that includes a table with numerous rows, everything works well with small amounts of data. However, once the item count reaches 2000 or more, it starts lagging. Scrolling and animations become sluggish. Even after trying to impl ...

Utilizing Javascript within a PHP while loop to showcase map markers

Is there a way to display multiple database entries in a loop and show them as markers on a map like this: https://i.stack.imgur.com/SwaGP.png I am struggling with looping through JavaScript in PHP to display multiple markers. Is it possible to achieve t ...

Tips for extracting particular information from a website and displaying it within my application

While I have searched for a solution to my problem, I couldn't find an answer that fits my specific needs. I am attempting to extract specific information (highlighted in red) from this website: . I understand that JSON parsing can retrieve this data, ...

"Exploring the New Features of Bootstrap 5: Button Collapse and

I am struggling to get two buttons working with Bootstrap 5. The first button is supposed to trigger two JavaScript functions to open a bootstrap carousel. The second button is a simple collapse button designed to reveal a long text string. Unfortunately, ...