How to Load data using jQuery AJAX in Select2 – CodeIgniter 4

How to Load data using jQuery AJAX in Select2 – CodeIgniter 4

 

With the Select2 jQuery plugin, you can customize the default HTML select element.

It allows searching, multiple option selection, loading data using jQuery AJAX, etc.

In this tutorial, I show how you can load MySQL database data remotely using jQuery AJAX in the Select2 plugin in the CodeIgniter 4 project.


 1. Database configuration

  • Open .env file which is available at the project root.

NOTE – If dot (.) not added at the start then rename the file to .env.

  • Remove # from start of database.default.hostname, database.default.database, database.default.username, database.default.password, and database.default.DBDriver.
  • Update the configuration and save it.
database.default.hostname = 127.0.0.1
database.default.database = testdb
database.default.username = root
database.default.password = 
database.default.DBDriver = MySQLi

2. Enable CSRF

  • Again open .env file.
  • Remove # from the start of the app.CSRFProtection, app.CSRFTokenNameapp.CSRFCookieNameapp.CSRFExpire, and app.CSRFRegenerate.
  • I update the app.CSRFTokenName value with 'csrf_hash_name'. With this name read CSRF hash. You can update it with any other value.
  • If you don’t want to regenerate CSRF hash after each AJAX request then set app.CSRFRegenerate = false.
app.CSRFProtection = true
app.CSRFTokenName = 'csrf_hash_name'
app.CSRFCookieName = 'csrf_cookie_name'
app.CSRFExpire = 7200
app.CSRFRegenerate = true
# app.CSRFExcludeURIs = []
  • Open app/Config/Filters.php file.
  • Uncomment in 'csrf' in 'before' if commented.
// Always applied before every request
public $globals = [
    'before' => [
       //'honeypot'
       'csrf',
    ],
    'after' => [
       'toolbar',
       //'honeypot'
    ],
];

3. Create Table

  • Create a new table users using migration.
php spark migrate:create create_users_table
  • Now, navigate to app/Database/Migrations/ folder from the project root.
  • Find a PHP file that ends with create_users_table and open it.
  • Define the table structure in the up() method.
  • Using the down() method delete users table which calls when undoing migration.
<?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

4. Download Select2

  • Download the select2 plugin from here.
  • Extract it in the public/ folder at the root.

5. Model

  • Create Users.php file in app/Models/ folder.
  • Open the file.
  • Specify table name "users" in $table variable, primary key "id" in $primaryKey, Return type "array" in $returnType.
  • In $allowedFields Array specify field names – ['name','email','city'] that can be set during insert and update.

Completed Code

<?php 
namespace App\Models; 
use CodeIgniter\Model;

class Users extends Model { 
   protected $table = 'users'; 
   protected $primaryKey = 'id'; 
   protected $returnType = 'array'; 
   protected $allowedFields = ['name', 'email','city']; 
   protected $useTimestamps = false; 
   protected $validationRules = []; 
   protected $validationMessages = []; 
   protected $skipValidation = false; 
}

6. Route

  • 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');

7. Controller

  • Create UsersController.php file in app/Controllers/ folder.
  • Open the 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\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);

   }
}

8. View

Create index.php file in app/Views/.

Create a hidden element to store CSRF token name specified in .env file in the name attribute and store CSRF hash in the value attribute.

<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.5.1/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>

9. Run & Output

  • Navigate to the project using Command Prompt if you are on Windows or terminal if you are on Mac or Linux, and
  • Execute “php spark serve” command.
php spark serve
  • Run http://localhost:8080 in the web browser.
Video Player
00:00
00:46

10. 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.



Comments