skip to Main Content

Good day again, seniors.

This was the same code I was working on last time. The question is how would I create a reusable function for any of the option element and modify its value the same as the text content?

In the code below I only had one form but for my real project I do have a lot of forms that contains a select element so I would like to have a reusable function for each.

I tried using the textContent() but it doesn’t give me the text content of each selected options.

Again, thank you in advance!

<body>

    <form action="" id="form">

        <label for="name">Name:</label>
        <input type="text" name="name" id="name">

        <label for="age">Age:</label>
        <input type="number" name="age" id="age">

        <select name="favorites" id="fav">
            <option value="" selected disabled>Favorite Colors</option>
            <option value="Red">Red</option>
            <option value="Blue">Blue</option>
            <option value="Yellow">Yellow</option>
        </select>

        <select name="location" id="loc">
            <option value="" selected disabled>Location</option>
            <option value="L">Luzon</option>
            <option value="V">Visayas</option>
            <option value="M">Mindanao</option>
        </select>

        <button id="btn" type="submit">OK</button>

    </form>


      <script>
        let list = [];
        const n = document.getElementById("name"); 
        const a = document.getElementById("age"); 
        const clr = document.getElementById("fav"); 
        const loc =  document.getElementById("loc"); 

        
   const addDets = (ev) => {
            ev.preventDefault();
            let officials = {
                name: n.value, 
                age: a.value, 
                favColor: clr.value, 
                location: loc.value 
            }
            list.push(officials)
            document.forms[0].reset();
            console.log(list);
        }

        document.addEventListener("DOMContentLoaded", ()=>{
            document.getElementById('btn').addEventListener('click', addDets);
        });
     </script>
</body>


2

Answers


  1. ID attributes can often be a nuisance to work with when generating dynamic content of trying, as here, to have a generic function to process similar requests so I find it easier to ignore them and use other methods of identifying DOM elements. You state there are "a lot of forms that contains a select element so I would like to have a reusable function for each" – the following uses a single delegated event listener that is bound to the submit buttons with class submit-btn – the handler captures a reference to all the form elements as an array which is filtered to remove empty elements. The name/value pairs from all form elements (unless empty) are added to an object literal and pushed onto the global list array stack for whatever processing you need. This seems fairly generic

    let list=[];
            
    document.addEventListener('click',e=>{
      if( e.target instanceof HTMLButtonElement && e.target.classList.contains('submit-btn') ){
    
        e.preventDefault();
    
        let form=e.target.closest('form');
        let data={};
        let col=[...form.elements].filter(n=>n.value!='');
          col.forEach(n=>data[n.name]=n.value);
        list.push( data );
        form.reset();
    
        console.log( list );
      }
    });
    <form name='myform-1'>
    
        <label>Name: <input type="text" name="name"></label>
        <label>Age: <input type="number" name="age"></label>
    
        <select name="favorites">
            <option selected disabled hidden>Favorite Colors</option>
            <option value="Red">Red</option>
            <option value="Blue">Blue</option>
            <option value="Yellow">Yellow</option>
        </select>
    
        <select name="location">
            <option selected disabled hidden>Location</option>
            <option value="L">Luzon</option>
            <option value="V">Visayas</option>
            <option value="M">Mindanao</option>
        </select>
    
        <button class="submit-btn" type="submit">OK</button>
    </form>
    
    
    
    
    <form name='myform-2'>
    
        <label>Height: <input type="number" name="height"></label>
        <label>Weight: <input type="number" name="weight"></label>
    
        <select name="category">
            <option selected disabled hidden>Favorite Colors</option>
            <option value="Red">Red dfgdf g</option>
            <option value="Blue">Blue dfgdf g</option>
            <option value="Yellow">Yellow dfgfd g</option>
        </select>
    
        <select name="skill">
            <option selected disabled hidden>Location</option>
            <option value="L">Luzon asda sd</option>
            <option value="V">Visayas asd as da</option>
            <option value="M">Mindanao asd as d</option>
        </select>
    
        <button class="submit-btn" type="submit">OK</button>
    </form>

    update

    Reading the penultimate line from the question I note that you say "it doesn't give me the text content of each selected options" which was not accounted for above. To capture that text content the portion of code within the forEach loop can be modified like this:

      col.forEach(n=>{
        if( n instanceof HTMLSelectElement ) data[ n.name ]=n.options[ n.options.selectedIndex ].text;
        else data[n.name]=n.value;
      });
    

    or even:

      col.forEach(n=>{
        let value=( n instanceof HTMLSelectElement ) ? n.options[ n.options.selectedIndex ].text : n.value;
        data[n.name]=value;
      });
    

    That will assign the name/text rather than name/value to the output object which seems more inline with your comment.

    Login or Signup to reply.
  2. have you tried using the "selectedOptions" property of the select element?

    Something like this:

    const getSelectedOption = (selectElement) => {
          const selectedOption = selectElement.selectedOptions[0];
          const value = selectedOption.value;
          const text = selectedOption.textContent;
          return { value, text };
      }
    
      const addDets = (ev) => {
          ev.preventDefault();
          let officials = {
              name: n.value, 
              age: a.value, 
              favColor: getSelectedOption(clr), 
              location: getSelectedOption(loc)
          }
          list.push(officials)
          document.forms[0].reset();
          console.log(list);
      }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search