Click to See Complete Forum and Search --> : Javascript: Matching Name questions


vincent85
July 23rd, 2007, 03:02 AM
I am trying to do this :
Typing a name into the suburb entry field will scroll the suburb select
field to a matching suburb name.

How it work:
1. Pick a state ("ACT" OR "NT")
2. Enter Suburb name into text field
3. See if the Select field scroll to a matching name.

Problem:
If you pick state as "ACT" and enter " WANNIASSA" into select field. The script work.
(DO NOT RELOAD THE PAGE)After that pick state "NT", enter any word into text field (eg, "darwin") . You will see the script doesn't work.

2.(Reload the page) Now pick state as "NT" then typing "Darwin" into text field. Now the script wor


Here is the script:
var index = new Object;
index.isthere = false;

function wordComplete (suburb1,suburb2)
{
var text = document.getElementById(suburb1);
var pick = document.getElementById(suburb2);
if (!index.isthere) listIndex(suburb2);
var suburb = text.value.match(/,*([^,]+)$/);
if (suburb)
{
var name = suburb[1].toUpperCase().replace(/^\s*/, '').replace(/\s*$/, '');
for (var i = index[name.charAt(0)]; i < pick.options.length; i++)
{
if (pick.options[i].text.toUpperCase().indexOf(name) == 0)
{
pick.selectedIndex = i;
break;
}
else
{
pick.selectedIndex = 0;
}
}
}
}

function listIndex (suburb)
{
var pick=0;
pick = document.getElementById(suburb);
for (var i = pick.options.length; i--;)
{
index[pick.options[i].text.toUpperCase().charAt(0)] = i;
}
index.isthere = true;
}

function subfieldInsert (suburb1,suburb2)
{
var text = document.getElementById(suburb2);
var select = document.getElementById(suburb1);

text.focus();
var suburb = select.options[select.selectedIndex];

if (select.selectedIndex == 0)
{
text.value = '';
return true;
}

var textSuburbs = text.value.split(/\s*,\s*/);
if (!textSuburbs) return false;
var pattern = new RegExp('\s*' + suburb.text + '\s*$');
for (var i = 0; i < textSuburbs.length; i++)
{
if (pattern.exec(textSuburbs[i])) return false;
}
var newvalue = text.value.replace(/(^|,)([^,]*)$/, "$1 " + suburb.text + ', ');
text.value = newvalue;
return false;
}


I hope you understand what i meant and help me iron this bugs.

Thank in advantage

ps. The attachment have all the files. Open it and run and you will understand.

PeejAvery
July 23rd, 2007, 07:44 AM
Well, to start out, use onkeyup instead of onkeydown. That will make the event fire when it is supposed to and not one character late every time.

Also, the problem occurs when you grab a different DOM element. Why don't you just create two different arrays and then auto populate dynamically the multi-display select when you change the state?

I am on vacation and don't have time to go into great detail right now. I will look into this more when I get more free online time.

vincent85
July 23rd, 2007, 08:35 AM
Thank you very much for the tip about use onkeyup.

About create two different arrays and then auto populate dynamically the multi-display select, i am not really got it. Sorry for being slow.
Can you go into more detail please? how about example codes?

Thank in advantage.

PeejAvery
July 23rd, 2007, 08:04 PM
You would create two arrays and then depending on the value for the drop-down list, you would fill it with the appropriate array. Here is an example.

<html>
<body>

<script type="text/javascript">
function populate(theNum){
var arr_act = [
'ACT 1',
'ACT 2',
'ACT 3',
'ACT 4',
'ACT 5',
'ACT 6',
'ACT 7',
'ACT 8',
'ACT 9',
'ACT 10',
'ACT 11',
'ACT 12',
];

var arr_nt = [
'NT 1',
'NT 2',
'NT 3',
'NT 4',
'NT 5',
'NT 6',
'NT 7',
'NT 8',
'NT 9',
'NT 10',
'NT 11',
'NT 12',
];

var temp_array = [];
if(theNum == 1){temp_array = arr_act;}
if(theNum == 2){temp_array = arr_nt;}

var theCities = document.getElementById('theCities');
theCities.length = 0;
for(i = 0; i < temp_array.length; i++){
theCities.options[i] = new Option(temp_array[i], temp_array[i]);
}
}
</script>

<select name="State" onchange="if(this.value != '-blank-'){populate(this.value);}">
<option value="-blank-">Choose</option>
<option value="1">ACT</option>
<option value="2">NT</option>
</select>

<select id="theCities" size="5"></select>

</body>
</html>

vincent85
July 23rd, 2007, 10:09 PM
Ok, I got it, thank.

Anyway, here is my fix for the one above (with out using dynamic populate array)

////////////////////////////////////////////////////////////////////////////////////////////
var index = new Object;
var ntindex = new Object;
index.isthere = false;
ntindex.isthere = false;

function wordComplete (suburb1,suburb2)
{
var text = document.getElementById(suburb1);
var pick = document.getElementById(suburb2);
if (!index.isthere || !ntindex.isthere) listIndex(suburb2);
var suburb = text.value.match(/,*([^,]+)$/);
if (suburb)
{
var name = suburb[1].toUpperCase().replace(/^\s*/, '').replace(/\s*$/, '');
var i;
if(suburb2=='nt')
{
i = ntindex[name.charAt(0)];
}
else
{
i = index[name.charAt(0)];
}
for (; i < pick.options.length; i++)
{
if (pick.options[i].text.toUpperCase().indexOf(name) == 0)
{
pick.selectedIndex = i;
break;
}
else
{
pick.selectedIndex = 0;
}
}
}
}

function listIndex (suburb)
{
var pick=0;
pick = document.getElementById(suburb);
for (var i = pick.options.length; i--;)
{
if(suburb=='nt')
{
ntindex[pick.options[i].text.toUpperCase().charAt(0)] = i;
ntindex.isthere = true;
}
else
{
index[pick.options[i].text.toUpperCase().charAt(0)] = i;
index.isthere = true;
}
}

}




I know it isnot very good way to fix but it work properly now.... :o

PeejAvery
July 24th, 2007, 02:18 PM
I know it isnot very good way to fix but it work properly now.... :o
I'm glad to hear it's working. Also, "not very good" fixes are a part of learning. You will iron those out with more experience.