Select2 and CodeIgniter 4: A Guide to Loading Data with jQuery AJAX

The functionality of common HTML select elements is improved by the Select2 jQuery plugin. You can quickly look up and choose multiple items from a dropdown list using Select2.

It allows loading data using jQuery AJAX.

This tutorial focuses on integrating the Select2 plugin with CodeIgniter 4 and using jQuery AJAX to load data from a MySQL database. To ensure secure communication, the tutorial also covers how to pass the CSRF token with the AJAX request.

If you’re unfamiliar with enabling CSRF protection, then you can view this tutorial which provides a helpful resource to guide you through the process.

Select2 and CodeIgniter 4: A Guide to Loading Data with jQuery AJAX

 


Contents

  1. Create Table
  2. Download Select2 library
  3. Create a Model
  4. Create Routes
  5. Create a Controller
  6. Create a View
  7. Run & Output
  8. Conclusion

1. Create Table

  • Using migration, generate a new table called users.
php spark migrate:create create_users_table
  • Now, navigate to app/Database/Migrations/ folder from the project root.
  • Locate the PHP file that ends with create_users_table and open it.
  • Within the up() method, specify the structure of the table.
<?php namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class CreateUsersTable extends Migration
{
    public function up() {
       $this->forge->addField([
          'id' => [
              'type' => 'INT',
              'constraint' => 5,
              'unsigned' => true,
              'auto_increment' => true,
          ],
          'name' => [
              'type' => 'VARCHAR',
              'constraint' => '100',
          ],
          'email' => [
              'type' => 'VARCHAR',
              'constraint' => '100',
          ],
          'city' => [
              'type' => 'VARCHAR',
              'constraint' => '100',
          ],
       ]);
       $this->forge->addKey('id', true);
       $this->forge->createTable('users');
    }

    //--------------------------------------------------------------------

    public function down() {
       $this->forge->dropTable('users');
    }
}
  • Run the migration –
php spark migrate

2. Download Select2 Library

Download the select2 plugin from GitHub and extract it in the public/ folder at the root.


3. Create a Model

  • Create Users Model –
php spark make:model Users
  • Open app/Models/Users.php file.
  • In $allowedFields Array specify field names – ['name','email','city'].

Completed Code

<?php

namespace App\Models;

use CodeIgniter\Model;

class Users extends Model
{
     protected $DBGroup = 'default';
     protected $table = 'users';
     protected $primaryKey = 'id';
     protected $useAutoIncrement = true;
     protected $insertID = 0;
     protected $returnType = 'array';
     protected $useSoftDeletes = false;
     protected $protectFields = true;
     protected $allowedFields = ['name', 'email','city'];

     // Dates
     protected $useTimestamps = false;
     protected $dateFormat = 'datetime';
     protected $createdField = 'created_at';
     protected $updatedField = 'updated_at';
     protected $deletedField = 'deleted_at';

     // Validation
     protected $validationRules = [];
     protected $validationMessages = [];
     protected $skipValidation = false;
     protected $cleanValidationRules = true;

     // Callbacks
     protected $allowCallbacks = true;
     protected $beforeInsert = [];
     protected $afterInsert = [];
     protected $beforeUpdate = [];
     protected $afterUpdate = [];
     protected $beforeFind = [];
     protected $afterFind = [];
     protected $beforeDelete = [];
     protected $afterDelete = [];
}

4. Create Routes

  • Open app/Config/Routes.php file.
  • Define 2 routes –
    • /
    • users/getUsers – It is used to load select2 data.

Completed Code

$routes->get('/', 'UsersController::index');
$routes->post('users/getUsers', 'UsersController::getUsers');

5. Create a Controller

  • Create UsersController Controller –
php spark make:controller UsersController
  • Open app/Controllers/UsersController.php file.
  • Import Users Model.
  • Create 2 methods –
    • index() – Load index view.
    • getUsers() – This method is use to handle select2 AJAX requests.

Read POST values and assign to $postData variable. Create $response Array to store return response. Assign new CSRF token to $response['token'].

If searchTerm is not POST then fetch 5 records from the users table otherwise fetch records from users table where searchTerm exists in the name field.

Loop on the fetched records and initialize $data Array with id and text keys. Assign $user['id'] to 'id' key and $user['name'] to 'text' key.

Assign $data Array to $response['data'].

Return $response Array in JSON format.

Completed Code

<?php
namespace App\Controllers; 
use App\Controllers\BaseController;
use App\Models\Users;

class UsersController extends BaseController{

   public function index(){
       return view('index');
   }

   public function getUsers(){

      $request = service('request');
      $postData = $request->getPost();

      $response = array();

      // Read new token and assign in $response['token']
      $response['token'] = csrf_hash();

      if(!isset($postData['searchTerm'])){
           // Fetch record
           $users = new Users();
           $userlist = $users->select('id,name')
               ->orderBy('name')
               ->findAll(5);
      }else{
           $searchTerm = $postData['searchTerm'];

           // Fetch record
           $users = new Users();
           $userlist = $users->select('id,name')
               ->like('name',$searchTerm)
               ->orderBy('name')
               ->findAll(5);
      } 

      $data = array();
      foreach($userlist as $user){
         $data[] = array(
            "id" => $user['id'],
            "text" => $user['name'],
         );
      }

      $response['data'] = $data;

      return $this->response->setJSON($response);

   }
}

6. Create a View

Create index.php file in app/Views/.

Create a hidden element to store the CSRF token.

<input type="hidden" class="txt_csrfname" name="<?= csrf_token() ?>" value="<?= csrf_hash() ?>" />

Create a <select id='selUser' > element.


Script –

Initialize select2 on #selUser. With 'ajax' option load data. Set url: "<?=site_url('users/getUsers')?>", type: "post", dataType: 'json'.

Read CSRF Token name and hash from the hidden field and assign it to the csrfName and csrfHash.

Pass typed value and CSRF token as data.

Handle AJAX response with processResults. Initialize results with the response.data and also, update CSRF token value – $('.txt_csrfname').val(response.token).

Completed Code

<!doctype html>
<html>
<head>
   <title>How to Load data using jQuery AJAX in Select2 – CodeIgniter 4</title>

   <!-- Select2 CSS -->
   <link rel="stylesheet" type="text/css" href="/select2/dist/css/select2.min.css"/>

   <!-- jQuery -->
   <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

   <!-- Select2 JS -->
   <script type="text/javascript" src="/select2/dist/js/select2.min.js"></script>
</head>
<body>

   <!-- CSRF token --> 
   <input type="hidden" class="txt_csrfname" name="<?= csrf_token() ?>" value="<?= csrf_hash() ?>" />

   <!-- Select Element -->
   <select id='selUser' style='width: 200px;'>
     <option value='0'>-- Select user --</option>
   </select>

   <!-- Script -->
   <script type='text/javascript'>
   $(document).ready(function(){

     // Initialize select2
     $("#selUser").select2({
        ajax: { 
          url: "<?=site_url('users/getUsers')?>",
          type: "post",
          dataType: 'json',
          delay: 250,
          data: function (params) {
             // CSRF Hash
             var csrfName = $('.txt_csrfname').attr('name'); // CSRF Token name
             var csrfHash = $('.txt_csrfname').val(); // CSRF hash

             return {
                searchTerm: params.term, // search term
                [csrfName]: csrfHash // CSRF Token
             };
          },
          processResults: function (response) {
 
             // Update CSRF Token
             $('.txt_csrfname').val(response.token); 

             return {
                results: response.data
             };
          },
          cache: true
        }
     });

   });
   </script>
</body>
</html>

7. Output

View Output


8. Conclusion

If the CSRF token is not enabled in your project then remove the CSRF token code from the controller and view.

I used LIMIT to only fetch 5 records you can update its value or remove it according to your requirement.

If you found this tutorial helpful then don't forget to share.