'Toggle between a textbox and a select using PHP

I have a basic customer information form that I would like to make a little more interactive. The idea being if the user selects a country that is not USA or Canada the state Select turns to a state textbox. I'm sure this can be done with just PHP but have debated using jQuery but would like to avoid it if possible. Here is my form sample:

<tr>
    <td>
        <input name="city" type="text" id="city" value="<?= $this->aBillingProf['cCity']; ?>" />
    </td>
    <td>
        <select name="state" id="state" style="width:218px;position:relative;top:-4px;">
            <? $s = strlen($this->aBillingProf['cState']) == 2 ? strtoupper($this->aBillingProf['cState']) : strtoupper(stateTranslate($this->aBillingProf['cState']));
            echo stateSelect('both',$s); ?>
        </select>
        <input name="state" type="text" id="state" value="<?= $this->aBillingProf['cState']; ?>" />
/*The Idea being only one of the above options is available depending on what is selected from the country select */

    </td>
</tr>
<tr>
    <td>
        <label for="zip">Zip / Postal Code</label>
    </td>
    <td>
        <label for="country">Country</label>
    </td>
</tr>
<tr>
    <td>
        <input name="zip" type="text" id="zip" maxlength="6" value="<?= $this->aBillingProf['cZip']; ?>" />
    </td>
    <td>
        <select name="country" id="country" style="width:218px;position:relative;top:-4px;">
            <?= AffiliateStore::countrySelect($this->aBillingProf['cCountry']); ?>
        </select>
        <!-- <input type="text" name="country" id="country" value="<?= $this->aBillingProf['cCountry']; ?>" /> -->
    </td>
</tr>


Solution 1:[1]

Basically what I do is to add a div containing the inputs I would need. In this case I would use a select boxes for US and Canadian states and a text input for other. Use the CSS diplay:none to collapse all divs except the one for the default selected country.

<div id="state_inputs">
    <div id="us_states_div">
        <!-- Select box for US states goes here -->
    </div>
    <div style="display:none" id="ca_states_div">
        <!-- Select box for US states goes here -->
    </div>
    <div style="display:none" id="other_states_div">
        <input type="text" name="other_states" />
    </div> 
</div>

Now assuming that your select box for the country has the id country_select:

<script>
document.getElementById("country_select").onchange = function() {
        var country_select = document.getElementById("country_select");
        var country = country_select.options[country_select.selectedIndex].text;

        if(country == "USA") {
            document.getElementById("us_states_div").style.display="block";
            document.getElementById("ca_states_div").style.display="none";
            document.getElementById("other_states_div").style.display="none";
        } else if(country == "Canada") {
            document.getElementById("us_states_div").style.display="none";
            document.getElementById("ca_states_div").style.display="block";
            document.getElementById("other_states_div").style.display="none";
        } else {
            document.getElementById("us_states_div").style.display="none";
            document.getElementById("ca_states_div").style.display="none";
            document.getElementById("other_states_div").style.display="block";
        }
    };
</script>

Once you've updated your PHP to output that markup, on the processing side you just look at the selected country and then use the value contained in the correct state input.

Solution 2:[2]

This can't be done with just PHP because it requires that you use client side scripting to determine when the event has been triggered. You could use PHP to rebuild the form, however, that would require a reload from the sever. It's much easier just to use JavaScript to handle the event and update the form.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Erik Nedwidek
Solution 2 Patrick Stephens