Drop down list code

If i run this on my page w/the populate function in the head I have no errors in my console, but it doesn’t work. the second drop down doesn’t populate.

I run in from it’s separate, linked .js I am told populate is not a function. I put the code in codepen. Could i please get some advice as to why this code is not working?Thx

1 Like

This is because the function is wrapped in the $(function() {}), and functions or variables defined in there aren’t global.

If i run this on my page w/the populate function in the head I have no
errors in my console, but it doesn’t work. the second drop down doesn’t
populate.

The problem is that you’re expecting DOM properties on s1 and s2 but those are jQuery wrapped elements with different methods. If you’re wanting to get the DOM nodes themselves you get them from the array. Then s1.value will be as you expect.

var s1=$(s1)[0];
var s2=$(s2)[0];

The easiest way to debug is to console.log the variables at different points and see if they are as you expect.

1 Like

All right, thank you @markbrown4 .
made some changes, but now working on making it global. co workers suggested on();

$("#slct1").on('change',function populate(s1,s2){

		var s1=$('#slct1').val();
		var s2=$('#slct2');		
		s2.innerHTML = "";
		console.log("we here yet?");
			if(s1 == "veggies"){
				var optionArray = ["type|type","carrots|Carrots","broccoli|Broccoli","onions|Onions"];
			}else if(s1 == "fruit"){
				var optionArray = ["type|type","oranges|oranges","cherries|cherries","pears|pears"];
			}else if(s1 == "candy"){
				var optionArray = ["type|type","licorice|licorice","chocolate|chocolate","mints|mints"];
			}
			

			
			for(var indx in optionArray){
				var pair = optionArray[indx].split("|");
				var newOption = $('<option></option>');
				newOption.val(pair[0]);
				newOption.text(pair[0]);
				s2.append(newOption);
			}
	});

And am trying to figure out now to make this one work & change to a for in to a foreach.

1 Like

This should do it:

optionArray.forEach( function( option ) {
  var pair = option.split("|");
  var newOption = $('<option></option>');
  newOption.val(pair[0]);
  newOption.text(pair[0]);
  s2.append(newOption);
} );
2 Likes

Thank you will go & try it out.

That’s the long way to do it - why not use the object JavaScript provides for creating options.

optionArray.forEach( function( option ) {
  var pair = option.split("|");
 s2.options[s2.options.length] = new Option(pair[1],pair[0]);
}
1 Like

was trying to change it all to jquery. Turns out it was more of a challenge than I thought.
Guess deep down I am an optimist.

Thank you worked great.

1 Like

code is generated by JQuery…

the following is independent;

/* JavaScript */

// object literal holding data for option elements
var Select_List_Data = {
    
    'choices': { // name of associated select list
        
        // names match option values in controlling select list
        js: {
            text: ['Scrolling Divs', 'Tooltips', 'Rotate Images', 'Scrollers', 'Banner Rotator'],
            value: ['scroll', 'tooltips', 'rotate', 'scrollers', 'banner']
        },
        php: {
            text: ['Random Image', 'Form Class', 'Table Class', 'Order Form'],
            value: ['random', 'form', 'table', 'order']
        },
        tuts: {
            // example without values
            text: ['Iframes', 'PHP to JS', 'Object Literals', 'Initializing JS']
        }
    
    }    
};

// removes all option elements in select list 
// removeGrp (optional) boolean to remove optgroups
function removeAllOptions(sel, removeGrp) {
    var len, groups, par;
    if (removeGrp) {
        groups = sel.getElementsByTagName('optgroup');
        len = groups.length;
        for (var i=len; i; i--) {
            sel.removeChild( groups[i-1] );
        }
    }
    
    len = sel.options.length;
    for (var i=len; i; i--) {
        par = sel.options[i-1].parentNode;
        par.removeChild( sel.options[i-1] );
    }
}

function appendDataToSelect(sel, obj) {
    var f = document.createDocumentFragment();
    var labels = [], group, opts;
    
    function addOptions(obj) {
        var f = document.createDocumentFragment();
        var o;
        
        for (var i=0, len=obj.text.length; i<len; i++) {
            o = document.createElement('option');
            o.appendChild( document.createTextNode( obj.text[i] ) );
            
            if ( obj.value ) {
                o.value = obj.value[i];
            }
            
            f.appendChild(o);
        }
        return f;
    }
    
    if ( obj.text ) {
        opts = addOptions(obj);
        f.appendChild(opts);
    } else {
        for ( var prop in obj ) {
            if ( obj.hasOwnProperty(prop) ) {
                labels.push(prop);
            }
        }
        
        for (var i=0, len=labels.length; i<len; i++) {
            group = document.createElement('optgroup');
            group.label = labels[i];
            f.appendChild(group);
            opts = addOptions(obj[ labels[i] ] );
            group.appendChild(opts);
        }
    }
    sel.appendChild(f);
}

document.forms['demoForm'].elements['category'].onchange = function(e) {
    // name of associated select list
    var relName = 'choices';
    
    // reference to associated select list 
    var relList = this.form.elements[ relName ];
    
    // get data from object literal based on selection in controlling select list (this.value)
    var obj = Select_List_Data[ relName ][ this.value ];
    
    // remove current option elements
    removeAllOptions(relList, true);
    
    // call function to add optgroup/option elements
    // pass reference to associated select list and data for new options
    appendDataToSelect(relList, obj);
};

(function() { // immediate function to avoid globals
    
    var form = document.forms['demoForm'];
    
    // reference to controlling select list
    var sel = form.elements['category'];
    sel.selectedIndex = 0;
    
    // name of associated select list
    var relName = 'choices';
    // reference to associated select list
    var rel = form.elements[ relName ];
    
    // get data for associated select list passing its name
    // and value of selected in controlling select list
    var data = Select_List_Data[ relName ][ sel.value ];
    
    // add options to associated select list
    appendDataToSelect(rel, data);
    
}());

/* HTML */

<form action="#" method="post" id="demoForm" class="demoForm">
    <fieldset>
        <legend>Demo: Paired Select Lists</legend>
    
        <select name="category">
            <option value="js">JavaScripts</option>
            <option value="php">PHP Scripts</option>
            <option value="tuts">Tutorials</option> 
        </select>
        
        <select name="choices" id="choices">
            <!-- js populates -->
        </select>
    
    </fieldset>
</form>

Textbook.

2 Likes

thx, will go over all of that!,
I had added
if((s1)!=“”){
s2.empty();
}

to reset the selection.
almost there, right now it prevents the new selection from appeding the previous to the dropped down list, but doesn’t’ reset the list if the user doesn’t select any of the three option.

Look very comprehensive.
thx

Okay quick follow up because I think my logic must be faulty or I am just stuck (codepen updated) I had cleared the continuous appending of list items with:

if((s1)!=""){
   s2.empty();
}

so that works, great.
However when i select the very first option w/out a value I’d want to the list from choose b to also return to a default value.
I have tried replaceWith.(); kinda worked but not like i wanted. Tried append, ditto. I tried adding an else if statement.

if(s1 == ""){
   var optionArray = ["pick something|pick something"];
 }else if(s1 == "veggies"){ ... etc...

but this only appends “pick something” to the bottom of the last list selected.

I especially don’t understand that.
Thx

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.