Reputation: 1964
I am going to implement a search form as in here. As you can see the first dropdown box is used to select a country. Once a country is selected the list of its cities will be populated into second dropdown list. Please note the second dropdown list is disabled first and will be enabled when it is populated by data.
To implement this, onChange function is used to send the selected value of the first dropdown list to the server and retrieve the results but I do not know how to populate the second dropdown list.
<s:form action="/Cars/find" method="GET">
<s:select id="country"
name="country"
list="@com.example.listOfCountries"
onChange="getCities(this.value)"
/>
<s:select id="city"
name="city"
headerKey="-1" headerValue="Select City"
disabled = "true"
list="{'empty'}";
/>
<s:submit value="Search"></s:submit>
</s:form>
JavaScript function
function getCities(val) {
if (window.XMLHttpRequest)
{
xmlhttp = new XMLHttpRequest();
}
else
{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
document.getElementById("carCity").disabled = "false";
document.getElementById("carCity").list = xmlhttp.responseText;
}
}
xmlhttp.open("get", "../Search/findCities?country=" + val, false);
xmlhttp.send();
}
Java
my Java function add the list of cities to the following field
private List<String> cities = new ArrayList();
And show them into result page using
${cities}
Output of the xmlhttp.responseText
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
[{, 'Aberdeen', 'Aberystwyth', 'Aldershot', 'Amesbury', 'Anglesey', 'Ashford', 'Aylesbury', 'Ayr', 'Banbury', 'Barnstaple', 'Barrow In Furness', 'Basildon', 'Basingstoke', 'Bath', 'Bedford', 'Belfast', 'Birkenhead', 'Birmingham', 'Blackpool', 'Bolton', 'Bournemouth', 'Bracknell', 'Bradford', 'Brighton', 'Bristol', 'Bromley', 'Burnley', 'Burton Upon Trent', 'Bury St. Edmunds', 'Caernarfon', 'Cambridge', 'Cardiff', 'Carlisle', 'Carmarthen', 'Chatham', 'Chelmsford', 'Cheltenham', 'Chester', 'Colchester', 'Colwyn Bay', 'Coventry', 'Crawley', 'Croydon', 'Darlington', 'Dartford', 'Derby', 'Derry', 'Doncaster', 'Dover', 'Dudley', 'Dumbarton', 'Dumfries', 'Dundee', 'Durham Tees Valley', 'Eastbourne', 'East Kilbride', 'East Midlands', 'Edinburgh', 'Elgin', 'Epsom', 'Exeter', 'Falkirk', 'Falmouth', 'Fareham', 'Farnborough', 'Feltham', 'Fishguard', 'Fraserburgh', 'Glasgow', 'Glasgow Prestwick', 'Gloucester', 'Godalming', 'Great Yarmouth', 'Grimsby', 'Guernsey', 'Guildford', 'Gwynedd', 'Hamilton', 'Hampton', 'Harlington / Hayes', 'Harlow', 'Harrogate', 'Harrow', 'Hastings', 'Helston', 'Hemel Hempstead', 'Hereford', 'High Wycombe', 'Hoddesdon', 'Holyhead', 'Huddersfield', 'Hull', 'Humberside', 'Ilchester', 'Inverness', 'Ipswich', 'Isle of Man', 'Jersey', 'Kent', 'Kilmarnock', 'Kings Lynn', 'Kirkcaldy', 'Lancaster', 'Lancing', 'Leeds', 'Leicester', 'Lincoln', 'Liverpool', 'Livingston', 'Llandudno', 'London', 'London City Airport', 'London Gatwick Airport', 'London Heathrow Airport', 'London Luton Airport', 'London Stansted Airport', 'Lowestoft', 'Luton', 'Macclesfield', 'Maidstone', 'Manchester', 'Mansfield', 'Middlesbrough', 'Milton Keynes', 'Motherwell', 'Newbury', 'Newcastle Upon Tyne', 'Newport', 'Newquay', 'Northampton', 'Northwich', 'Norwich', 'Nottingham', 'Oldbury', 'Oldham', 'Oxford', 'Paisley', 'Pembroke', 'Penrith', 'Penzance', 'Perth', 'Peterborough', 'Peterhead', 'Plymouth', 'Poole', 'Portsmouth', 'Preston', 'Reading', 'Redditch', 'Reigate', 'Rochdale', 'Rochester', 'Romford', 'Rutland', 'Salisbury', 'Sheffield', 'Shetland Islands', 'Shrewsbury', 'Slough', 'Southampton', 'Southend', 'Southend-on-Sea', 'Stafford', 'Staines', 'St. Albans', 'Stansted', 'Stevenage', 'Stirling', 'Stockport', 'Stockton On Tees', 'Stoke-On-Trent', 'Stranraer', 'Stratford Upon Avon', 'Sunbury', 'Sunderland', 'Sutton', 'Swansea', 'Swindon', 'Tamworth', 'Taunton', 'Teesside', 'Telford', 'Thetford', 'Tonbridge', 'Torquay', 'Truro', 'Uxbridge', 'Wakefield', 'Walsall', 'Warrington', 'Warwick', 'Watford', 'Wellingborough', 'Welshpool', 'Welwyn Garden City', 'West Bromwich', 'Weston-Super-Mare', 'Wetherby', 'Weymouth', 'Wigan', 'Woking', 'Wolverhampton', 'Worcester', 'Workington', 'Worthing', 'Worthing Lancing', 'Yeovil', 'York', }]
</body>
</html>
Upvotes: 1
Views: 264
Reputation: 101
It appears that you are on the right track, however, I would suggest that you take a look at using a framework like jQuery because this task would be much simpler.
First off, looking at the xmlhttp.responseText, it appears that you need to change your struts configuration so that the output is not a full HTML document. The way the server is returning this response is going to make it very difficult for you to process. A quick way to make this work the way you want is to have the server generate a populated select tag. When your source page renders, place a disabled select tag inside of a div element that you can reference by an ID like so -
<div id="dynamicSelectTagHolder">
<select name="foo" disabled="true" />
</div>
Once the server has generated a result, you can assign the contents of the div#dynamicSelectTagHolder to the text returned by the server using innerHTML like so -
document.getElementById("dynamicSelectTagHolder").innerHTML = xmlhttp.responseText;
Be forewarned you may run into many problems with your current approach. It has been a while for me, but if I remember correctly, innerHTML and getElementById is not something that works perfectly across all browsers. That is why I suggest looking into jQuery.
Upvotes: 2