I din't able to create this in proper way like magento does but if you will have all the state of all country then I think this is the perfect solution. If you don't have all state for all country then this module is not solved your problem. If any one knows the correct way then please add the solution via comment. I am describing here How I exactly did on my Magento Cloud Hosting.

First Time you have see only country drop down

When you select country that time load  Ajax

And Next Update all select option with Ajax

So now ready to start and display country and state in drop down in custom module.
Open your form which is in Yournamespace/Modulename/Block/Adminhtml/Modulename/Edit/Tab/Form.php then add below fields

$storeId = $this->getRequest()->getParam('id');
        if($storeId !=''):
            $editState = $stateCollection = Mage::getModel('storelocator/storelocator')->load($storeId);
            $stateCollection = Mage::getModel('directory/region')->getResourceCollection()->addCountryFilter($editState->getCountry())->load();
            $state = "";
            foreach ($stateCollection as $_state) {
                $state[]= array('value'=>$_state->getCode(),'label'=>$_state->getDefaultName());
            $fieldset->addField('state', 'select', array(
                'label' => Mage::helper('storelocator')->__('State'),
                'required' => false,
                'name' => 'state',
                'selected' => 'selected',
                'values' => $state,
            $fieldset->addField('state', 'select', array(
                'name'  => 'state',
                'required' => false,
                'label' => Mage::helper('storelocator')->__('State'),
                'values' => '--Please Select Country--',
        * Add Ajax to the Country select box html output
        $country->setAfterElementHtml("<script type=\"text/javascript\">
            function getstate(selectElement){
                var reloadurl = '". $this->getUrl('storelocator/adminhtml_storelocator/state') . "country/' + selectElement.value;
                new Ajax.Request(reloadurl, {
                    method: 'get',
                    onComplete: function(transport){
                        var response = transport.responseText;

And Now Create State Action in modulenamecontroller.php file which will be like this
public function stateAction() {
        $countrycode = $this->getRequest()->getParam('country');
        $state = "<option value=''>--Please Select--</option>";
        if ($countrycode != '') {
            $statearray = Mage::getModel('directory/region')->getResourceCollection()->addCountryFilter($countrycode)->load();
            foreach ($statearray as $_state) {
                $state .= "<option value='" . $_state->getCode() . "'>" . $_state->getDefaultName() . "</option>";
        echo $state;

It's working in Magento. I already tested. i have use only prototype js code with ajax this code not conflict any js.