County in respect of Country list
Permalink 1 user found helpful
Hi All
I'm integrating a payment system where I need users to put its address details. I've done everything instead the County/State list in respect of Country. Well its like if I choose US, it automatically gets the list of states of US. If any other country, it will show a textbox. Pretty similar like core-commerce billing or shipping page.
I need the same to implemented. Is there any code or how-to available in forum. Or is there anybody who can help me to solve this.
Thanks in advance!
Rony
I'm integrating a payment system where I need users to put its address details. I've done everything instead the County/State list in respect of Country. Well its like if I choose US, it automatically gets the list of states of US. If any other country, it will show a textbox. Pretty similar like core-commerce billing or shipping page.
I need the same to implemented. Is there any code or how-to available in forum. Or is there anybody who can help me to solve this.
Thanks in advance!
Rony
Thanks so much for this. Really helpful.
Will do some tricks to fetch all available states list in respect of all individual country by Ajax call. Anyway you can write it down as how-to so that people can easily get help from this.
Rony
Will do some tricks to fetch all available states list in respect of all individual country by Ajax call. Anyway you can write it down as how-to so that people can easily get help from this.
Rony
Glad I could help! I think I will go ahead and write a how-to for this later on this morning. I think I will also include the AJAX necessary to pull the states for the selected country. Anyway, when I get it posted I'll send you the link.
Hey Rony,
Just an FYI - I published a how-to on this topic here:http://www.concrete5.org/documentation/how-tos/developers/filtering...
The how-to is a bit cleaner because I used concrete5's form helpers to generate the dropdown lists. Also the how-to shows how you can use AJAX to filter the states based on the selected country. Hopefully it will be helpful to someone.
Have a good one!
Blake
Just an FYI - I published a how-to on this topic here:http://www.concrete5.org/documentation/how-tos/developers/filtering...
The how-to is a bit cleaner because I used concrete5's form helpers to generate the dropdown lists. Also the how-to shows how you can use AJAX to filter the states based on the selected country. Hopefully it will be helpful to someone.
Have a good one!
Blake
hi bbeng89, I know that this is an old link, but I'm hoping you can help me as this is driving me crazy...
I have followed you tutorial on the above link and I have created a little form to GET the submitted info:
and my controller has:
This all works fine and if, for example, the user selects 'United States' it will change the state dropdown accordingly. On SUBMIT, USA is automtically selected and the states are also successfully loaded. Brilliant!
However, if the user selects a country which does NOT have any pre-entered 'states', for example Ukraine, the 'stateTextbox' appears and they type in the state.
My problem is that on SUBMIT, it comes up with an error:
I understand why the error is happening - the controller is loading in 'Ukraine', but form.php isn't able to find any associated 'states', instead of the 'stateTextbox' loading in...
Is there any way 'round this? I'm so close, yet I feel so far away. It would be brilliant to get this to work properly.
I you can help me out, I'd be really grateful as I've been puzzling over this for weeks now :(
Thanks
Rob
I have followed you tutorial on the above link and I have created a little form to GET the submitted info:
<form method="get"> <?php $fh = Loader::helper('form'); ?> Country: <?php echo $fh->select('country', $countries, 'GB'); ?> <br/><br/> State: <?php echo $fh->select('stateDropdown', $states, 'IL'); ?> <input type="text" id="stateTextbox" name="stateTextbox" style="display:none;" /> <script> $(document).ready(function(){ $('#country').change(function(){ $.ajax({ url: '<?php echo $this->action('get_states'); ?>', type: 'GET', data: { country: $(this).val() },
Viewing 15 lines of 43 lines. View entire code block.
and my controller has:
<?php class StateFilterController extends Controller{ public function on_start(){ $this->stateHelper = Loader::helper('lists/states_provinces'); $this->countryHelper = Loader::helper('lists/countries'); } public function get_states(){ $country = $this->get('country'); if(!empty($country)){ $states = $this->stateHelper->getStateProvinceArray($country); echo json_encode($states); } exit; } public function view(){
Viewing 15 lines of 21 lines. View entire code block.
This all works fine and if, for example, the user selects 'United States' it will change the state dropdown accordingly. On SUBMIT, USA is automtically selected and the states are also successfully loaded. Brilliant!
However, if the user selects a country which does NOT have any pre-entered 'states', for example Ukraine, the 'stateTextbox' appears and they type in the state.
My problem is that on SUBMIT, it comes up with an error:
Warning: Invalid argument supplied for foreach() in /concrete/core/helpers/form.php on line 341
I understand why the error is happening - the controller is loading in 'Ukraine', but form.php isn't able to find any associated 'states', instead of the 'stateTextbox' loading in...
Is there any way 'round this? I'm so close, yet I feel so far away. It would be brilliant to get this to work properly.
I you can help me out, I'd be really grateful as I've been puzzling over this for weeks now :(
Thanks
Rob
Hi Rob,
Can you show me the code that handles the form submission? Wherever in your code that the error is being thrown.
Thanks
Can you show me the code that handles the form submission? Wherever in your code that the error is being thrown.
Thanks
Hi there, thanks for getting back to me.
I'm not using a 'bespoke' form for my little country/state selector - the entire code on the single page is that above. I do not know how to make a 'bespoke' form to handle just this page :(
The form.php is the default /concrete/core/helpers/form.php and the code referenced in the error message is (line 341).This is the chunk that form.php is referring to:
I don't know if this is any help. I think I have to produce a different version, but I have no idea how to go about it :(
If you can point me in the right direction, I'd be really happy.
Cheers
I'm not using a 'bespoke' form for my little country/state selector - the entire code on the single page is that above. I do not know how to make a 'bespoke' form to handle just this page :(
The form.php is the default /concrete/core/helpers/form.php and the code referenced in the error message is (line 341).This is the chunk that form.php is referring to:
public function select($key, $optionValues, $valueOrArray = false, $miscFields = array()) { $val = $this->getRequestValue($key); if (is_array($val)) { $valueOrArray = $val[0]; } if ((strpos($key, '[]') + 2) == strlen($key)) { $_key = substr($key, 0, strpos($key, '[]')); $id = $_key . $this->selectIndex; } else { $_key = $key; $id = $key; } if (is_array($valueOrArray)) { $miscFields = $valueOrArray; } else {
Viewing 15 lines of 29 lines. View entire code block.
I don't know if this is any help. I think I have to produce a different version, but I have no idea how to go about it :(
If you can point me in the right direction, I'd be really happy.
Cheers
So I unfortunately don't have an environment up to test this yet, so hopefully I didn't mess anything up here... but give this a shot. Replace the view() function in your controller with this:
All this does is make sure that $states is initialized to an empty array if no states are found for the selected country. Because right now i think $states is null and it's trying to iterate over a null.
You're also probably going to want to add some logic to the view to show the textbox instead of the dropdown if the $states array is empty. Let me know if you need help with that.
Let me know if that works.
Thanks!
Blake
public function view(){ $search_country_posted = $_GET["country"]; if (!$search_country_posted){$search_country_posted ='GB';} $this->set('countries', $this->countryHelper->getCountries()); $statesForCountry = $this->stateHelper->getStateProvinceArray($search_country_posted); $this->set('states', empty($statesForCountry) ? array() : $statesForCountry); }
All this does is make sure that $states is initialized to an empty array if no states are found for the selected country. Because right now i think $states is null and it's trying to iterate over a null.
You're also probably going to want to add some logic to the view to show the textbox instead of the dropdown if the $states array is empty. Let me know if you need help with that.
Let me know if that works.
Thanks!
Blake
That's brilliant Blake - the error message is no longer cropping up!
The countries dropdown is behaving on 'submit', but as you pointed out, the states dropdown is reverting to an empty 'select' instead of the textBox. I changed the code on the single page for the stateTextbox to:
so that it populates it with the submitted value,, but it just needs swapping over. Do I need to do something else in the controller to make that happen?
I am so happy that that error message has gone! You are a star mate!
The countries dropdown is behaving on 'submit', but as you pointed out, the states dropdown is reverting to an empty 'select' instead of the textBox. I changed the code on the single page for the stateTextbox to:
<? $stateTextboxValue = $_GET["stateTextbox"] ?> <input type="text" id="stateTextbox" name="stateTextbox" <? if ($stateTextboxValue) {echo 'value="'.$stateTextboxValue.'"';}; ?> style="display:none;" />
so that it populates it with the submitted value,, but it just needs swapping over. Do I need to do something else in the controller to make that happen?
I am so happy that that error message has gone! You are a star mate!
Hey Rob,
Glad that fix worked! Now hiding/showing the dropdown vs. the textbox is just handled through the style="display:none" property.
So we know that if the $states array is empty, it means that there are no states for the currently selected country and instead we want to show the textbox. So in that case, the dropdown should have style="display:none" set, and the textbox should not.
However, if the $states array has values in it, then we want to leave style="display:none" on the textbox, and not on the dropdown.
So here is some code that would do that. Again, this is untested so please forgive me if I made a mistake somewhere. I've simplified things a bit by using the concrete5 html helper to generate the textbox rather than using actual html tags. I just find it a little cleaner/easier.
Hopefully this does the trick. Let me know how it goes.
Blake
Glad that fix worked! Now hiding/showing the dropdown vs. the textbox is just handled through the style="display:none" property.
So we know that if the $states array is empty, it means that there are no states for the currently selected country and instead we want to show the textbox. So in that case, the dropdown should have style="display:none" set, and the textbox should not.
However, if the $states array has values in it, then we want to leave style="display:none" on the textbox, and not on the dropdown.
So here is some code that would do that. Again, this is untested so please forgive me if I made a mistake somewhere. I've simplified things a bit by using the concrete5 html helper to generate the textbox rather than using actual html tags. I just find it a little cleaner/easier.
Hopefully this does the trick. Let me know how it goes.
Blake
Brilliant Blake, it works a treat! Thank you very much for your help - this has been a headache for me for ages!
Just 2 quick questions...
1. Is it possible to re-order the Countries list so that the most popular at at the top ie. United Sates, United Kingdom then the rest ?
2. I'm trying to implement the above code on my homepage. I have made a pagetype with a handle 'homepage.php' and the controller in /controllers/page_types/homepage.php. This works on any page which I apply the page_type design to APART from the homepage. Does the homepage have some sort of issue with another controller being applied to it. I know that the controller works, but it simply does nothing...
Once again, thanks very much for your time and helping me out :)
Rob
Just 2 quick questions...
1. Is it possible to re-order the Countries list so that the most popular at at the top ie. United Sates, United Kingdom then the rest ?
2. I'm trying to implement the above code on my homepage. I have made a pagetype with a handle 'homepage.php' and the controller in /controllers/page_types/homepage.php. This works on any page which I apply the page_type design to APART from the homepage. Does the homepage have some sort of issue with another controller being applied to it. I know that the controller works, but it simply does nothing...
Once again, thanks very much for your time and helping me out :)
Rob
Glad that worked for you!
1. There isn't going to be a super easy way of doing this. In my code, I had the countries dropdown set with 'US' as the default, in this line:
It looks like you changed it to have 'GB' (United Kingdom) as the default.
If that isn't what you want and you want it to be actually reordered you're going to have to do some work. I'm sure there is a much more clever way of doing this, but I've written a basic method that will let you pass in an array of country codes you want to appear at the top of the list, and then all the rest will follow in alphabetical order. So you can add this to your controller and then update your view() method. Here is the method and updated view().
Hopefully that does the trick.
2. I'm honestly not sure what could be going on here. Have you tried clearing the cache? The homepage shouldn't be any different from any other page. If I think of anything else on this I'll let you know.
1. There isn't going to be a super easy way of doing this. In my code, I had the countries dropdown set with 'US' as the default, in this line:
<?php echo $fh->select('country', $countries, 'US'); ?>
It looks like you changed it to have 'GB' (United Kingdom) as the default.
If that isn't what you want and you want it to be actually reordered you're going to have to do some work. I'm sure there is a much more clever way of doing this, but I've written a basic method that will let you pass in an array of country codes you want to appear at the top of the list, and then all the rest will follow in alphabetical order. So you can add this to your controller and then update your view() method. Here is the method and updated view().
protected function getCustomSortedCountries(array $firstCountryCodes) { // array containing all countries $allCountries = $this->countryHelper->getCountries(); $firstCountries = array(); foreach($firstCountryCodes as $countryCode) { $firstCountries[$countryCode] = $allCountries[$countryCode]; } // remove the countries in the first array so they aren't duplicated $allCountries = array_diff_key($allCountries, $firstCountries); // append $allCountries to $firstCountries and return return array_merge($firstCountries, $allCountries); } public function view()
Viewing 15 lines of 23 lines. View entire code block.
Hopefully that does the trick.
2. I'm honestly not sure what could be going on here. Have you tried clearing the cache? The homepage shouldn't be any different from any other page. If I think of anything else on this I'll let you know.
thank you, it solves my problem
Hopefully this bit of code will help you out. It has a dropdown list of the US states and also a textbox. When the country dropdown is changed the javascript checks if the selected value is 'US'. If it is then it makes the state dropdown visible. If it is anything other than 'US' it hides the state dropdown and shows the state textbox.