CodeIgniter 4 AJAX Tutorial
    About Lesson

    To create a basic CRUD (Create, Read, Update, Delete) application with CodeIgniter 4, follow these steps:

     

    Step 1: Database Setup

    CREATE TABLE `customer_info` (
    `id` bigint(20) NOT NULL,
    `name` varchar(100) NOT NULL,
    `email` varchar(255) NOT NULL,
    `address` varchar(255) NOT NULL,
    `mobile_number` varchar(100) DEFAULT NULL,
    `image_url` TEXT NULL,
    `ip_address` varchar(255) NOT NULL,
    `created_at` datetime NOT NULL,
    `updated_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
    `status` varchar(10) NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
    ALTER TABLE `customer_info`
      ADD PRIMARY KEY (`id`);

     

    Step 2: Controller

    Create a controller to handle CRUD operations. Create a new file named Customer.php in the app/Controllers/customer folder.

    <?php
    namespace App\Controllers\customer;

    use App\Controllers\BaseController;

    use App\Models\customer\CustomerModel;
    use App\Models\customer\CustomerDeferModel;

    class Customer extends BaseController {

    public function __construct() {
    $db = db_connect();
    $this->session = \Config\Services::session();

    $this->customer = new CustomerModel($db);
    $this->customerDefer = new CustomerDeferModel($db);

    $this->ip_address = $_SERVER['REMOTE_ADDR'];
    $this->datetime = date("Y-m-d H:i:s");

    }

    public function index() {
    $this->list();
    }

    public function list() {
    $data = [];
    $data ['content_title'] = 'List of Customers';
    echo view('customer/list', $data);
    }

    public function edit() {
    $id = $this->request->getPost('id');
    $result = $this->customer->getEntry(['id' => $id]);
    $html = '';
    if($result) {
    $html = '
    <form id="form-update-customer" method="post" autocomplete="off">
    <input type="hidden" name="id" value="'.$result->id.'"/>
    <div class="modal-header">
    <h5 class="modal-title" id="exampleModalLabel">Update Customer</h5>
    <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">&times;</span>
    </button>
    </div>
    <div class="modal-body">
    <div class="modal-message">
    </div>
    <div class="form-group">
    <label>Name</label>
    <input type="text" class="form-control" id="name" name="name" placeholder="Name" value="'.$result->name.'" required>
    </div>
    <div class="form-group">
    <label>Email</label>
    <input type="email" class="form-control" id="email" name="email" placeholder="Email" value="'.$result->email.'" required>
    </div>
    <div class="form-group">
    <label>Mobile No.</label>
    <input type="text" class="form-control" id="mobile_number" name="mobile_number" value="'.$result->mobile_number.'" placeholder="Mobile No." maxlength="10" required>
    </div>
    <div class="form-group">
    <label>Address</label>
    <input type="text" class="form-control" id="address" name="address" placeholder="Address" value="'.$result->address.'" required>
    </div>
    <div class="form-group">
    <label>File</label>
    <input type="file" class="form-control" id="file" name="file" placeholder="Choose File" accept="image/*">
    <a href="'.base_url($result->image_url).'" target="_blank">Open File</a>
    </div>
    </div>
    <div class="modal-footer">
    <button type="submit" class="btn btn-primary">Update Customer</button>
    </div>
    </form>
    ';
    }
    echo $html;
    }

    public function create() {
    $name = $this->request->getPost('name');
    $email = $this->request->getPost('email');
    $address = $this->request->getPost('address');
    $mobile_number = $this->request->getPost('mobile_number');
    $file = $this->request->getFile('file');

    $where = [
    'email' => $email,
    ];
    $has_account = $this->customer->getEntry($where);
    if($has_account) {
    $json = [
    'status' => false,
    'message' => showDangerMessage("Entered email address is already exists."),
    ];
    } else {
    if($file->isValid()) {
    $path = 'uploads/customers/';
    $image_url = $this->uploadFile($path, $file);
    $data = [
    'name' => $name,
    'email' => $email,
    'address' => $address,
    'mobile_number' => $mobile_number,
    'image_url' => $image_url,
    'ip_address' => $this->ip_address,
    'created_at' => $this->datetime,
    'status' => "1",
    ];
    $result = $this->customer->addEntry($data);
    if($result) {
    $json = [
    'status' => true,
    'message' => showSuccessMessage("New record has been created successfully"),
    ];
    } else {
    $json = [
    'status' => false,
    'message' => showDangerMessage("Something went wrong. Please try again!"),
    ];
    }
    } else {
    $json = [
    'status' => false,
    'message' => showDangerMessage("Please select file."),
    ];
    }
    }
    echo json_encode($json);
    }

    public function update() {
    $id = $this->request->getPost('id');
    $name = $this->request->getPost('name');
    $email = $this->request->getPost('email');
    $address = $this->request->getPost('address');
    $mobile_number = $this->request->getPost('mobile_number');
    $file = $this->request->getFile('file');

    $where = [
    'id !=' => $id,
    'email' => $email,
    ];
    $has_account = $this->customer->getEntry($where);
    if($has_account) {
    $json = [
    'status' => false,
    'message' => showDangerMessage("Entered email address is already exists."),
    ];
    } else {
    if($file->isValid()) {
    $path = 'uploads/customers/';
    $image_url = $this->uploadFile($path, $file);
    $data = [
    'name' => $name,
    'email' => $email,
    'address' => $address,
    'mobile_number' => $mobile_number,
    'image_url' => $image_url,
    'ip_address' => $this->ip_address,
    ];
    } else {
    $data = [
    'name' => $name,
    'email' => $email,
    'address' => $address,
    'mobile_number' => $mobile_number,
    'ip_address' => $this->ip_address,
    ];
    }
    $result = $this->customer->updateEntry(['id' => $id], $data);
    if($result) {
    $json = [
    'status' => true,
    'message' => showSuccessMessage("Selected record has been updated successfully"),
    ];
    } else {
    $json = [
    'status' => false,
    'message' => showDangerMessage("Something went wrong. Please try again!"),
    ];
    }
    }
    echo json_encode($json);
    }

    public function delete() {
    $id = $this->request->getPost('id');
    $result = $this->customer->deleteEntry(["id" => $id]);
    if($result) {
    $json = [
    'message' => showSuccessMessage("The selected record has been deleted successfully."),
    'status' => true,
    ];
    } else {
    $json = [
    'message' => showDangerMessage("Something went wrong. Please try again."),
    'status' => false,
    ];
    }
    echo json_encode($json);
    }

    public function datatable() {
    $postData = $this->request->getPost();
    $i = $this->request->getPost('start');
    $result = $this->customerDefer->getRows($postData);
    $arrayList = $this->getRows($i, $result);
    $output = array(
    "draw" => $this->request->getPost('draw'),
    "recordsTotal" => $this->customerDefer->countAll($this->request->getPost()),
    "recordsFiltered" => $this->customerDefer->countFiltered($this->request->getPost()),
    "data" => $arrayList,
    );
    echo json_encode($output);
    }

    function getRows($i, $result) {
    $arrayList = [];
    foreach($result as $row) {
    $action = ' <button type="button" name="btn-edit" class="btn btn-sm btn-primary" data-id="'.$row->id.'" title="Edit">Edit</button>';
    $action .= ' <button type="button" name="btn-delete" class="btn btn-sm btn-danger" data-id="'.$row->id.'" title="Delete">Delete</button>';
    $arrayList [] = [
    ++$i,
    $row->name,
    $row->email,
    $row->mobile_number,
    $row->address,
    '<a href="'.base_url($row->image_url).'" target="_blank"><img src="'.base_url($row->image_url).'" class="img-thumbnail" width="100px"></a>',
    $action,
    ];
    }
    return $arrayList;
    }

    function uploadFile($path, $image) {
    if (!is_dir($path))
    mkdir($path, 0777, TRUE);

    if ($image->isValid() && ! $image->hasMoved()) {
    $newName = $image->getRandomName();
    $image->move('./'.$path, $newName);
    return $path.$image->getName();
    }
    return false;
    }
    }

     

    Step 3: Model

    Create a model to handle database operations. Create a new file named CustomerModel.php and CustomerDeferModel.php in the app/Models/customer folder.

    CustomerModel.php

    <?php
    namespace App\Models\customer;

    use CodeIgniter\Model;
    use CodeIgniter\Database\ConnectionInterface;

    class CustomerModel extends Model {

    protected $db;
    public function __construct(ConnectionInterface &$db) {
    $this->db =& $db;

    $this->table = 'customer_info';
    }

    public function addEntry($data) {
    $this->db
    ->table($this->table)
    ->insert($data);
    return $this->db->insertID();
    }

    public function updateEntry($where, $data) {
    return $this->db
    ->table($this->table)
    ->where($where)
    ->set($data)
    ->update();
    }

    public function deleteEntry($where) {
    return $this->db
    ->table($this->table)
    ->where($where)
    ->delete();
    }

    public function getEntry($where) {
    return $this->db
    ->table($this->table)
    ->where($where)
    ->get()
    ->getRow();

    }

    public function getEntryList($where = 0) {
    if($where) {
    return $this->db
    ->table($this->table)
    ->where($where)
    ->get()
    ->getResult();
    } else {
    return $this->db
    ->table($this->table)
    ->get()
    ->getResult();
    }
    }

    public function getNumRows($where) {
    return $this->db
    ->table($this->table)
    ->where($where)
    ->get()
    ->getNumRows();
    }
    }
     

     

    Step 4: Create Views

    Create views (list.php) in the app/Views/customer folder for listing, creating, updating, and deleting records.

    list.php

    <!DOCTYPE html>
    <html lang="en">

    <head>
    <title><?php echo $content_title; ?></title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdn.datatables.net/1.13.7/css/jquery.dataTables.min.css"/>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
    <script src="https://cdn.datatables.net/1.13.7/js/jquery.dataTables.min.js"></script>
    </head>

    <body>

    <div class="jumbotron text-center">
    <h1>Welcome to Infovistar.in</h1>
    <p>CRUD Example with AJAX</p>
    </div>
    <div class="container">
    <div class="row">
    <div class="col-sm-12 message">
    </div>
    <div class="col-sm-12">
    <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#modal-add-customer">Add Customer</button>
    </div>
    <div class="col-sm-12 mt-1">
    <div class="table-responsive">
    <table id="table-customer" class="table table-sm table-bordered table-striped table-hover" width="100%">
    <thead>
    <tr>
    <th>#</th>
    <th>Name</th>
    <th>Email</th>
    <th>Mobile</th>
    <th>Address</th>
    <th>Attachment</th>
    <th>Action</th>
    </tr>
    </thead>
    </table>
    </div>
    </div>
    </div>
    </div>

    <div class="modal fade" id="modal-add-customer" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog" role="document">
    <div class="modal-content">
    <form id="form-add-customer" method="post" autocomplete="off" enctype="multipart/form-data">
    <div class="modal-header">
    <h5 class="modal-title" id="exampleModalLabel">Add Customer</h5>
    <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">&times;</span>
    </button>
    </div>
    <div class="modal-body">

    <div class="modal-message">
    </div>
    <div class="form-group">
    <label>Name</label>
    <input type="text" class="form-control" id="name" name="name" placeholder="Name" required>
    </div>
    <div class="form-group">
    <label>Email</label>
    <input type="email" class="form-control" id="email" name="email" placeholder="Email" required>
    </div>
    <div class="form-group">
    <label>Mobile No.</label>
    <input type="text" class="form-control" id="mobile_number" name="mobile_number" placeholder="Mobile No." maxlength="10" required>
    </div>
    <div class="form-group">
    <label>Address</label>
    <input type="text" class="form-control" id="address" name="address" placeholder="Address" required>
    </div>
    <div class="form-group">
    <label>File</label>
    <input type="file" class="form-control" id="file" name="file" placeholder="Choose File" accept="image/*" required>
    </div>
    </div>
    <div class="modal-footer">
    <button type="submit" id="btn-add" class="btn btn-primary">Add Customer</button>
    </div>
    </form>
    </div>
    </div>
    </div>

    <div class="modal fade" id="modal-update-customer" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog" role="document">
    <div class="modal-content">
    <div class="edit-customer"></div>
    </div>
    </div>
    </div>

    <script>
    $(document).ready(function() {
    var table_customer = $("#table-customer").DataTable({
    "processing":true,
    "serverSide":true,
    "order":[],
    "ajax": {
    url : '<?php echo base_url("customer/datatable") ?>',
    type:"POST"
    },
    "columnDefs":[
    {
    "targets":[0],
    "orderable":false,
    },
    ],
    });

    $('#table-customer tbody').on( 'click', 'button', function () {
    let id = $(this).attr('data-id');
    if(this.name == "btn-delete") {
    var isDelete = confirm("Are you sure you want to delete this?");
    if(isDelete) {
    $.post("<?php echo base_url("customer/delete"); ?>", {id: id}, function( result ) {
    $(".message").html(result.message);
    if(result.status) {
    table_customer.ajax.reload();
    }
    }, 'json');
    }
    } if(this.name == "btn-edit") {
    $.post("<?php echo base_url("customer/edit"); ?>", {id: id}, function( result ) {
    $(".edit-customer").html(result);
    $("#modal-update-customer").modal("show");
    });
    }
    });

    $("body").on("submit", "#form-add-customer", function(e) {
    e.preventDefault();
    var data = new FormData(this);
    $.ajax({
    type: 'POST',
    url: "<?php echo base_url('customer/create') ?>",
    data: data,
    dataType: 'json',
    contentType: false,
    cache: false,
    processData:false,
    beforeSend: function() {
    $("#btn-add").prop('disabled', true);
    },
    success: function(result) {
    $("#btn-add").prop('disabled', false);
    if(result.status) {
    $(".message").html(result.message);
    table_customer.ajax.reload();
    $("#form-add-customer")[0].reset();
    $("#modal-add-customer").modal("hide");
    } else {
    $(".modal-message").html(result.message);
    }
    }
    });
    });

    $("body").on("submit", "#form-update-customer", function(e) {
    e.preventDefault();
    var data = new FormData(this);
    $.ajax({
    type: 'POST',
    url: "<?php echo base_url('customer/update') ?>",
    data: data,
    dataType: 'json',
    contentType: false,
    cache: false,
    processData:false,
    beforeSend: function() {
    $("#btn-add").prop('disabled', true);
    },
    success: function(result) {
    $("#btn-add").prop('disabled', false);
    if(result.status) {
    $(".message").html(result.message);
    table_customer.ajax.reload();
    $("#form-update-customer")[0].reset();
    $("#modal-update-customer").modal("hide");
    } else {
    $(".modal-message").html(result.message);
    }
    }
    });
    });
    });
    </script>

    </body>

    </html>

     

    Step 5: Set Up Routes

    Edit the app/config/Routes.php file to define routes for your controller.

    // Customer Routes
    $routes->group('customer', function($routes) {
    $routes->get('/', 'customerCustomer::index');
    $routes->get('list', 'customerCustomer::list');
    $routes->post('datatable', 'customerCustomer::datatable');
    $routes->post('create', 'customerCustomer::create');
    $routes->post('edit', 'customerCustomer::edit');
    $routes->post('update', 'customerCustomer::update');
    $routes->post('delete', 'customerCustomer::delete');
    });

     

    Step 6: BaseController

    <?php
    namespace App\Controllers;

    use CodeIgniter\Controller;
    use CodeIgniter\HTTP\CLIRequest;
    use CodeIgniter\HTTP\IncomingRequest;
    use CodeIgniter\HTTP\RequestInterface;
    use CodeIgniter\HTTP\ResponseInterface;
    use Psr\Log\LoggerInterface;

    /**
    * Class BaseController
    *
    * BaseController provides a convenient place for loading components
    * and performing functions that are needed by all your controllers.
    * Extend this class in any new controllers:
    * class Home extends BaseController
    *
    * For security be sure to declare any new methods as protected or private.
    */
    abstract class BaseController extends Controller
    {
    /**
    * Instance of the main Request object.
    *
    * @var CLIRequest|IncomingRequest
    */
    protected $request;

    /**
    * An array of helpers to be loaded automatically upon
    * class instantiation. These helpers will be available
    * to all other controllers that extend BaseController.
    *
    * @var array
    */
    protected $helpers = [
    'url', 'form', 'array', 'date',
    'message_helper'
    ];

    /**
    * Be sure to declare properties for any property fetch you initialized.
    * The creation of dynamic property is deprecated in PHP 8.2.
    */
    // protected $session;

    /**
    * @return void
    */
    public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
    {
    // Do Not Edit This Line
    parent::initController($request, $response, $logger);

    // Preload any models, libraries, etc, here.

    // E.g.: $this->session = \Config\Services::session();
    }
    }

     

    Step 7: Custom Helpers

    Create a helper (message_helper.php) in the app/Helpers folder.

    <?php

    function showSuccessMessage($message) {
    return '<div class="alert alert-success">
    <strong>Great!</strong> '.$message.'
    </div>';
    }

    function showDangerMessage($message) {
    return '<div class="alert alert-danger">
    <strong>Oops!</strong> '.$message.'
    </div>';
    }

     

    Step 8: Run Project & Output

    CodeIgniter 4 Form Submit with File Upload Infovistar