Skip to content

Instantly share code, notes, and snippets.

@arodu
Last active April 20, 2019 17:59
Show Gist options
  • Select an option

  • Save arodu/709b71f8c3eb1f134e9160a7c651315f to your computer and use it in GitHub Desktop.

Select an option

Save arodu/709b71f8c3eb1f134e9160a7c651315f to your computer and use it in GitHub Desktop.
Select Dependents CakePHP 3.x

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>
@aedommarp

Copy link
Copy Markdown

I'm trying use this in cakephp 3,5 but doesn't work. Child List are not updated while parents change. Any idea

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment