JavaScript Subclass Selections - Resetting Choices

Hey there, I'm facing an issue with subcategories and need some help. When I change the options, the function to clear the OS list is not working properly - it keeps growing as changes are made. I've tried adding the remove function in various places but nothing seems to fix it. To recreate the problem, select "Internal" for network and check the OS list. Then, select "Physical" for resource and see how the OS list behaves. I have a removeAllOptions function in the list.js file that is not clearing the OS selections when the resource is changed (although it works fine when the network is changed). Any ideas on how to solve this would be greatly appreciated.

Cheers, Ray

Check out my JS Fiddle here

index.php

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

    <head>
    <script language="javascript" src="list.js"></script>
    </head>
    <head>
   <script language="javascript" src="list.js"></script>
</head>
<div class="left_box" />
<body onload="fillCategory();">
   <div id="formWrapper" />
   <FORM name="drop_list" action="availability.php" method="POST" />
   <fieldset>
      <label>Network</label>
      <SELECT class="formSelect" NAME="build" onChange="selectResource();">
         <Option value="">Select Internal or Firewall</option>
      </SELECT>
      <br />
      <br />
      <label>Resource</label>
      <SELECT class="formSelect" id="resource" NAME="resource" 
          onChange="selectOS(this);">
         <Option value="">Resource</option>
      </SELECT>
      <br />
      <br />
      <label>OS</label>
      <SELECT class="formSelect" id="OS" NAME="OS">
         <Option value="">OS</option>
      </SELECT>
      <br />
      <br />
   </fieldset>

list.js

function fillCategory(){ 
 // This function fills the category list on page load
addOption(document.drop_list.build, "Internal", "Internal", "");
addOption(document.drop_list.build, "Internal Cluster", "Internal Cluster", "");
addOption(document.drop_list.build, "Firewall", "Firewall", "");
addOption(document.drop_list.build, "Firewall Cluster", "Firewall Cluster", "");
}

function selectResource(){
// Function executes after selecting a category
removeAllOptions(document.drop_list.resource);
removeAllOptions(document.drop_list.OS);

if((document.drop_list.build.value == 'Internal')||(document.drop_list.build.value == 'Firewall')){
addOption(document.drop_list.resource,"Virtual", "Virtual","");
addOption(document.drop_list.resource,"Physical", "Physical","");
}

if((document.drop_list.build.value == 'Internal Cluster') || (document.drop_list.build.value     == 'Firewall Cluster')) {
addOption(document.drop_list.resource,"Physical", "Physical");
}
    selectOS();
}
function selectOS(el){

if(document.drop_list.build.value == 'Internal') {
addOption(document.drop_list.OS,"AIX 6.1", "AIX 6.1");
addOption(document.drop_list.OS,"Linux 5.0 (64-bit)", "Linux 5.0 (64-bit)");
addOption(document.drop_list.OS,"Linux 6.0 (64-bit)", "Linux 6.0 (64-bit)");
addOption(document.drop_list.OS,"Solaris 10", "Solaris 10");
addOption(document.drop_list.OS,"Windows 2008 (64-bit) Standard", "Windows 2008 (64-bit) Standard");
addOption(document.drop_list.OS,"Windows 2008 (64-bit) Enterprise", "Windows 2008 (64-bit)   Enterprise");
addOption(document.drop_list.OS,"Windows 2008 R2 (64-bit) Standard", "Windows 2008 R2 (64-bit)  Standard");
addOption(document.drop_list.OS,"Windows 2008 R2 (64-bit) Enterprise", "Windows 2008 R2 (64-bit) Enterprise");
addOption(document.drop_list.OS,"Special", "Special");
}

if((document.drop_list.build.value == 'Internal Cluster') ||(document.drop_list.build.value == 'Firewall Cluster')){
addOption(document.drop_list.OS,"AIX 6.1", "AIX 6.1");
addOption(document.drop_list.OS,"Linux 5.0 (64-bit)", "Linux 5.0 (64-bit)");
addOption(document.drop_list.OS,"Linux 6.0 (64-bit)", "Linux 6.0 (64-bit)");
addOption(document.drop_list.OS,"Solaris 10", "Solaris 10");
addOption(document.drop_list.OS,"Windows 2008 (64-bit) Enterprise", "Windows 2008 (64-bit) Enterprise");
addOption(document.drop_list.OS,"Windows 2008 R2 (64-bit) Enterprise", "Windows 2008 R2 (64-bit) Enterprise");
}

if((document.drop_list.build.value == 'Firewall') && (document.drop_list.resource.value == 'Virtual')) {
addOption(document.drop_list.OS,"Linux 5.0 (64-bit)", "Linux 5.0 (64-bit)");
addOption(document.drop_list.OS,"Linux 6.0 (64-bit)", "Linux 6.0 (64-bit)");
addOption(document.drop_list.OS,"Windows 2008 (64-bit) Enterprise", "Windows 2008 (64-bit) Enterprise");
addOption(document.drop_list.OS,"Windows 2008 R2 (64-bit) Enterprise", "Windows 2008 R2 (64-bit) Enterprise");
}

if((document.drop_list.build.value == 'Firewall') && (document.drop_list.resource.value == 'Physical')) {
addOption(document.drop_list.OS,"AIX 6.1", "AIX 6.1");
addOption(document.drop_list.OS,"Linux 5.0 (64-bit)", "Linux 5.0 (64-bit)");
addOption(document.drop_list.OS,"Linux 6.0 (64-bit)", "Linux 6.0 (64-bit)");
addOption(document.drop_list.OS,"Solaris 10", "Solaris 10");
addOption(document.drop_list.OS,"Windows 2008 (64-bit) Enterprise", "Windows 2008 (64-bit) Enterprise");
addOption(document.drop_list.OS,"Windows 2008 R2 (64-bit) Enterprise", "Windows 2008 R2 (64-bit) Enterprise");
}

} 

function removeAllOptions(selectbox)
{
    var i;
    for(i=selectbox.options.length-1;i>=0;i--)
{
    //selectbox.options.remove(i);
    selectbox.remove(i);
}
} 


function addOption(selectbox, value, text )
{
var optn = document.createElement("OPTION");
optn.text = text;
optn.value = value;

selectbox.options.add(optn);
}

Answer №1

If you need a quick solution, just make sure to invoke the removeAllOptions() function every time you call another function.

However, it's not efficient to have repetitive code and access the DOM repeatedly whenever you interact with the select box.

It's better to store them in a cache for easier access.

Here's the optimized code:

var networkList = '';
var resourceList = '';
var osList = '';

function fillCategory() {
    // Load the category list initially
    networkList = document.drop_list.build;
    resourceList = document.drop_list.resource;
    osList = document.drop_list.OS;
    var catOptions = ["Internal", "Internal Cluster"
                      , "Firewall", "Firewall Cluster"];
    addOptions(networkList, catOptions);
}

function selectResource() {
    // Perform actions when a category is selected
    removeAllOptions(resourceList);
    removeAllOptions(osList);
    var networkValue = networkList.value;

    if ((networkValue == 'Internal') || (networkValue == 'Firewall')) {
        addOptions(resourceList, ["Virtual", "Physical"]);
    }
    else if ((networkValue == 'Internal Cluster') 
               || (networkValue == 'Firewall Cluster')) {
        addOptions(resourceList, ["Physical"]);
    }
    selectOS();
}

function selectOS(el) {
    var networkValue = networkList.value;
    var resourceValue = resourceList.value;

    var internalOS = ["AIX 6.1","Linux 5.0 (64-bit)","Linux 6.0 (64-bit)"
                      ,"Solaris 10","Windows 2008 (64-bit) Standard"
                      ,"Windows 2008 (64-bit) Enterprise"
                      , "Windows 2008 R2 (64-bit) Standard" 
                      ,"Windows 2008 R2 (64-bit) Enterprise"
                      , "Special"];
    var clusterOS = ["AIX 6.1","Linux 5.0 (64-bit)","Linux 6.0 (64-bit)",
                     "Solaris 10","Windows 2008 (64-bit) Enterprise"
                     ,"Windows 2008 R2 (64-bit) Enterprise" ];

    var firewallOS = ["Linux 5.0 (64-bit)","Linux 6.0 (64-bit)"
                       ,"Windows 2008 (64-bit) Enterprise"
                      ,"Windows 2008 R2 (64-bit) Enterprise" ];

    removeAllOptions(osList); // Clear the OS list
    if (networkValue == 'Internal') {
        addOptions(osList , internalOS);
    }
    else if ((networkValue == 'Internal Cluster') 
              || (networkValue == 'Firewall Cluster')) {
        addOptions(osList , clusterOS);
    }
    else if ((networkValue == 'Firewall') && (resourceValue == 'Virtual')) {
       addOptions(osList , firewallOS);
    }
    else if ((networkValue == 'Firewall') && (resourceValue == 'Physical')) {
        addOptions(osList , clusterOS);
    }

}

function removeAllOptions(selectbox) {
    var i;
    for (i = selectbox.options.length - 1; i >= 0; i--) {
        selectbox.remove(i);
    }
}

function addOptions(selectbox, arr) {
    // Populate Select Options using an array
    for (var i = 0; i < arr.length; i++) {
        var optn = document.createElement("OPTION");
        optn.text = arr[i];
        optn.value = arr[i];
        selectbox.options.add(optn);
    }
}​

This can be further optimized. It's recommended to use jQuery for such tasks and move inline JavaScript into separate script files.

Check out this working fiddle for reference.

Answer №2

When clearing the select options with

removeAllOptions(document.drop_list.OS);
, it is supposed to be called from the function selectResource. However, the resource onChange handler is mistakenly calling selectOS, thus disregarding the code for removing options.

To resolve this issue:

function selectResource(){
    // This function is triggered on category selection
    removeAllOptions(document.drop_list.resource);

    if((document.drop_list.build.value == 'Internal')||(document.drop_list.build.value == 'Firewall')) {
        addOption(document.drop_list.resource,"Virtual", "Virtual","");
        addOption(document.drop_list.resource,"Physical", "Physical","");
    }

    if((document.drop_list.build.value == 'Internal Cluster') || (document.drop_list.build.value     == 'Firewall Cluster')) {
        addOption(document.drop_list.resource,"Physical", "Physical");
    }

    selectOS();
}

function selectOS(el) {

    removeAllOptions(document.drop_list.OS);

    if(document.drop_list.build.value == 'Internal') {
        addOption(document.drop_list.OS,"AIX 6.1", "AIX 6.1");
        addOption(document.drop_list.OS,"Linux 5.0 (64-bit)", "Linux 5.0 (64-bit)");
        addOption(document.drop_list.OS,"Linux 6.0 (64-bit)", "Linux 6.0 (64-bit)");
        addOption(document.drop_list.OS,"Solaris 10", "Solaris 10");
        addOption(document.drop_list.OS,"Windows 2008 (64-bit) Standard", "Windows 2008 (64-bit) Standard");
        addOption(document.drop_list.OS,"Windows 2008 (64-bit) Enterprise", "Windows 2008 (64-bit)   Enterprise");
        addOption(document.drop_list.OS,"Windows 2008 R2 (64-bit) Standard", "Windows 2008 R2 (64-bit)  Standard");
        addOption(document.drop_list.OS,"Windows 2008 R2 (64-bit) Enterprise", "Windows 2008 R2 (64-bit) Enterprise");
        addOption(document.drop_list.OS,"Special", "Special");
    }

    // remaining code of this function

}

The adjustment made was to relocate

removeAllOptions(document.drop_list.OS);
inside selectOS.

Tip: Consider using a DOM library like jQuery. Using .value to access the selected value of the select box may lead to issues on certain versions of IE. Various browsers also present other inconsistencies.

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

JavaScript EasyBitConverter

Looking to create a basic C# BitConverter equivalent in JavaScript, I've developed a simple BitConverter implementation. class MyBitConverter { constructor() {} GetBytes(int) { var b = new Buffer(8); b[0] = int; b ...

Utilizing optional chaining with function parameters

When dealing with a function f: (X => Y) | undefined that may be undefined, and x: X is defined, we can utilize the optional chaining operator ?. to apply f to x: f?.(x) // This is fine even if `f` is undefined However, if f: X => Y is defi ...

The browser is unable to access localhost:3000

Backend: Utilizing an Express server, created with the npx create-express-api command Frontend: Using Next.js, set up with npx create-react-app in the frontend directory Having executed these commands in the root folder, I attempted to run npm start xxx ...

What is the best way to embed an HTML tag along with its attributes as a string within an element?

https://i.sstatic.net/EZSOX.png Is there a way to incorporate this specific HTML tag with its distinct colors into an element within a JSX environment? I attempted the following approach: const htmlTag = '<ifx-icon icon="calendar-16"> ...

Is there a way to pass an object as a parameter when calling a function in JavaScript?

Is it possible to pass an object as a parameter to a function that is a value of another object? I know how to pass a string easily and even a variable as a string. But passing an object seems to be tricky. Let's consider the following 2 objects: var ...

Dispatching a personalized jQuery validation form

I have been working on a simple custom validation script. Despite it meeting my needs, I am struggling to figure out how to properly submit the form after validation. Initially, I thought using 'return true' would do the trick, but unfortunately, ...

Updating AngularJS templateURL to display a 404 page URL when data fails to load

Although this example may not function as intended, it serves to illustrate my goal: Within the factory "myapp.factory('gameService', function($http, $location) {" I am retrieving data from a JSON feed by using "return $http.jsonp('api/game ...

Is there a way to verify if a specific combination of keys has been pressed using JavaScript?

Currently, I am creating a software application that requires the integration of custom hotkeys. These hotkeys need to be chosen by the user and stored for future use. For instance, if the user selects CTRL + M, how can I save this combination and trigge ...

I've been working on a script in JavaScript to retrieve lectures for a specific day, but I'm having trouble connecting my jQuery code to it

Exploring a JavaScript function that retrieves today's lectures for a specific section of a class using jQuery. The challenge lies in implementing this array of classes on an HTML file. //function to get today var today = new Date(); var dd = today ...

I am facing an issue with the Options functionality in Materialize, and the remove method does not seem to work when I am using the

Having a little trouble appending options in a materialize select for my project. Can someone take a look at my code snippet below and provide some guidance on what changes I should make? Thanks! $(document).ready(function() { $(".condition").click(fu ...

Exploring Firefox webpage data with JavaScript or browser extensions

Have you ever wondered if it's possible to retrieve the "Modified" information seen in Firefox when selecting "View page Info" by just using a JavaScript extension? ...

Validation of decimal numbers in JavaScript without the presence of any other characters

Looking to create a JavaScript regex to validate an 8-digit number that may include decimals. The current regex /^\d+$/ allows for any other characters such as ( , * $ etc. How can I modify this to only accept numbers and periods? For example, the nu ...

The PHP script is not receiving the post parameters sent in the ajax request

Help Needed jQuery.ajax({ url: 'PHPdocs/appsearch.php', data: {term:'blub'}, type: "POST", async: true, data: "text", succes ...

Obtaining the input value within a list

Trying to extract the updated value of an input field within an HTML list is proving to be a challenge. The goal is to retrieve the newly entered value (for example, abcd) rather than the default value set when the page loads. Efforts have been made utili ...

Express.js using GET request to retrieve all data entries from the database

I am facing a challenge in retrieving specific user data using the GET method on Express.js through a Form. Instead of returning only one user's information, it is currently returning all values when the form is used. Here is the code from index.html ...

Struggling to make the AJAX script function properly

I have a table containing a list of transactions and I am attempting to update the table contents at specific intervals. The web page is hosted on a Linux Red Hat server, and currently, only the AJAX functionality is not functioning as expected. <!do ...

What are the steps to retrieve information from your personal server using Astro?

I have successfully set up a NodeJS server using Express and Astro for the frontend, with SSR configured through the Astro adapter for NodeJS. My current challenge is fetching data from the backend, and I am unsure of the correct approach to do so. Below ...

I am encountering a problem with validating my form using JavaScript

I've been working on a project where I'm developing a website using JavaScript, HTML, and CSS to search for movies and purchase tickets. While the basic functionalities are working fine, I'm encountering some challenges with form validation. ...

JQuery Chosen extension - Go back to "Choose an option"

This is a select element with the Chosen plugin applied to it: <label class="radio-inline"><input type="radio" name="reset" value="reset">Reset</label> <select id="listclient"> <option value=""></option> <option val ...

How can I restrict Threejs Perspective Camera from going below a Y value of zero?

Is there a way to avoid setting a negative position.y for a THREE.PerspectiveCamera? I have implemented a customized TrackballControl that limits camera rotation on the z-axis, but I still want to ensure that my camera remains elevated above the "ground" ...