Ask your JavaScript questions! Pay money and get answers fast! (more info)

Filter a drop down menu and then link this one with another menu JavaScript

  • SOLVED

Dear Javscript;

I want to filter one drop down box with a text menu; and then link that with the capital link box. For example: I type "Net"; then automatically Netherlands appears in menu 1 and Amsterdam in menu 2.

Here is my code so far; the linking (of country and capital) works if the filter is not active.. and it works not when the filter is active and I need that filter... please help me!



<script type="text/javascript">
/*==================================================*
$Id: filterlist.js,v 1.3 2003/10/08 17:13:49 pat Exp $
Copyright 2003 Patrick Fitzgerald
http://www.barelyfitz.com/webdesign/articles/filterlist/

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*==================================================*/
function filterlist(selectobj) {
//==================================================
// PARAMETERS
//==================================================

// HTML SELECT object
// For example, set this to document.myform.myselect
this.selectobj = selectobj;

// Flags for regexp matching.
// "i" = ignore case; "" = do not ignore case
// You can use the set_ignore_case() method to set this
this.flags = 'i';

// Which parts of the select list do you want to match?
this.match_text = true;
this.match_value = false;

// You can set the hook variable to a function that
// is called whenever the select list is filtered.
// For example:
// myfilterlist.hook = function() { }

// Flag for debug alerts
// Set to true if you are having problems.
this.show_debug = false;

//==================================================
// METHODS
//==================================================

//--------------------------------------------------
this.init = function() {
// This method initilizes the object.
// This method is called automatically when you create the object.
// You should call this again if you alter the selectobj parameter.

if (!this.selectobj) return this.debug('selectobj not defined');
if (!this.selectobj.options) return this.debug('selectobj.options not defined');
// Make a copy of the select list options array
this.optionscopy = new Array();
if (this.selectobj && this.selectobj.options) {
for (var i=0; i < this.selectobj.options.length; i++) {

// Create a new Option
this.optionscopy[i] = new Option();

// Set the text for the Option
this.optionscopy[i].text = selectobj.options[i].text;

// Set the value for the Option.
// If the value wasn't set in the original select list,
// then use the text.
if (selectobj.options[i].value) {
this.optionscopy[i].value = selectobj.options[i].value;
} else {
this.optionscopy[i].value = selectobj.options[i].text;
}

}
}
}
//--------------------------------------------------
this.reset = function() {
// This method resets the select list to the original state.
// It also unselects all of the options.

this.set('');
}
//--------------------------------------------------
this.set = function(pattern) {
// This method removes all of the options from the select list,
// then adds only the options that match the pattern regexp.
// It also unselects all of the options.

var loop=0, index=0, regexp, e;

if (!this.selectobj) return this.debug('selectobj not defined');
if (!this.selectobj.options) return this.debug('selectobj.options not defined');
// Clear the select list so nothing is displayed
this.selectobj.options.length = 0;

// Set up the regular expression.
// If there is an error in the regexp,
// then return without selecting any items.
try {

// Initialize the regexp
regexp = new RegExp(pattern, this.flags);

} catch(e) {

// There was an error creating the regexp.
// If the user specified a function hook,
// call it now, then return
if (typeof this.hook == 'function') {
this.hook();
}

return;
}
// Loop through the entire select list and
// add the matching items to the select list
for (loop=0; loop < this.optionscopy.length; loop++) {

// This is the option that we're currently testing
var option = this.optionscopy[loop];

// Check if we have a match
if ((this.match_text && regexp.test(option.text)) ||
(this.match_value && regexp.test(option.value))) {

// We have a match, so add this option to the select list
// and increment the index

this.selectobj.options[index++] =
new Option(option.text, option.value, false);

}
}
// If the user specified a function hook,
// call it now
if (typeof this.hook == 'function') {
this.hook();
}
}
//--------------------------------------------------
this.set_ignore_case = function(value) {
// This method sets the regexp flags.
// If value is true, sets the flags to "i".
// If value is false, sets the flags to "".

if (value) {
this.flags = 'i';
} else {
this.flags = '';
}
}

//--------------------------------------------------
this.debug = function(msg) {
if (this.show_debug) {
alert('FilterList: ' + msg);
}
}
//==================================================
// Initialize the object
//==================================================
this.init();
}
</script>

<SCRIPT LANGUAGE="javascript">

function SearchList()
{
var l = document.getElementById('country');
var tb = document.getElementById('TextBox1');

l.options.length=0;

if(tb.value == "")
{
for (var i=0; i < myVals.length; i++)
{
l.options[l.options.length] = new Option(myVals[i]);
}
}
else{

for (var i=0; i <myVals.length; i++)
{
if (myVals[i].toLowerCase().indexOf(tb.value.toLowerCase()) != -1)
{
l.options[l.options.length] = new Option(myVals[i]);
}
else
{
// do nothing
}
}
}
}

function ClearSelection(lb)
{
lb.selectedIndex = -1;
}

function listSel(fld,id) {
var opt = fld.selectedIndex;
if (fld[opt].label != ' ') {
var sel = document.getElementById(id);
for (var i = sel.options.length -1; i > -1; i--) {
if (fld[opt].label == sel[i].value) sel[i].selected = true;
}
}
}
</script>

<script type="text/javascript">
// Script to link city menu to country menu
function listSel(fld,id) {
var opt = fld.selectedIndex;
if (fld[opt].label != ' ') {
var sel = document.getElementById(id);
for (var i = sel.options.length -1; i > -1; i--) {
if (fld[opt].label == sel[i].value) sel[i].selected = true;
}
}
}
</script>



<HEAD>


</HEAD>

<BODY onload=CacheValues();>
<form name="form" action="action.asp" method="POST">
<table width="100%" border="1" cellpadding="10" cellspacing="0" bordercolor="#CCCCCC">
<tr>
<td><p>
<input name="regexp" onKeyUp="myfilter.set(this.value)" value="" size="10" class="style1">
Country:
<select name="country" onChange="listSel(this,'city')" class="style1">
<option value="NL" label="1" selected>Netherlands</option>
<option value="UK" label="2" selected>England</option>
<option value="SP" label="3">Spain</option>
</select>
<SCRIPT TYPE="text/javascript">
<!--
var myfilter = new filterlist(document.form.country);
//-->
</SCRIPT>
City:
<select name="city" id="city" class="style1" style="arrowButtonWidth: 20;">
<option value="1">Amsterdam</option>
<option value="2">Londen</option>
<option value="3">Madrid</option>
</select>
<br>
</p>
<span class="style1"> </span><span class="style1"> </span>
</td>
</tr>
</table>
</form>


</BODY>

</HTML>

</textarea>



Answers (2)

2012-01-18

Julian Drei├čig answers:

The script you are using makes copies of the option elements but doesn't copy the 'label' attribute you use to identify the matching city option. Also, you will need to explicitly call your 'listSel()' function after the filter has been applied.

I have patched your code and removed some unnecessary parts for this question, have a look:


<HTML>
<HEAD>

<script type="text/javascript">
/*==================================================*
$Id: filterlist.js,v 1.3 2003/10/08 17:13:49 pat Exp $
Copyright 2003 Patrick Fitzgerald
http://www.barelyfitz.com/webdesign/articles/filterlist/

*** Patched to copy 'label' parameter of options. JD ***

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*==================================================*/
function filterlist(selectobj) {
//==================================================
// PARAMETERS
//==================================================

// HTML SELECT object
// For example, set this to document.myform.myselect
this.selectobj = selectobj;

// Flags for regexp matching.
// "i" = ignore case; "" = do not ignore case
// You can use the set_ignore_case() method to set this
this.flags = 'i';

// Which parts of the select list do you want to match?
this.match_text = true;
this.match_value = false;

// You can set the hook variable to a function that
// is called whenever the select list is filtered.
// For example:
// myfilterlist.hook = function() { }

// Flag for debug alerts
// Set to true if you are having problems.
this.show_debug = false;

//==================================================
// METHODS
//==================================================

//--------------------------------------------------
this.init = function() {
// This method initilizes the object.
// This method is called automatically when you create the object.
// You should call this again if you alter the selectobj parameter.

if (!this.selectobj) return this.debug('selectobj not defined');
if (!this.selectobj.options) return this.debug('selectobj.options not defined');
// Make a copy of the select list options array
this.optionscopy = new Array();
if (this.selectobj && this.selectobj.options) {
for (var i=0; i < this.selectobj.options.length; i++) {

// Create a new Option
this.optionscopy[i] = new Option();

// Set the text for the Option
this.optionscopy[i].text = selectobj.options[i].text;

// Set the value for the Option.
// If the value wasn't set in the original select list,
// then use the text.
if (selectobj.options[i].value) {
this.optionscopy[i].value = selectobj.options[i].value;
} else {
this.optionscopy[i].value = selectobj.options[i].text;
}

// Copy 'label' attribute
if (selectobj.options[i].getAttribute('label')) {
this.optionscopy[i].setAttribute('label', selectobj.options[i].getAttribute('label'));
}
}
}
}
//--------------------------------------------------
this.reset = function() {
// This method resets the select list to the original state.
// It also unselects all of the options.

this.set('');
}
//--------------------------------------------------
this.set = function(pattern) {
// This method removes all of the options from the select list,
// then adds only the options that match the pattern regexp.
// It also unselects all of the options.

var loop=0, index=0, regexp, e;

if (!this.selectobj) return this.debug('selectobj not defined');
if (!this.selectobj.options) return this.debug('selectobj.options not defined');
// Clear the select list so nothing is displayed
this.selectobj.options.length = 0;

// Set up the regular expression.
// If there is an error in the regexp,
// then return without selecting any items.
try {

// Initialize the regexp
regexp = new RegExp(pattern, this.flags);

} catch(e) {

// There was an error creating the regexp.
// If the user specified a function hook,
// call it now, then return
if (typeof this.hook == 'function') {
this.hook();
}

return;
}
// Loop through the entire select list and
// add the matching items to the select list
for (loop=0; loop < this.optionscopy.length; loop++) {

// This is the option that we're currently testing
var option = this.optionscopy[loop];

// Check if we have a match
if ((this.match_text && regexp.test(option.text)) ||
(this.match_value && regexp.test(option.value))) {

// We have a match, so add this option to the select list
// and increment the index
var newOption = new Option(option.text, option.value, false);
if (option.getAttribute('label')) {
newOption.setAttribute('label', option.getAttribute('label'));
}
this.selectobj.options[index++] = newOption;

}
}
// If the user specified a function hook,
// call it now
if (typeof this.hook == 'function') {
this.hook();
}
}
//--------------------------------------------------
this.set_ignore_case = function(value) {
// This method sets the regexp flags.
// If value is true, sets the flags to "i".
// If value is false, sets the flags to "".

if (value) {
this.flags = 'i';
} else {
this.flags = '';
}
}

//--------------------------------------------------
this.debug = function(msg) {
if (this.show_debug) {
alert('FilterList: ' + msg);
}
}
//==================================================
// Initialize the object
//==================================================
this.init();
}

</script>

<script type="text/javascript">

// Script to link city menu to country menu
function listSel(fld, id) {
var opt = fld.selectedIndex;
if (opt >= 0) {
var targetValue = fld[opt].getAttribute('label');
if (targetValue != null) {
var sel = document.getElementById(id);
for (var i = sel.options.length-1; i >= 0; i--) {
if (targetValue == sel[i].value) sel[i].selected = true;
}
}
}
}

</script>
</HEAD>

<BODY>
<form name="form" action="action.asp" method="POST">
<table width="100%" border="1" cellpadding="10" cellspacing="0" bordercolor="#CCCCCC">
<tr>
<td><p>
<input name="regexp" onKeyUp="myfilter.set(this.value); listSel(document.form.country, 'city')" value="" size="10" class="style1" />
Country:
<select name="country" onChange="listSel(this,'city')" class="style1">
<option value="NL" label="1" selected>Netherlands</option>
<option value="UK" label="2">England</option>
<option value="SP" label="3">Spain</option>
</select>
<SCRIPT TYPE="text/javascript">
<!--
var myfilter = new filterlist(document.form.country);
//-->
</SCRIPT>
City:
<select name="city" id="city" class="style1" style="arrowButtonWidth: 20;">
<option value="1" selected>Amsterdam</option>
<option value="2">Londen</option>
<option value="3">Madrid</option>
</select>
<br>
</p>
</td>
</tr>
</table>
</form>


</BODY>

</HTML>


However, this is a rather dirty solution and I personally would use a cleaner approach. Contact me if you are interested in further discussion.


Jeroen Hollander comments:

We have a winner!! :) Thanx!

Yes; I would like to know the clean approach please; can you send it to me? Have a good evening!

Regards: Jeroen

2012-01-18

Arnav Joy answers:

can you please explain more your question , Sorry I did not get you.


Jeroen Hollander comments:

Yes; sure; this code generates three boxes;
1. input box to type in a filter (for the countries drop down menu see point 2: so when I type "Ne" here only Netherlands will appear in the next dropdown menu:)
2. one drop down menu with 3 countries: Netherlands,England,Spain
3. one drop down menu with 3 main cities/capitals: Amsterdam,Londen,Madrid

The filter works great.
The link between 2 and 3 works also; but only when there is no filter active.

<strong>So: what I want is this:</strong> I type "Net" in the first text field and automatically Netherlands and Amsterdam appear in 2 and 3.

Sorry I can't host this code this time; perhaps when you copy/paste it; you can see/try it?