Ứng dụng JQuery Ajax vào Select Box trong Laravel

Giới thiệu

Hello cả nhà, hôm nay mình xin mạn phép đề cập đến một chủ đề trong Laravel đó là làm thế nào để tạo một select box động. Sao lại gọi là động? Mình ví dụ thế này, khi bạn cập nhật thông tin cá nhân, sẽ có rất nhiều ô input cho bạn chọn. Nếu bạn đã chọn countries (đất nước) thì ở ô cities(thành phố) sẽ chỉ hiện những thành phố thuộc đất nước đó. Và nếu cho bạn select tất cả các thành phố trên thế giới thì không biết sẽ phải kéo chuột đến khi nào, cực kì gây bất tiện cho người dùng. Bởi vậy Ajax đã hỗ trợ cho bạn làm việc đó một cách đơn giản, bằng ví dụ dưới đây, mình sẽ chứng minh cho các bạn thấy điều đó.

Example

Bước 1: Tạo một project chạy bằng Laravel

Bạn vào thư mục xampp/htdocs, chạy cmd rồi gõ dòng lệnh sau:

composer create-project --prefer-dist laravel/laravel test

Bước 2: Sau khi tạo thành công, bạn cần vào file .env để config các tham số kết nối với database

DB_HOST=localhost
DB_DATABASE=test
DB_USERNAME=root
DB_PASSWORD=

Ở đây mình sẽ kết nối tới localhost, database mình sử dụng là test và mình truy cập bằng username là root, không có password

Bước 3. Tạo 2 table countries và cities trong database để truy vấn dữ liệu và tạo model, controller để thao tác tới dữ liệu

Bạn không phải tạo bằng tay từng bảng từng cột, mà Laravel đã giúp bạn làm việc đó dễ dàng. Bạn chỉ cần vào cmd gõ 2 dòng lệnh sau:

php artisan make:model Country -mc

Đây là tạo model có tên là Country, đồng thời tạo luôn cả CountryController và file migration create_countries_table Tương tự ta cũng tạo một Model City, controller CityController và file migration create_cities_table chỉ với một dòng lệnh:

php artisan make:model City -mc

Tiếp đến bạn hãy truy cập vào 2 file migration để thêm vào những column cần có trong table:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateCountriesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('countries', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('countries');
    }
}

Ở bên trên mình đã tạo 1 table countries gồm các column: id, name, created_at, updated_at.

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateCitiesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('cities', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->integer('country_id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('cities');
    }
}

Mình cũng vừa tạo một table cities gồm các column: id, name, country_id, created_at, updated_at. Tiếp theo mình lại vào cmd và gõ lệnh để tạo table trong database:

php artisan migrate

Ok vậy là đã hoàn thành xong bước này.

Bước 4. Tạo route

Bạn mở file route/web.php và thêm 2 dòng dưới đây:

Route::get('/form', 'CountryController@showForm');
Route::post('/showCitiesInCountry', 'CityController@showCitiesInCountry']);

Bước 5. Tạo các function showForm() và showCitiesInCountry()

Tạo function showForm() trong CountryController, mục đích là để lấy ra tất cả các countries trong table countries để show ra form

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Country;

class CountryController extends Controller
{
    public function showForm()
    {
    	$countries = Country::all();

    	return view('form', compact('countries'));
    }
}

Tạo function showCitiesInCountry() trong CityController với mục đích là lấy ra những cities theo country mà bạn đã select:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\City;

class CityController extends Controller
{
	public function showCitiesInCountry(Request $request)
	{
		if ($request->ajax()) {
			$cities = City::whereCountryId($request->country_id)->select('id', 'name')->get();

			return response()->json($cities);
		}
	}
}

Đoạn code trên mình đã kiểu tra xem đó có phải dữ liệu nhận từ ajax hay không, sau đó mình query dữ liệu từ table cities theo $request->country_id mà mình nhận được từ server. Để ý là mình sử dụng whereCountryId mới được hỗ trợ từ Laravel 5.4 trở đi, thay vì phải viết câu lệnh: where('country_id', $request->country_id).

Bước 6. Tạo view để show kết quả

<!DOCTYPE html>
<html>
<head>
    <title>Dynamic Dependant Select Box using JQuery Ajax Example</title>
    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
</head>

<body>
<div class="container">
    <h1>Dynamic Dependant Select Box using JQuery Ajax Example</h1>

    <form method="" action="">
        {{ csrf_field() }}
        <div class="form-group">
            <label>Select Country:</label>
            <select class="form-control" name="country">
                <option value="">---</option>
                @foreach($countries as $country)
                    <option value="{{ $country->id }}">{{ $country->name }}</option>
                @endforeach
            </select>
        </div>

        <div class="form-group">
            <label>Select City:</label>
            <select class="form-control" name="city">
            </select>
        </div>

        <div class="form-group">
            <button class="btn btn-success" type="submit">Submit</button>
        </div>
    </form>

</div>

<script type="text/javascript">
    var url = "{{ url('/showCitiesInCountry') }}";
    $("select[name='country']").change(function(){
        var country_id = $(this).val();
        var token = $("input[name='_token']").val();
        $.ajax({
            url: url,
            method: 'POST',
            data: {
                country_id: country_id,
                _token: token
            },
            success: function(data) {
                $("select[name='city'").html('');
                $.each(data, function(key, value){
                    $("select[name='city']").append(
                        "<option value=" + value.id + ">" + value.name + "</option>"
                    );
                });
           }
        $('#city').selectpicker('refresh');});
    });
</script>
</body>
</html>

Ở phần view mình đã tạo 2 ô select cho countries và cities. Các bạn hãy chú ý đến phần ajax load dữ liệu, mình có thể giải thích sơ qua như sau:

  1. url: Đường dẫn xử lý dữ liệu,nó tương tự như thuộc tính action trong form
  2. method: Kiểu gửi dữ liệu, có thể là POST hoặc GET , nó giống với thuộc tính method trong form
  3. data: Tập hợp các biến dữ liệu gửi lên server
  4. success: Hàm chạy khi nhận dữ liệu thành công

Lưu ý: Nếu code của bạn có sử dụng bootstrap-select.js thì phải sử dụng$(‘#city’).selectpicker(‘refresh’);

Có thể sử dụng: $(‘#city’).append thay thế cho $(‘select[name=city]’).append

Vậy là đã xong 1 ví dụ rất đơn giản. Hi vọng các bạn làm theo và thành công! Hẹn gặp lại trong một ngày gần nhất!

Hotline: 0905 063 126
Zalo: 0905.063.126