Dropdown populated by array of countries

Question

As the title reads I have an issue with a drop down that I made. It contains a list of countries to which a store is able to ship. It can create a shipping region, give it a name and then select all the countries that fall under that region. to then add a price to it.

During checkout I want to get that list of countries given by the webstore and use that so that the customer can select where he lives. The options for the country are the ones the store ships its products too. However I have ran into some issues.

The main problem is that the way it was constructed is that one selects a region which will do a reload of the page with the extra parameter in the URL which will add the shipping region to the order about to be created. This causes an issue on my drop down. As it will always pick the bottom option of the drop down instead of the one I just selected, which means I can't set the country the person lives in properly.

so if dropdown is

USA
China

and I select USA the page will reload and china will be hovered

My code:

Dropdown html

{% for shippingRegion in store.getShippingRegions %}
    <a style="display: none" id="addShippingRegion{{shippingRegion.id}}" href="{{ path('checkout', {'store_id': store.id, 'shippingRegion': shippingRegion.id}) }}"></a>
{% endfor %}

 <div class="collection">
     <select onchange="shippingRegionSelectCheck(this)" class="browser-default" id="shippingRegion" name="ShippingRegion">
           <option selected disabled>Select a shipping region</option>
              {% for key,country  in regionCountries %}
                  {% for c in country %}  = 
                    <option id="countrySelect" data-id="{{key}}" selected value="{{c}}" >{{c}}</option>   
                  {% endfor %}
             {% endfor %}
      </select>
</div> 

Javascript function reloading the page

function shippingRegionSelectCheck(regionSelect){
    if(regionSelect){
         var selected = $('#shippingRegion').find('option:selected');
         var extra = selected.data('id'); 
         var country = $('#shippingRegion').val('value');
         var href = $('#addShippingRegion' + extra).attr('href');

         window.location.href = href; 
    }

}

Entity

/**
 * @ORM\Entity
 * @ORM\Table(name="Shipping_Regions")
 */
class ShippingRegion{
    public function __construct() {
        $this->shipping_weight_prices = new ArrayCollection();
        $this->shipping_amount_prices = new ArrayCollection();
    }

    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(type="string", length=100, nullable=true)
     */
    protected $name;

    /**
     * @ORM\Column(type="boolean", nullable=true)
     */
    protected $regionType;

    /**
     * @ORM\Column(type="array", nullable=true)
     */
    protected $regionCountry;

Show source
| php   | jquery   | symfony2   | twig   2017-01-03 14:01 2 Answers

Answers ( 2 )

  1. 2017-01-03 17:01

    Perhaps it's because you have 'selected' written in each option, so the browser selects the last one.

    <option id="countrySelect" data-id="{{key}}" {{ c == selected_country ? 'selected' }} value="{{c}}" >{{c}}</option>
    
  2. 2017-01-06 13:01

    So reason that I got stuck was partially due to my own mess up. What I did to fix it was give the countries their own ID, so that could be used in the HTML and JS to refresh the data used. Using a nullable paramter named cId to set in the route and use its data. Hope this answer will help others in the future

    /**
         * @Route("/checkout/{store_id}/{shippingRegion}/{cId}", name="checkout", defaults={"shippingRegion" = null, "cId" = null})
         */
        public function showAction($store_id, $shippingRegion, $cId, Request $request)
    

    giving countries their own ID

    foreach ($webstore->getShippingRegions() as $shippingRegions) {
                foreach ($shippingRegions->getRegionCountry() as $key=>$regionCountry) { 
    // key being the ID used for countries
                      $regionCountries[$shippingRegions->getId()][$key] = Intl::getRegionBundle()->getCountryName($regionCountry);
                 }  
        }
    

    the twig of the dropdown:

     {% for key,country  in regionCountries %}
        {% for id,c in country %}
           {% if shippingRegionEntity is defined and shippingRegionEntity is not null and key == shippingRegionEntity.getId and cId is defined  and cId is not null  and cId == id %}
             <option id="countrySelect" data-cId="{{id}}" selected checked data-id="{{key}}" >{{c}}</option>
           {% else %}
             <option id="countrySelect" data-cId="{{id}}" data-id="{{key}}" >{{c}}</option>
           {% endif %}                                      
        {% endfor %}
    {% endfor %}
    

    and finally the JS I used to refresh the page and load the data:

    function shippingRegionSelectCheck(regionSelect){
        if(regionSelect){
             var selected = $('#shippingRegion').find('option:selected');
             var extra = selected.data('id'); 
             var country = selected.attr('data-cId');
    
             var href = $('#addShippingRegion' + extra ).attr('href')+ '/' + country;
             window.location.href = href; 
    
        }
    
    }
    
◀ Go back