Creating a country, city search form

Hi Guys,

I'm trying to create a rather basic search form that first asks the user to select a country (from a 'pulldown' list of existing countries via the BRILLIANT country selector plugin by Jarome Bakker) and then from that specific, selected country gather 'cities' and produce another pulldown for the final search. So the search form is then producing a page of results just from the selected city, but its a 2-step process for the user. Country - then City - then bingo; results.

So far to do this I have the following code; but unfortunately the city pulldown is not being updated and populated and so its not working....

    global $CONFIG;

    $mypluginposts = elgg_get_entities(array('type'=>'object','subtype'=>'myplugin'));

    foreach ($mypluginposts as $mypluginpost) {
        $value = $mypluginpost->country;
        $countries_from_myplugin[] = $value; 
    $unique_countries_from_myplugin = array_unique($countries_from_myplugin);
         $form_body = "<div class=\"contentWrapper\"><label><strong>" . elgg_echo("myplugin:search:title") . "</strong><br /></label>" ;
          $form_body .= "<label><strong>".elgg_echo('Select a Country of interest, then a city: ')."</strong></label>";
                        $country_params = array(
            'internalname' => 'selectcountry',
            'value' => 'default if any',
            'options' => $unique_countries_from_myplugin
          $form_body .= "<label>" . elgg_echo('Country: ') . elgg_view('input/pulldown', $country_params) ."</label><br />";
          foreach ($mypluginposts as $bar_country) {
              if ($bar_country->country == 'selectcountry') {
                  $cities[] = $bar_country->city;
          $city_names = array_unique($cities);
              $params = array(
            'internalname' => 'selectcity',
            'value' => 'default if any',
            'options' => $city_names
          $form_body .= "<label>" . elgg_echo('City: ') . elgg_view('input/pulldown', $params) ."</label><br />";
         $form_body .= elgg_view('input/submit', array('value' => elgg_echo("Search"))) . "</p></div>";
         echo elgg_view('input/form', array('body' => $form_body, 'selectedcity' => $selectcity, 'action' => "{$CONFIG->url}mod/myplugin/mypluginbycity.php"));



...I suspect I'm not using the internalname 'selectcountry' properly (and passing the needed city string) or I need to do something to update the page?

Any insights super appreciated.



  • Hi James,

    yes, you need 'something to update the page'. The best way is to use Javascript:

    you attach an event to the pulldown menu, so each time you pick a different country a function is called, then this function load new data in the city pulldown menu (when no country is selected the city menu is empty).


    If are not familiar with Javascript, you can do it without JS, but for sure is not a good can select a country from the menu, then the city menu is still empty, now you click on search and the page refresh sending holding the selected country and loading cities in the city menu, now if you click pick the city and click search, you've done!

    For sure the first way is the best!

  • Oh k, Thanks :D - I'll do some looking into the JS way. I'm not familiar with it at all. But maybe there's something already out there I can copy & change to suit *fingers crossed* 


  • Update:

    ok i tested the code and was a bit buggy...this works:








    <form id="addressForm">

    <select id="countries" onchange="populateCities();">

    <option value="ITA">Italy</option>

    <option value="NOR">Norway</option>



    <select id="cities"></select>




    <script type="text/javascript"><!--



    function populateCities(){


    var all_cities = {'ITA':{'Mln':'Milan', 'Blg':'Bologna'}, 'NOR':{'Osl':'Oslo', 'Trd':'Trondheim'}};

    var selected_country = document.getElementById("countries").value;


    document.getElementById("cities").options.length=0; //clear all previous options

    var count = 0;

    var city;

    for ( city in all_cities[selected_country]) {

    document.getElementById("cities").options[count]=new Option(all_cities[selected_country][city], city);









    you can copy in a .html file and open it with a browser...

  • hmm..
    i coded something along these lines for a client -
    to automatically fill in the state and city for zip code input ->


  • Thanks Tango - This works and nicely ! You're a star.

    2 questions -

    1 - is it better, cleaner code to refer to an external .js script and not include header script in a php file?

    2 - how from within this script can I get it to pull data from existing elgg entities. In my initial post I detail normal php code that GETS countries associated with existing entities (i.e the country doesn't show up if no ones created an object in that country) and then the available city choices (these are user created by a text field, metadata when the object is saved, whereas the country is from a pulldown selector plugin....

    Sorry that got long winded - basically just want to change ->

    <option value="ITA">Italy</option>

    <option value="NOR">Norway</option> <- to options from $unique_countries_from_myplugin (from 1st post above)


    then change ->

    var all_cities = {'ITA':{'Mln':'Milan', 'Blg':'Bologna'}, 'NOR':{'Osl':'Oslo', 'Trd':'Trondheim'}};

    <- to city options from $city_names


    any help greatly appreciated :)




  • well:

    1 - for sure if you include a JS file in the head of the page, the html page code is cleaner than to write the whole JS code in the body and is simplier for you to edit the JS code...but this is the only difference..


    2 - you can create the options of the two pulldown menu with the Option object, so instead of writing

    <option value="ITA">Italy</option>

    <option value="NOR">Norway</option>

    you can use 

    document.getElementById("countries").options[count]=new Option( country_show_name, country_id);

    on the country menu, to 'automize' both the pulldown menus.

    Then what you need is to dynamically create two array, one for the cities and one for the countries, so instead of

    var all_cities = {'ITA':{'Mln':'Milan', 'Blg':'Bologna'}, 'NOR':{'Osl':'Oslo', 'Trd':'Trondheim'}};

    you can simply use your array 

    document.getElementById("countries").options[count]=new Option( unique_countries_from_myplugin, country_unique_id )

    if you use the code i wrote above, the array use as keys an identifier of the country, and as correspondent value, the friendly name of the country/city, so when a user select something, what you get as result, is the identifier and not the friendly name...for sure you can avoid this using only the friendly name!


    Note: if your countries array is a php variable, you must pass it to javascript, that allow you to change menus value without refreshing the page (ajax), or you must build the pulldown menus in php...