CakePHP Multi-Select Using Select2

Options array could be presented using few methods such as dropdown list, radio button or checkbox. It is depending on number of array and the requirement of the application to use what types of options array. To create a multiple selection, it is recommended to use checkbox array options. Thanks to select2 jQuery script for making the multiple selection more practical and user friendly.

The select2 jQuery (https://select2.org/) gives developer a customizable select box with support for searching, tagging, remote data sets, infinite scrolling, and many other highly used options. To integrate select2 in CakePHP, simply download the jQuery or use CDN from their website.

Below is the list of sample tables 1)documents; 2)groups; 3)document_groups. Documents table store information related to the document and the groups table store information of the document group such as education, history, novel, technology, fiction etc. Each document can be assign to more than one (1) groups. 


1. Define the HABTM relationship in document model at ...app/Model/Document.php as shown below to store and retrieve group data for document. 

public $hasAndBelongsToMany = array(
	'Group' => array(
		'className' => 'Group',
		'joinTable' => 'document_groups',
		'foreignKey' => 'document_id',
		'associationForeignKey' => 'group_id',
		'unique' => 'keepExisting',
		'conditions' => '',
		'fields' => '',
		'order' => '',
		'limit' => '',
		'offset' => '',
		'finderQuery' => '',
	)
);


2. In document controller at ...app/Controller/DocumentsController.php developer need to load model Group as the document is belongs to group (category) and create a find to list all possible category that available in groups table as shown below. The coding should be in public function add() as the group input is in add page. The group-category for document will be stored in document_groups table.

public function add() {
	//Load the Group model & find the category list
	$this->loadModel('Group');
       $this->set('group_id', $this->Group->find('list',array('fields'=>array('id','category'))));
		
	if ($this->request->is('post')) {
		$this->Document->create();
		if ($this->Document->save($this->request->data)) {
			$this->Session->setFlash(__('The document has been saved.'), 'default', array('class' => 'alert alert-success'));
			return $this->redirect(array('action' => 'index'));
		} else {
			$this->Session->setFlash(__('The document could not be saved. Please, try again.'), 'default', array('class' => 'alert alert-danger'));
		}
	}
	//List of category
	$groups = $this->Document->Group->find('list');
	$this->set(compact('groups'));
}


3. Load the select2 CSS and JS as shown below at the top of add page at ...app/View/Documents/add.ctp. The select2 CSS and JS should be stored inside respective folder in webroot. If you use select2 CDN, skip this step.

<?php
	echo $this->Html->css('select2');
	echo $this->Html->script('select2.js');	?>


4. Create a new input for document group category in ...app/View/Documents/add.ctp as shown below 

<?php echo $this->Form->input('Group', array('class' => 'form-control'));?>


At this stage, developer can test the input for group at add page for document and it should display the list of category that has been extracted from groups table. If the array options value is display as ID instead of category, use the public $displayField in ...app/Model/Group.php to change the display field value as shown below:

public $displayField ='category';


The input for the multiple-select array should be render as shown below:


5. To display the Group-category in view page, add the following codes at ...app/View/Documents/view.ctp as shown below. It will retrieve all category that assigned to the document.

<?php foreach($document['Group'] as $groupName):
	echo "<span class='label label-primary'>";
	echo ($groupName['category']);
	echo "</span>&nbsp;"; ?>
<?php endforeach;unset($groupName);?>


The output for the multiple-select array should be render as shown below:


6. For the edit page, refer step 2,3 and 4 to edit the group-category for document.

That all. Happy coding!