Cakephp

Ultimate chained drop down with ajax, jquery and cakephp

Ultimate chained drop down with ajax, jquery and cakephp


Ultimate chained drop down with ajax, jquery and cakephp

There are various variations of drop downs that you want to populate with ajax to make the next selection available.

The first drop down will be an ordinary drop down with an given id
The second will auto populate with ajax., and the third and the fourth.. and so on.

There are various variations, like you can send the values selected to the back end php function in the link or you can post it.
You can send more than one value if you query is expecting more than one value.

Your second or first drop downs can have multiple values

So here below is a few examples of all these options.

First a 'normal' cakephp drop down.

<?php echo $this->Form->input('country_id', ['options' => $countries, 'label' => false, 'empty' => '-- select country --']); ?>

which looks like this in the html

<select name="country_id" id="country-id"><option value="">-- select country --</option><option value="1">USA</option><option value="2">UK</option></select>

Now the javascript that pushes this selected value to the back end php function

<script>
$(document).ready(function() {     
    $('#country-id').change(function(){   //<--- when it changes
    $( "#spinner" ).addClass( "spinner" );    // <--   add the spinner class, to show users the site is doing something
    $.ajax({
         type : "POST",  //<-- you can POST or GET
                url  : ('/cities/getcity/') + $("#country-id option:selected").val(),  //<--- we are going to get the cities
                success : function(opt){
                        document.getElementById('city-id').innerHTML = opt;  // <-- then populate the city drop down
                        $( "#spinner" ).removeClass( "spinner" );    //<-- then remove the spinner class
                    }
            })
            });
 </script>

put this on the page where you want the spinner to appear.

<div id="spinner" class=""></div>

here is the css, you can pick any revolving image of the web
.spinner  {
    background: url('../img/loading.gif');
    background-repeat: no-repeat;
    display: block;
    position: absolute;
    left: 450px;
    z-index: 1000;
    height: 200px;
    width: 200px;
}

now we add the empty drop down value select which we are going to populate the cities to the page.

<select id="city-id" name="cities"></select>

this is the function in the cities controller.

    public function getcity($countryid = null)
    {
    $this->viewBuilder()->layout('ajax'); 
  
     // $this->log('test', 'debug');   //<-- here we can log/test if we get the values
      if(!empty($id)) {  
        $this->loadModel('cities');
       // $this->log($id, 'debug');
        $lists = $this->cities->find();
        $lists->select(['cities.id', 'cities.name'])
            ->distinct(['name']) //<-- if we had the same city more than once we might to use distinct
            ->where(['cities.country_id' => $countryid]);            
              
        $lists = $lists->toArray();        
        $this->set('lists', $lists);           
      }
    } 

the view will look like this.

<option disabled selected value> -- select type of city-- </option>
<?php
if (!empty($lists)) {

    foreach ($lists as $list) {
        echo '<option value="' . $list->id . '">' . h($list->name) . '</option>';  
    }

} else {
    echo '<option value="0">' . __('No Options Available') . '</option>';
}
?>

the javascript function might look like this if we want to to strictly post values, in this case more than one.

<script>
    $('#country-id').change(function(){
    $( "#spinner" ).addClass( "spinner" );
      var continent_id = $("#continent-id option:selected").val();  // <-- previous drop down box as example
      var country_id = $("#country_id option:selected").val() 
    $.ajax({
            url  : ('/cities/getcity/'),
            method : "POST",                                                                                  
            data: { continent_id  : continent_id, country_id : country_id },
            success : function(opt){
              document.getElementById('city-id').innerHTML = opt;
              $( "#spinner" ).removeClass( "spinner" );    
            }
            })
            }); </script>

Example of a multi select and multi out put by ajax

<script>
    $('#continent-ids').change(function(){
    $( "#spinner" ).addClass( "spinner" );
    $('#selectator_country-ids .selectator_chosen_item').remove();  //<-- hide previous selected options
    
     var str='';
        var val=document.getElementById('continent-ids');
        for (i=0;i< val.length;i++) { 
            if(val[i].selected){
                str += val[i].value + ','; 
            }
        }         
        var str=str.slice(0,str.length -1);
                   
    $.ajax({
          type : "POST",
                url  : ('/countries/getallcountryfromcontinents/') + str,
                success : function(opt){
                        document.getElementById('country-ids').innerHTML = opt;
                        $( "#spinner" ).removeClass( "spinner" );
                   }
    })
    });
</script>

the back end php function will look like this

      public function getcountryfromcontinents($ids = null)
    {
      if(!empty($ids)) {  
        $this->loadModel('Continents');   
        $lists = $this->Continents->find('all', ['fields'=>['country_id', 'country'], 'conditions' => ['continent_id IN ('.$ids.')'],'order'=> ['country'=>'ASC'" style="padding:10px;">);
//$this->log($lists , 'debug');
        $this->set('lists', $lists);           
      }
    }

here is the view for this function

<?php 
if (!empty($lists)) { 
    foreach ($lists as $list) {
        echo '<option value="' . $list->country_id . '">' . h($list->country) . '</option>';  
    }      
} else {
    echo '<option value="0">' . __('No Option') . '</option>';
}
?>

Published: 26th May 2019 by Gabriel Kolbe

Adverts