The title may be a bit confusing, but here is what I am trying to do..

I have three different <select> fields, named city, state and zip code.

What I would like to do is have the visitor choose a state from the first <select> field. When they choose their state, I would like to automatically load the city <select> field with all the cities from that state (I have all the city / state / zip info stored in a database).
Finally, after choosing their city, the zip <select> should load all the appropriate zip codes for that city.

I know how to do this with PHP, but I can't have the page reload because this is going on a sign up form..
I have spent the last two days searching the internet on how to do this, but cant find anything, so I am hoping I can find some help here!

Thank you very much for your time :)

Dani AI

Generated

has the right idea: use an async request to refill the dependent selects without reloading. Two gotchas to watch out for, both visible in this thread: cache and race conditions. already hit a browser cache issue; on the server, send JSON with appropriate Cache-Control headers, or version your URLs, to avoid stale option lists. Also guard against the user switching state quickly; otherwise responses can arrive out of order and populate the wrong cities.

Here is a small, modern, jQuery-free pattern that handles disable/enable, caching, and aborted requests. Have your endpoints return JSON arrays like [ { "id": 123, "name": "Phoenix" } ] and [ { "zip": "85001" } ].

<script>
const $ = s => document.querySelector(s);
const stateSel = $('#state'), citySel = $('#city'), zipSel = $('#zip');
const cache = { citiesByState: {}, zipsByKey: {} };
let cityCtrl, zipCtrl;

function fillOptions(sel, items, v='value', l='label') {
  sel.innerHTML = '<option value="">Select...</option>' +
    items.map(o => `<option value="${o[v]}">${o[l]}</option>`).join('');
}

stateSel.addEventListener('change', async () => {
  const state = stateSel.value; citySel.disabled = zipSel.disabled = true;
  if (!state) return;
  if (cityCtrl) cityCtrl.abort(); cityCtrl = new AbortController();
  const key = state;
  const data = cache.citiesByState[key] || await fetch(`/api/cities?state=${encodeURIComponent(state)}`, { signal: cityCtrl.signal })
    .then(r => r.json()).then(d => (cache.citiesByState[key]=d));
  fillOptions(citySel, data.map(c => ({ value: c.id ?? c.name, label: c.name })));
  citySel.disabled = false; zipSel.innerHTML = '<option value="">Select...</option>';
});

citySel.addEventListener('change', async () => {
  const state = stateSel.value, city = citySel.value; zipSel.disabled = true;
  if (!state || !city) return;
  if (zipCtrl) zipCtrl.abort(); zipCtrl = new AbortController();
  const k = `${state}|${city}`;
  const data = cache.zipsByKey[k] || await fetch(`/api/zips?state=${encodeURIComponent(state)}&city=${encodeURIComponent(city)}`, { signal: zipCtrl.signal })
    .then(r => r.json()).then(d => (cache.zipsByKey[k]=d));
  fillOptions(zipSel, data.map(z => ({ value: z.zip, label: z.zip })));
  zipSel.disabled = false;
});
</script>

Server-side tips: keep using prepared statements, return only the fields needed, and include a sentinel option or 204 when no results. Front-end: ensure each <select> has a useful name for form submission and an initial disabled state until its parent selection is made.

Recommended Answers

All 11 Replies

For get data you can use following script:

 <head>
 <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
 </head>
 <body>
    <script>
        $(document).ready(function()
        {
            $("#state").change(function()
            {
                var state = $(thia).val();//get select value
                $.ajax(
                {
                    url:"get_city.php",
                    data:{s:state},
                    success:function(responce)
                    {
                        $("#city").html(responce);
                    }
                });
            });
        });
    </script>
    <select id="state">
        <option id="423">Alabama</option>
        <option id="424">Alaska</option>
        <option id="425">Arizona</option>
    </select>
    <select id="city"></select>
    <select id="zip"></select>
 </body>

Above is an example to get data for the "state" to others by analogy.

Thank you for the tip! I will try it out shortly and post results here

I just copy / pasted your code above, I am assuming the following are typos?

var state = $(thia).val();//get select value
$(thia) should be $(this)

and

(responce) should be (response)

Is that correct?

radow,

I have the get_city.php side working, but the city select field isn't changing..
I have the jquery lib included, so i am not sure why this is?

My PHP code is as follows:

$db = new PDO(///// PDO connection details /////);
$state = $_REQUEST['state'];
$s = $db->prepare(" SELECT name FROM cities WHERE statecode = ? ORDER BY name ASC");
$s->execute(array($state));
$s->setFetchMode(PDO::FETCH_ASSOC);
$city = $s->fetch();

while($city = $s->fetch())
echo "<option>" . $city['name'] . "</option>";

If I view get_city.php directly in the browser (and append ?state=PA), it shows all the cities in the appropraite state. So the PHP code is working properly, but I think the problem is is that is not getting passed back to the signup page, but I'm new to JS, so possibly I am doing something wrong there

Ok. I adjusted my code.

$(document).ready(function()
        {
            $("#state").change(function()
            {
                var state = $(this).val();//get select value
                $.ajax(
                {
                    url:"get_city.php",
                    type:"post",
                    data:{state:$(this).val()},
                    success:function(responce)
                    {
                        $("#city").html(responce);
                    }
                });
            });
        });

Still no dice; the city field does not get populated for some reason...

You can view the page I am trying this on here:

Also, here is the code that I have:

 <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>

    <script>
$(document).ready(function()
        {
            $("#state").change(function()
            {
                var state = $(this).val();//get select value
                $.ajax(
                {
                    url:"",
                    type:"post",
                    data:{state:$(this).val()},
                    success:function(response)
                    {
                        $("#city").html(response);
                    }
                });
            });
        });
    </script>


<div align="center"><h3>Sign up for free on Fling Finder</h3></div>

<form name='signup' action="" method="post">
<table class="table" cellpadding="5px">
<tr><td>First Name</td><td><input type="text" name="fname" required=required size="35"></td></tr>
<tr><td>Last Name</td><td><input type="text" name="lname" required=required size="35"></td></tr>
<tr><td>Username</td><td><input type="text" name="username" required=required size="35" maxlength="20" <?php if(isset($uname)){ echo "value=".$uname;}?>  placeholder="Only alphanumerical characters, spaces and underscore allowed"><div id="signupdiv">
</div></td></tr>
<tr><td>Password</td><td><input type="password" name="password" size="35" required=required <?php if(isset($password)){ echo "value=".$password;}?> ></td></tr>
<tr><td>Date of Birth &nbsp;&nbsp;<em>(YEAR-MONTH-DAY)</em></td><td><input type="text" name="dob" size="35" required=required value="<?php echo  (date("Y") - 18).date("-m-d"); ?>"></td></tr>
<tr><td>I am a</td><td><select name="gender" required=required><option value="Male">Male</option><option value="Female">Female</option></select></td></tr>
<tr><td>Seeking a</td><td><select name="lookgender" required=required><option value="Male">Male</option><option value="Female">Female</option></select></td></tr>
<tr><td>Email</td><td><input type="email" name="email" size="35" required=required></td></tr>


**    <tr><td>State</td><td><select name="state" id="state"><option value="<?= MYSTATE; ?>"><?= MYSTATE; ?></option><br /><?= states(); ?></select></td></tr>
    <tr><td>City</td><td><select id="city" name="city"><option></option></select></td></tr>
    <tr><td>Zip Code</td><td><input type="text" name="zip" size="35" maxlength="5" required=required value="<?= MYZIP; ?>"></td></tr>**
    <tr><td>About Me</td><td><textarea rows="20" cols="36" name="about_me"  onfocus="this.value=''; this.onfocus=null;">Tell other members a little about yourself. Please enter at least two sentences.</textarea></td></tr>
    <tr><td></td><td><input type="checkbox" name="agree" value="1"> &nbsp;&nbsp; Agree to <a href="<?= URL.'site/terms'; ?>">terms of use</a> in order to register</td></tr>
    <tr><td></td><td><input class="btn btn-primary" name="submit" type="submit" value="Finished!"></td></tr>
    </table>
    </form>

Nevermind!
I was logged into my Mac, and restarted in to Windows, and now the script works. I think that I simply needed to clear the cache from my browser.

Thank you so much radow!

One last question,

When doing the zip code field, I need to use both the city and state in my PHP query, but being new to JS / Jquery, I cannot figure out how to modify this to send both the city and state values to my php script:

 <script>
$(document).ready(function()
        {
            $("#city").change(function()
            {
                var city = $(this).val();//get select value
                $.ajax(
                {
                    url:"",
                    type:"post",
                    data:{city:$(this).val()},
                    success:function(response)
                    {
                        $("#zip").html(response);
                    }
                });
            });
        });
    </script>
data:{city:$(this).val(),state:$("#state").val()},

Change this line to line number 11 in your the script writed above. and line number 6 can delete, it don't use

Just wanted to say thanks for your time helping me! Feel great to learn new things

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.