Add function selectList in the controller
<?php
// in the Controller
// ...
public function selectList ($ type_list , $ ref_id = null ){
if ($ type_list == 'provinces ' && $ ref_id != null ){
$ list = $ this ->Provinces ->find ('list ' )
->where (['country_id ' =>$ ref_id ])
->toArray ();
}elseif ($ type_list == 'cities ' && $ ref_id != null ){
$ list = $ this ->Cities ->find ('list ' )
->where (['province_id ' =>$ ref_id ])
->toArray ();
}else {
$ list = [];
}
$ this ->response ->type ('json ' );
$ this ->response ->body (json_encode ($ list ));
return $ this ->response ;
}
// ...
?>
Add to the forms in the Template, the element select_dependent.ctp, and add the following list to be updated in data-child
<?php
// in the Template
// ...
echo $ this ->Form ->control ('country_id ' , array (
'id ' =>'countries ' ,
'empty ' =>'' ,
'options ' =>$ countries ,
'class ' =>'select-dependent ' ,
'data-child ' =>'provinces ' ,
));
echo $ this ->Form ->control ('province_id ' , array (
'id ' =>'provinces ' ,
'empty ' =>'' ,
'class ' =>'select-dependent ' ,
'data-child ' =>'cities ' ,
));
echo $ this ->Form ->control ('city_id ' , array ('empty ' =>'' , 'id ' =>'cities ' ));
// ...
echo $ this ->element ('select_dependent ' ,array (
'url ' => array ('controller ' =>'Users ' , 'action ' =>'selectList ' ),
'selector_class ' =>'select.select-dependent ' ,
'empty ' => '' ,
));
?>
Create the element select_dependent.ctp to handle ajax logic
<?php
// src/Template/Element/select_dependent.ctp
$ empty = (isset ($ empty ) ? $ empty : false );
$ selector_class = (isset ($ selector_class ) ? $ selector_class : 'select.select-dependent ' );
$ loader_text = (isset ($ loader_text ) ? $ loader_text : __ ('Loading... ' ));
?>
<script type="text/javascript">
<?= $ this ->Html ->scriptStart (['block ' => true ]); ?>
$('<?= $ selector_class ; ?> ').change(function(){
var selec_dependent = function($current, url){
var $child = $("#"+$current.data('child'));
$.ajax({
url : url + '/' + $current.data('child') + '/' + $current.val(),
dataType : 'json',
success : function(json) {
$child.empty(); // remove old options
<?php if ($ empty !== false ) echo '$child.append($("<option></option>").attr("value", "").text(" ' .$ empty .'")); ' ; ?>
$.each(json, function(value,key) {
$child.append($("<option></option>")
.attr("value", value).text(key));
});
if (typeof $child.data('child') !== "undefined") {
selec_dependent($child, url);
}
},
beforeSend: function(){
$child.prop('disabled', true);
$child.empty(); // remove old options
$child.append($("<option></option>").attr("value", "").text('<?php echo $ loader_text ;?> '));
},
error : function(xhr, status) {
concole.log(xhr);
concole.log(status);
$child.empty(); // remove old options
},
complete : function(xhr, status) {
$child.prop('disabled', false);
}
});
}
selec_dependent($(this), '<?= $ this ->Url ->build ($ url ) ?> ');
});
<?php echo $ this ->Html ->scriptEnd (); ?>
</script>
I'm trying use this in cakephp 3,5 but doesn't work. Child List are not updated while parents change. Any idea