I’m learned to search country use jQuery ajax in CakePHP4 based on my browsing below
https://makitweb.com/how-to-add-select2-in-cakephp-4-and-load-data-using-jquery-ajax/
I’m replaced with Countries table. Here’s below my complete code.
inside \Controller\CoutriesController.php
<?php
declare(strict_types=1);
namespace App\Controller;
/**
* Countries Controller
**/
class CountriesController extends AppController
{
public function index()
{
$countrires = $this->paginate($this->Countries);
$this->set(compact('countries'));
}
//fungsi getCountriyList()
public function getCountryList()
{
//nilai POST
$search = "";
if(isset($this->request->getData()['SearchTerm'])) {
$search = trim($this->request->getData()['SearchTerm']);
}
//kumpulkan countries
$COUNTRIES = $this->getTableLocator()->get('Countries');
$query = $COUNTRIES->find('all');
//nilai pencarian
if(!empty($search)) {
$query->where(['name LIKE' => "%".$search."%"]);
}
$query->order(['name' => 'ASC']);
$query->limit(5);
$countryList = $query->toArray();
$data_arr = array();
foreach($countryList as $country) {
$data_arr[] = array(
'id' => $country['id'],
'name' => $country['name'],
'sortname' => $country['sortname'],
'phonecode' => $country['phonecode']
);
}
echo json_encode($data_arr);
die;
}
}
I’m calling csrfToken inside \template\layout\default.php
<?php
$cakeDescription = 'CakePHP: the rapid development php framework';
?>
<!DOCTYPE html>
<html>
<head>
<?= $this->Html->charset() ?>
<meta name="viewport" content="width=device-width, initial-scale=1">
<?php
echo $this->Html->meta('csrfToken', $this->request->getAttribute('csrfToken'));
?>
<title>
<?= $cakeDescription ?>:
<?= $this->fetch('title') ?>
</title>
<?= $this->Html->meta('icon') ?>
<link href="https://fonts.googleapis.com/css?family=Raleway:400,700" rel="stylesheet">
<?= $this->Html->css(['normalize.min', 'milligram.min', 'cake']) ?>
<?= $this->fetch('meta') ?>
<?= $this->fetch('css') ?>
<?= $this->fetch('script') ?>
<?php
//embed bootstrap
echo $this->Html->css('https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css');
//embed css select
echo $this->Html->css('https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css');
?>
</head>
<body>
<nav class="top-nav">
<div class="top-nav-title">
<a href="<?= $this->Url->build('/') ?>"><span>Cake</span>PHP</a>
</div>
<div class="top-nav-links">
<a target="_blank" rel="noopener" href="https://book.cakephp.org/4/">Documentation</a>
<a target="_blank" rel="noopener" href="https://api.cakephp.org/">API</a>
</div>
</nav>
<main class="main">
<div class="container">
<?= $this->Flash->render() ?>
<?= $this->fetch('content') ?>
</div>
</main>
<footer>
</footer>
<?php
//embed jQuery dari google
echo $this->Html->script('https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js');
//embed select js
echo $this->Html->script('https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js');
?>
</body>
</html>
And then render output inside \templates\Countries\index.php
<html>
<head>
</head>
<body>
<div class="row">
<div class="col-6">
<!-- Country -->
<div class="input" style="margin-bottom:15px;">
<label for="selcountry">Country</label>
<?php
echo $this->Form->select(
'selcountry',[],
[
'id' => 'selcountry',
'empty' => '--Select Country--',
'style' => 'width:250px;'
]
);
?>
</div>
<!-- Select Country ID -->
<?php
echo $this->Form->control('countryid',array(
['id' => 'countryid'],
['label' => 'Selected Country ID'],
['class' => 'form-control']
));
echo $this->Form->button('view', array(
['type' => 'button'],
['id' => 'btnview'],
['value' => 'View Selected Country ID']
));
?>
</div>
</div>
<?php
//embed jQuery dari google
echo $this->Html->script('https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js');
//embed select js
echo $this->Html->script('https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js');
?>
<!-- script -->
<script type="text/javascript">
//baca csrfToken
var csrfToken = $('meta[name="csrfToken"]').attr('content');
$(document).ready(function(){
//selectCountry
$("#selcountry").select2({
ajax: {
url: "<?= $this->Url->build(['controller' => 'CountriesController', 'action' => 'getCountryList']) ?>",
type: "post",
dataType: 'json',
delay: 250,
headers:{
'X-CSRF-Token': csrfToken
},
data: function (params) {
return {
searchTerm: params.term
};
},
processResults: function(response) {
return {
results: response
};
},
cache: true
}
});
//Read selected value
$('#btnview').click(function(){
var countryid = $('#selcountry').val();
$('#countryid').val(countryid);
});
});
</script>
</body>
</html>
why the result comes error, below this
Warning (2) : compact(): Undefined variable $countries [in C:\xampp\htdocs\jqueryload\src\Controller\CountriesController.php, line 23]
Warning (512) : Unable to emit headers. Headers sent in file=C:\xampp\htdocs\jqueryload\vendor\cakephp\cakephp\src\Error\Renderer\HtmlErrorRenderer.php line=36 [in C:\xampp\htdocs\jqueryload\vendor\cakephp\cakephp\src\Http\ResponseEmitter.php, line 71]
Warning (2) : Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\jqueryload\vendor\cakephp\cakephp\src\Error\Renderer\HtmlErrorRenderer.php:36) [in C:\xampp\htdocs\jqueryload\vendor\cakephp\cakephp\src\Http\ResponseEmitter.php, line 168]
Warning (2) : Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\jqueryload\vendor\cakephp\cakephp\src\Error\Renderer\HtmlErrorRenderer.php:36) [in C:\xampp\htdocs\jqueryload\vendor\cakephp\cakephp\src\Http\ResponseEmitter.php, line 197]
Warning (2) : Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\jqueryload\vendor\cakephp\cakephp\src\Error\Renderer\HtmlErrorRenderer.php:36) [in C:\xampp\htdocs\jqueryload\vendor\cakephp\cakephp\src\Http\ResponseEmitter.php, line 197]
Warning (2) : Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\jqueryload\vendor\cakephp\cakephp\src\Error\Renderer\HtmlErrorRenderer.php:36) [in C:\xampp\htdocs\jqueryload\vendor\cakephp\cakephp\src\Http\ResponseEmitter.php, line 236]
I hope someone can help me to fix this, thanx !