Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Create comma-delimited list from two or more combo boxes 1

Status
Not open for further replies.

tmcneil

Technical User
Nov 17, 2000
294
US
All,

I've been working on some code to try and handle creating a comma delimited list of values from combo boxes. If there are two combox boxes, the user can either choose one of two values or enter in their own value. I would like to store this in a string. When the user selects or enters another value in the 2nd combo box, then add that to the list, ie., "brown,glasses". I've got code to handle one combo box, but I'm struggling with the multiple combo boxes since it is a lot more complicated. The last option is where the user can enter in text. The following is an example of the combo box on my asp page.:
Code:
<tr class="item" height="28">
    <td width="350" nowrap>Child's Physical Description</td>
    <td width="425" nowrap>
        <select id="text4" name="text4" size="1" style="width: 300px;"
         onFocus="return combo_focus(this);"
	     onChange="return combo_change(this); OnSelText(this);"
	     onKeydown="return combo_keydown(this, event); OnSelText(this);"
	     onKeypress="return combo_keypress(this, event);"
	     onKeyup="return combo_keyup(this, event);">
            <option value="0" >Enter Child's Physical Description
            <option value="66000" selected>Unknown
            <option value="66001">
        </select>
        </td>
    </tr>

    <tr class="item" height="28">
        <td width="350" nowrap>Suspect's Physical Description</td>
        <td width="425" nowrap>
            <select id="text5" name="text5" size="1" style="width: 300px;"
             onFocus="return combo_focus(this);"
	         onChange="return combo_change(this); OnSelText(this);"
	         onKeydown="return combo_keydown(this, event); OnSelText(this);"
	         onKeypress="return combo_keypress(this, event);"
	         onKeyup="return combo_keyup(this, event);">
                <option value="0" >Enter Suspect's Physical Description
                <option value="67000" selected>Unknown              
                <option value="67001">
            </select>
        </td>
    </tr>

The combo box gets its real functionality from the onFocus, onChange and onKeypress events. onFocus calls combo_focus(), onChange calls combo_change() and onKeypress calls combo_keypress(). The else part of the code in combo_focus gets rather lengthy and that is the part that I need help with.:
Code:
var combo_word;	 //The user-editable word
var combo_keypress_called;	// A fix for Konqueror/Safari
var newSource;
var curSource;
var oldSource;

// When select is focused, set the editable word.
function combo_focus(element)
{
    // original function combo_focus(element)
    /*combo_word = "";
	if(element.selectedIndex >= 0)
		combo_word = element.options[element.selectedIndex].text;
	return true;*/
	//
	
    combo_word = "";
    
    var aatakes = document.forms[0].aatakes.value;  // aatakes is the number of amber alert combo boxes
    var delim = ",";
    var textList = document.forms[0].cbTextList.value;  //comma-delimited list of text values
    var pos = document.forms[0].pos.value;
    
    if (aatakes == 1)  // one combo box
    {
        if(element.selectedIndex >= 0)
	    {
	        combo_word = element.options[element.selectedIndex].text;
	        if (textList.length <= 0)  //more accurate than, textList = ""
            {
                // Search for "Enter.." in combo_word
                if(combo_word.search("Enter") >= 0)
                {
                    document.forms[0].action.value = "";
                    pos = combo_word.search("Enter");
                    textList = "";
                }
                // Search for "Unknown" in combo_word
                else if(combo_word.search("Unknown") >= 0)
                {
                    document.forms[0].action.value = "";
                    pos = combo_word.search("Unknown");
                    textList = "";
                }
                else if(pos == -1)
                {
                    textList = combo_word;
                }
            }
            else  //textList has a value
            {
                // Search for "Enter.." in combo_word
                if (combo_word.search("Enter") >= 0)
                {
                    document.forms[0].action.value = "";
                    pos = textList.search("Enter");
                    textList = "";
                }
                // Search for "Unknown" in combo_word
                if (combo_word.search("Unknown") >= 0)
                {
                    document.forms[0].action.value = "";
                    pos = textList.search("Unknown");
                    textList = "";
                }
                else if(pos == -1)
                {
                    textList = combo_word;
                }
            }
	    }
    }
    else  // multiple combo boxes
    {
        //alert("multiple combo boxes");
        if(element.selectedIndex >= 0)
        {
            newSource = element.name;
            curSource = newSource;
            //alert("curSource:" + curSource);
            combo_word = element.options[element.selectedIndex].text;
            
            if (textList.length <= 0)
            {
                //alert("if (eval(buffer) <= 0)");
                // Search for "Enter.." in combo_word
                if(combo_word.search("Enter") >= 0)
                {
                    //alert("if(combo_word.search(Enter) >= 0)");
                    document.forms[0].action.value = "";
                    pos = combo_word.search("Enter");
                    textList = "";
                }
                // Search for "Unknown" in combo_word
                else if(combo_word.search("Unknown") >= 0)
                {
                    //alert("else if(combo_word.search(Unknown) >= 0)");
                    document.forms[0].action.value = "";
                    pos = combo_word.search("Unknown");
                    textList = "";
                }
                else if(pos == -1)
                {
                    //alert("else if(pos == -1)");
                    textList = combo_word;
                }
                oldSource = curSource;
                //alert("oldSource:" + oldSource);
            }
            else  //textList has a value
            {
                //alert("curSource:" + curSource);
                if (curSource != oldSource)  // if current element is different then old element
                {
                    // Search for "Enter.." in combo_word
                    if (combo_word.search("Enter") >= 0)
                    {
                        //alert("if(combo_word.search(Enter) >= 0)");
                        document.forms[0].action.value = "";
                        pos = buffer.search("Enter");
                        textList = textList;
                    }
                    // Search for "Unknown" in combo_word
                    if (combo_word.search("Unknown") >= 0)
                    {
                        //alert("if(combo_word.search(Unknown) >= 0)");
                        document.forms[0].action.value = "";
                        pos = buffer.search("Unknown");
                        textList = textList;
                    }
                    else if(pos == -1)
                    {
                        //alert("else if(pos == -1)");
                        textList += delim + combo_word;
                    }
                }
                else  // curSource is the same element as oldSource
                {
                    // Search for "Enter.." in combo_word
                    if (combo_word.search("Enter") >= 0)
                    {
                        //alert("if(combo_word.search(Enter) >= 0)");
                        document.forms[0].action.value = "";
                        pos = textList.search("Enter");
                        textList = "";
                    }
                    // Search for "Unknown" in combo_word
                    if (combo_word.search("Unknown") >= 0)
                    {
                        //alert("if(combo_word.search(Unknown) >= 0)");
                        document.forms[0].action.value = "";
                        pos = textList.search("Unknown");
                        textList = "";
                    }
                    else if(pos == -1)
                    {
                        //alert("else if(pos == -1)");
                        textList = combo_word;
                    }
                }
            }
        }
    }
    alert("textList: " + textList);
    document.forms[0].cbTextList.value = textList;
    return true;
}

// Same function as focus, but here to make the HTML less confusing.
function combo_change(element)
{
    OnSelText(element);    
	return combo_focus(element);
}

// Return false to try and block built-in keydown functions.
function combo_keydown(element, event)
{
	var c=0;
	if(event.keyCode) c = event.keyCode;
	else if(event.charCode) c = event.charCode;
	else if (event.which) c = event.which;
	// Don't block the tab key
	if(c == 9) return true;

	// We have not called keypress yet.
	combo_keypress_called = false;
	return false;
}

// The real work.  Update the editable word and the select box.
function combo_keypress(element, event)
{
    // space bar works in IE, not in FF
    
	// Do not call this again on keyup.
	combo_keypress_called = true;

	// Get the current key pressed.
	var c=0;
	if(event.keyCode) c = event.keyCode;
	else if(event.charCode) c = event.charCode;
	else if (event.which) c = event.which;
	// Don't block the tab key
	if(c == 9) return true;

	// Konqueror sends all alpha-characters in as upper case.
	// This converts them to lower case if shift is not pressed.
	if(!event.shiftKey)
	{
		if(c>=65 && c<=90) c+= 32;
		else if(c == 190) c = 46; // period
		else if(c == 189) c = 45; // minus sign
		else if(c == 187) c = 61; // equal sign
		else if(c == 192) c = 96; // backtick
		else if(c == 222) c = 39; // single quote
		else if(c == 186) c = 59; // ;
	}
	// IE doesn't send the numbers shifted.
	else
	{
		if(c == 48) c = 41;
		else if(c == 49) c = 33;
		else if(c == 50) c = 64;
		else if(c == 51) c = 35;
		else if(c == 52) c = 36;
		else if(c == 53) c = 37;
		else if(c == 54) c = 94;
		else if(c == 55) c = 38;
		else if(c == 56) c = 42;
		else if(c == 57) c = 40;
		else if(c == 187) c = 43; // plus sign
		else if(c == 189) c = 95; // underscore
		else if(c == 192) c = 126; // ~
		else if(c == 222) c = 34; // quotes
		else if(c == 186) c = 58; // :
	}

	// This is used to get char codes that don't show up properly.
	//if(c > 126) alert(c);

	if(c>=32 && c<=126)	// Printable characters
	{
		combo_word += String.fromCharCode(c);
		//element.options[2].value = combo_word;  // take_id will not be selected
		                                          // and default to 0
		element.options[2].text = combo_word;
		var combo_wlc = combo_word.toLowerCase();
		var combo_select = 2;
		for(i=1; i<element.options.length; i++)
		{
			combo_sel = element.options[i].text.toLowerCase();
			if(combo_wlc.length <= combo_sel.length)
			{
				combo_sel = combo_sel.substring(0, combo_wlc.length);
				if(combo_wlc == combo_sel)
					combo_select = i;
			}
		}
		element.selectedIndex = combo_select;
	}
	else if((c == 8 || c == 4099) && combo_word.length>0)	// Backspace
	{
		combo_word = combo_word.substring(0, combo_word.length-1);
		//element.options[2].value = combo_word;  // take_id will not be selected
		                                          // and default to 0
		element.options[2].text = combo_word;
		element.selectedIndex = 2;
	}
	
	//alert("char code: " + c);
    OnSelText(element);
	// Make sure combo_word is set after every keypress event
	combo_focus(element);
	return false;
}

So, I apologize for the lengthy post, but I wanted to make sure that I included everything. So, my goal is to create a comma-delimited list of values, ie. "black hair, wire-rimmed glasses" to store in a variable on the page. So any help would be greatly appreciated.

Thanks,
Todd
 
I'm not sure about what all of your code does but here is a snippet of code that should do what you want:

Code:
<script>
function buildlist() {
	var arList = [];
	var frm = document.forms[0];
	for (var i=0; i<frm.elements.length; i++)
		if (frm.elements[i].tagName == 'SELECT') {
			var txt = frm.elements[i].options[frm.elements[i].selectedIndex].text;
			if (!txt.match(/Enter|Unknown/g))
				arList[arList.length] = txt;
		}
	alert(arList.join(','));
}	
</script>

<form>
<select onchange='buildlist()'>
<option value='a'>a
<option value='b'>b
<option value='c'>c
</select>

<select onchange='buildlist()'>
<option value='d'>d
<option value='e'>e
<option value='f'>f
</select>
</form>

Chaz
 
Chaz,

Well the code that I posted has been changed quite a bit, especially the javascript. I understand what your getting at, but let me throw one more twist into the works. For example, say I have 5 select boxes named:
Code:
text1
text2
text3
text4
text5
Only two of these select boxes are what i call combo boxes, or select boxes with benefits. :) So, if you just loop through all of the elements and build the list, wouldn't I need to differentiate between both types of elements? how would I do that when they use the same naming convention and the same element type.

Thanks,
Todd
 
In my previous query I check the following:

Code:
if (frm.elements[i].tagName == 'SELECT') {

That means that only the select boxes are used - all other fields are ignored.

FYI: I also ignore SELECTs where the value contains Enter or Unknown, which I think your script was trying to do as well.

Chaz
 
Chaz,

yes, I understand. Like I was trying to say, if all of my elements are "Select" boxes, then there is no way for me to only read the values from the "select" elements that I need. It will read them all. Unless, I hard code them..... Does this make sense?

Todd
 
Sorry about the delay - weekend and whatever!

There are several things you could do to get around this: you could have an array of valid select boxes and only use the ones that are in the array, or alternatively you could set a property in the select tag itself and check that.

for example:

Code:
  <select include=true><option>... </select>

You can then use

Code:
  if (frm.elements[i].getAttribute('include') == true) {
    .. do stuff
  }

You can use whatever tag you want (and as many as you want - it's pretty useful for maintaining state)

This is how we do things here - I'm not sure if this is specific to IE (this is an IE only place) and I'm pretty sure it isn't in the W3C standard but it's an option.

Chaz
 
scorpio66,

That makes perfect sense and at first glance, it should work. I'll try it out.

Thanks,
Todd
 
scorpio66,

I built your buildlist() function into my code in the combo_focus() function. Works like a charm and cut down my code more than half.

Code:
// When select is focused, set the editable word.
function combo_focus(element)
{	
    combo_word = "";
    
    var textList = "";  //comma-delimited list of text values
    
    if(element.selectedIndex >= 0)
	{
	    combo_word = element.options[element.selectedIndex].text;
	    // create arList array
        var arList = [];
        var frm = document.forms[0];
        for (var i=0; i<frm.elements.length; i++)
            if (frm.elements[i].tagName == 'SELECT')  //look for all select elements
                // look for all select elements with an attribute of "include" set to "true"
                if (frm.elements[i].getAttribute('include') == "true")
                {
                    var txt = frm.elements[i].options[frm.elements[i].selectedIndex].text;
                    // do not include "Enter.." or "Unknown" when building arList
                    if (!txt.match(/Enter|Unknown/g))
                        arList[arList.length] = txt;
                    else
                        if (document.forms[0].aatakes.value != 1)
                            arList[arList.length] = "";
                }
                document.forms[0].cbValues.value = arList.join(',');
    }
    return true;
}

Thanks again,
Todd
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top