Hi Stephane, I hope this example will help. This component can be used to populate city based on country and then location based on city selected. You need t5components/chenellkit components.
1. Add PKCCL component into component folder package com.openfinance.OpenFinanceManager.components; import java.util.ArrayList; import java.util.List; import org.apache.tapestry5.ComponentResources; import org.apache.tapestry5.Field; import org.apache.tapestry5.SelectModel; import org.apache.tapestry5.StreamResponse; import org.apache.tapestry5.ValidationTracker; import org.apache.tapestry5.ValueEncoder; import org.apache.tapestry5.annotations.Component; import org.apache.tapestry5.annotations.Environmental; import org.apache.tapestry5.annotations.IncludeJavaScriptLibrary; import org.apache.tapestry5.annotations.Mixins; import org.apache.tapestry5.annotations.OnEvent; import org.apache.tapestry5.annotations.Parameter; import org.apache.tapestry5.annotations.Persist; import org.apache.tapestry5.corelib.components.Form; import org.apache.tapestry5.corelib.components.Select; import org.apache.tapestry5.ioc.Messages; import org.apache.tapestry5.ioc.annotations.Inject; import org.apache.tapestry5.json.JSONArray; import org.apache.tapestry5.json.JSONObject; import org.apache.tapestry5.services.ComponentDefaultProvider; import org.apache.tapestry5.util.TextStreamResponse; import org.hibernate.Session; import org.slf4j.Logger; import com.openfinance.OpenFinanceManager.data.CityDAO; import com.openfinance.OpenFinanceManager.data.CityDAOImpl; import com.openfinance.OpenFinanceManager.data.CountryDAO; import com.openfinance.OpenFinanceManager.data.CountryDAOImpl; import com.openfinance.OpenFinanceManager.data.LocationDAO; import com.openfinance.OpenFinanceManager.data.LocationDAOImpl; import com.openfinance.OpenFinanceManager.entities.City; import com.openfinance.OpenFinanceManager.entities.Country; import com.openfinance.OpenFinanceManager.entities.Location; import com.openfinance.OpenFinanceManager.helper.CityEncoder; import com.openfinance.OpenFinanceManager.helper.CitySelectModel; import com.openfinance.OpenFinanceManager.helper.CountryEncoder; import com.openfinance.OpenFinanceManager.helper.CountrySelectModel; import com.openfinance.OpenFinanceManager.helper.LocationEncoder; import com.openfinance.OpenFinanceManager.helper.LocationSelectModel; import com.openfinance.OpenFinanceManager.pages.Home; public class PKCCL implements Field { @Inject private Logger logger; @Inject private Messages messages; @Inject private CountryDAO countryDAO; @Inject private CityDAO cityDAO; @Inject private LocationDAO locationDAO; @Persist private Country selectedCountry; @Persist private City selectedCity; @Persist private Location selectedLocation; @Component(id="countries", parameters = {"value=selectedCountry", "event=change", "onCompleteCallback=literal:onChangeCountry"}) @Mixins({"t5components/OnEvent"}) private Select _countries; @Component(id="cities", parameters = {"value=selectedCity", "event=change", "onCompleteCallback=literal:onChangeCity"}) @Mixins({"t5components/OnEvent"}) private Select _citiesOfCountry; @Parameter(defaultPrefix="literal") private String label; @Inject private ComponentResources componentResources; @Inject private ComponentDefaultProvider componentDefaultProvider; @Parameter private boolean disabled; @Environmental private ValidationTracker tracker; public PKCCL() { } public SelectModel getCountryModel() { return new CountrySelectModel(countryDAO.findAllCountries()); } public ValueEncoder<Country> getCountryEncoder() { return new CountryEncoder(countryDAO); } public Country getSelectedCountry() { return selectedCountry; } public void setSelectedCountry(Country selectedCountry) { this.selectedCountry = selectedCountry; } public SelectModel getCityModel() { if (selectedCountry == null || selectedCountry.getName() == "") { List<City> c = new ArrayList<City>(); return new CitySelectModel(c); } else { return new CitySelectModel(cityDAO.findAllCities(selectedCountry.getId().longValue())); } } public ValueEncoder<City> getCityEncoder() { return new CityEncoder(cityDAO); } public City getSelectedCity() { return selectedCity; } public void setSelectedCity(City selectedCity) { this.selectedCity = selectedCity; } public SelectModel getLocationModel() { if (selectedCity == null || selectedCity.getName() == "") { List<Location> c = new ArrayList<Location>(); return new LocationSelectModel(c); } else { return new LocationSelectModel(locationDAO.findAllLocationsOfCity(selectedCity.getId().longValue())); } } public ValueEncoder<Location> getLocationEncoder() { return new LocationEncoder(locationDAO); } public Location getSelectedLocation() { return selectedLocation; } public void setSelectedLocation(Location selectedLocation) { logger.info("Inside setSelectedLocation() "); this.selectedLocation = selectedLocation; if (selectedCountry == null || selectedCity == null || selectedLocation == null) { logger.info("Location is null."); tracker.recordError(this, messages.get("ccl-empty")); } } public StreamResponse onChangeFromCountries(String c) { logger.info("country ID = " + c); JSONObject json = new JSONObject(); if (c != null && c!= "") { List<City> cities = cityDAO.findAllCities(new Long(c).longValue()); if (cities != null) { String idv = ""; JSONArray ids = new JSONArray(); JSONArray vs = new JSONArray(); JSONArray counter = new JSONArray(); counter.put("0"); ids.put(""); vs.put(""); for(int i = 0; i < cities.size(); i++) { String tmpid = new Long(cities.get(i).getId()).toString(); ids.put(tmpid); String tmpvalue = cities.get(i).getName(); vs.put(tmpvalue); counter.put(new Integer(i+1).toString()); } json.put("counter", counter); json.put("ids", ids); json.put("values", vs); } } else { //form.recordError("Country information is empty."); } //json.put("color", c); //return json; return new TextStreamResponse("text/json", json.toString()); } public StreamResponse onChangeFromCities(String c) { logger.info("city ID = " + c); JSONObject json = new JSONObject(); if (c != null && c!= "") { List<Location> locs = locationDAO.findAllLocationsOfCity(new Long(c).longValue()); if (locs != null) { String idv = ""; JSONArray ids = new JSONArray(); JSONArray vs = new JSONArray(); JSONArray counter = new JSONArray(); counter.put("0"); ids.put(""); vs.put(""); for(int i = 0; i < locs.size(); i++) { String tmpid = new Long(locs.get(i).getId()).toString(); ids.put(tmpid); String tmpvalue = locs.get(i).getName(); vs.put(tmpvalue); counter.put(new Integer(i+1).toString()); } json.put("counter", counter); json.put("ids", ids); json.put("values", vs); } } else { //form.recordError("City information is empty."); } return new TextStreamResponse("text/json", json.toString()); } public String getClientId() { // TODO Auto-generated method stub return componentResources.getId(); } public String getControlName() { // TODO Auto-generated method stub return null; } public String getLabel() { // TODO Auto-generated method stub return label; } public boolean isDisabled() { // TODO Auto-generated method stub return false; } public boolean isRequired() { // TODO Auto-generated method stub return false; } String defaultLabel() { return componentDefaultProvider.defaultLabel(componentResources); } public void setDisabled(boolean disabled) { this.disabled = disabled; } } 2. Here is the corresponding tml file <t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd" xmlns:p="tapestry:parameter"> <div class="PKCCLcont"> <div class="PKCCLl"> <label t:type="Label" t:for="countries"></label> </div> <div class="PKCCLd"> <select t:type="Select" t:model="countryModel" t:value="selectedCountry" t:encoder="countryEncoder" t:id="countries" t:disabled="disabled"/> </div> <div class="PKCCLl"> <label t:type="Label" t:for="cities"></label> </div> <div class="PKCCLd"> <select t:type="Select" t:model="cityModel" t:value="selectedCity" t:encoder="cityEncoder" t:id="cities" t:disabled="disabled"/> </div> <div class="PKCCLl"> <label t:type="Label" t:for="locations"></label> </div> <div class="PKCCLd"> <select t:type="Select" t:model="locationModel" t:value="selectedLocation" t:encoder="locationEncoder" t:id="locations" t:disabled="disabled"/> </div> </div> <script type="text/javascript"> //<![CDATA[ function onChangeCountry(response) { //alert(response); var ids = new Object(); ids = response.evalJSON().ids; if (ids != null) { //alert(ids[0]); } var vals = new Object(); vals = response.evalJSON().values; //var idsarray = ids.split(','); //alert(idarray[1]); if (vals != null) { //alert(vals[0]); } var c = new Object(); c = response.evalJSON().counter; var selectId = document.getElementById("cities"); selectId.innerHTML = ""; if (c != undefined) { populateCitiesOrLocations("cities", c, ids, vals); } } function onChangeCity(response) { var ids = new Object(); ids = response.evalJSON().ids; if (ids != null) { //alert(ids[0]); } var vals = new Object(); vals = response.evalJSON().values; //var idsarray = ids.split(','); //alert(idarray[1]); if (vals != null) { //alert(vals[0]); } var c = new Object(); c = response.evalJSON().counter; var selectId = document.getElementById("locations"); selectId.innerHTML = ""; if (c != undefined) { populateCitiesOrLocations("locations", c, ids, vals); } } function populateCitiesOrLocations(id, c, ids, vs) { var s = document.getElementById(id); var len = c.length; var count = 0; var x = 0; var optn = document.createElement("OPTION"); optn.text = ""; optn.value = ""; c.each(function(x) { var optn = document.createElement("OPTION"); optn.text = vs[x]; optn.value = ids[x]; s.options.add(optn); }); /* for(x = 0; x < len; x++) { var optn = document.createElement("OPTION"); optn.text = vs[x]; optn.value = ids[x]; s.options.add(optn); } */ } //]]> </script> </t:container> Stephane Decleire wrote: > > Has anyone already tried to implement dependant dropdown boxes with the > Ajax features of Tapestry 5.0.11 ? > I would like to implement a component to get a user address (country, > zipcode, city) and i would like to present the user the cities according > to the zipcode and the country just filled. > > Any ideas ? > > Stephane > > Quoted from: http://www.nabble.com/T5-%3A-Dependant-dropdown-boxes-tp15760811s302p15760811.html Otho wrote: > > Shouldn't that be possible with chenillekits' onEvent mixin and the > onchange > event? > > 2009/7/12 Geoff Callender <geoff.callender.jumpst...@gmail.com> > >> Please add your vote to https://issues.apache.org/jira/browse/TAP5-138 . >> >> Cheers, >> >> Geoff >> >> >> On 11/07/2009, at 5:48 AM, newtonik wrote: >> >> >>> I am also about to try to implement it. Has anyone out there done this. >>> If >>> you have, please share tips and samples. Javascript in Tapestry is not >>> as >>> simple as we would like. Thanks. >>> -- >>> View this message in context: >>> http://www.nabble.com/T5-%3A-Dependant-dropdown-boxes-tp15760811p24433504.html >>> Sent from the Tapestry - User mailing list archive at Nabble.com. >>> >>> >>> --------------------------------------------------------------------- >>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org >>> For additional commands, e-mail: users-h...@tapestry.apache.org >>> >>> >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org >> For additional commands, e-mail: users-h...@tapestry.apache.org >> >> > > -- View this message in context: http://www.nabble.com/T5-%3A-Dependant-dropdown-boxes-tp15760811p24556794.html Sent from the Tapestry - User mailing list archive at Nabble.com. --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org