I'm trying to create a chained select dropdown list in CakePHP 4. I've search several forum and found few solution and it is found that they are work with previous CakePHP version. I've follow the codes from CakePHP 4 Sandbox which is good sample project. However, when i request the chained selected value, it shows error "An error occurred: undefined".
My database tables:
- countries [id,name]
- states [id,name]
- locations [id,country_id, state_id]
I've bake the code and all relationship works very well. Then I've modified the following codes:
Download Ajax Plugin and enable it.
Create the public function chainedDropdowns and countryStates as follows:
public function chainedDropdowns()
{
$location = $this->Locations->newEmptyEntity();
if ($this->request->is('post')) {
$location = $this->Locations->patchEntity($location, $this->request->getData());
if ($this->Locations->save($location)) {
$this->Flash->success(__('The location has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('The location could not be saved. Please, try again.'));
}
$countries = $this->Locations->Countries->find('list', ['limit' => 200]);
$states = $this->Locations->States->find('list', ['limit' => 200]);
$this->set(compact('location', 'countries', 'states'));
}
public function countryStates() {
$this->request->allowMethod('ajax');
$id = (int)$this->request->getQuery('id');
if (!$id) {
throw new NotFoundException();
}
$this->viewBuilder()->setClassName('Ajax.Ajax');
$this->loadModel('States');
$states = $this->States->getListByCountry($id);
$this->set(compact('states'));
}
- Create chaindropdown page at ...localhost\cake4\templates\Locations\chained_dropdowns.php
<?php
use Cake\Core\Configure;
?>
<div class="page index col-sm-8 col-xs-12">
<?= $this->Form->create($location) ?>
<fieldset>
<legend><?php echo __('Countries and States');?></legend>
<?php
$url = $this->Url->build(['controller' => 'locations', 'action' => 'countryStates', '_ext' => 'json']);
$empty = $states ? Configure::read('Select.defaultBefore') . __('pleaseSelect') . Configure::read('Select.defaultAfter') : ['0' => Configure::read('Select.naBefore') . __('noOptionAvailable') . Configure::read('Select.naAfter')];
echo $this->Form->control('country_id', ['id' => 'countries', 'rel' => $url]);
echo $this->Form->control('state_id', ['id' => 'states', 'empty' => $empty]);
?>
</fieldset>
<?php echo $this->Form->submit(__('Submit'));
echo $this->Form->end();?>
</div>
<?php $this->append('script'); ?>
<script>
$(function() {
$('#countries').change(function() {
var selectedValue = $(this).val();
var targeturl = $(this).attr('rel') + '?id=' + selectedValue;
$.ajax({
type: 'get',
url: targeturl,
beforeSend: function(xhr) {
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
},
success: function(response) {
if (response.content) {
$('#states').html(response.content);
}
},
error: function(e) {
alert("An error occurred: " + e.responseText.message);
console.log(e);
}
});
});
});
</script>
<?php $this->end();
- Create country_states at ...localhost\cake4\templates\Locations\ajax\country_states.php
<?php
use Cake\Core\Configure;
if ($states) {
echo '<option value="">' . Configure::read('Select.defaultBefore') . __('pleaseSelect') . Configure::read('Select.defaultAfter') . '</option>';
foreach ($states as $k => $v) {
echo '<option value="' . $k . '">' . h($v) . '</option>';
}
} else {
echo '<option value="0">' . Configure::read('Select.naBefore') . __('noOptionAvailable') . Configure::read('Select.naAfter') . '</option>';
}
When selecting the country, eg: Thailand, the states will list Bangkok, Krabi, Phuket. However, it produce error: localhost says: An error occurred: undefined.
The browser console shows error: toolbar.js?1589525179:91 GET http://localhost/cake4/locations/country-states.json?id=2 500 (Internal Server Error)
Apache access log shows:
::1 - - [22/Jun/2020:12:25:49 +0800] "GET /myCake4/locations/country-states.json?id=2 HTTP/1.1" 500 281 "http://localhost/cake4/locations/chained-dropdowns" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36"
How can i solve this problem. Thanks for your help.