Imagine that you have a form where the boxes spend one of the other. The common example is a selected city, where you must first choose a country, then the list of cities is updated. How to do it in Laravel?
To be honest, this subject is as old as JQuery, and there are tons of examples online, but as it was one of the most popular questions of our audience, we decided to write our own example in QuickadminPanel.
Step 1. Form code generated
Here is the form generated by QuickadminPanel. We will seize the offices with their cities, and the city depends on the country.
We are mainly interested in the code of the blade of Resources / Views / Admin / Offices / Create.blade.php::
<form action="{{ route("admin.offices.store") }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="form-group">
<label for="country">{{ trans('global.office.fields.country') }}</label>
<select name="country_id" id="country" class="form-control">
@foreach($countries as $id => $country)
<option value="{{ $id }}">
{{ $country }}
</option>
@endforeach
</select>
</div>
<div class="form-group {{ $errors->has('city_id') ? 'has-error' : '' }}">
<label for="city">{{ trans('global.office.fields.city') }}</label>
<select name="city_id" id="city" class="form-control">
<option value="">{{ trans('global.pleaseSelect') }}</option>
</select>
@if($errors->has('city_id'))
<p class="help-block">
{{ $errors->first('city_id') }}
</p>
@endif
</div>
As you can see, we only list the options of the countries, the cities are empty at first.
Here is the code for app / http / controllers / admin / officescontroller.php::
public function create()
{
abort_unless(\Gate::allows('office_create'), 401);
$countries = Country::all()->pluck('name', 'id')->prepend(trans('global.pleaseSelect'), '');
return view('admin.offices.create', compact('countries'));
}
Step 2. Code JQuery for the Ajax call
In our blade Resources / Views / Admin / Offices / Create.blade.php file that we have this:
@extends('layouts.admin')
In this “parent” blade file Resources / views / arrangement / admin.blade.php We have it below:
// ... Loading jQuery from CDN
// ... Some other global JavaScript
@yield('scripts')
</body>
</html>
This means that in each child’s blade file, we can implement @Section (“scripts”) With the personalized JavaScript code. So we will do exactly that in our Offices / Create.Blade.Php down:
@section('scripts')
<script type="text/javascript">
$("#country").change(function(){
$.ajax({
url: "{{ route('admin.cities.get_by_country') }}?country_id=" + $(this).val(),
method: 'GET',
success: function(data) {
$('#city').html(data.html);
}
});
});
</script>
@endsection
Now you see a new Laravel route here: {{Road (‘admin.tités.get_by_country’)}}. The idea here is that it would return the full HTML to select Entrance for us.
Let’s build the answer for this Ajax request:
itineraries / web.php::
Route::get('cities/get_by_country', 'CitiesController@get_by_country')->name('admin.cities.get_by_country');
app / http / controls / admin / cities control.php::
public function get_by_country(Request $request)
{
abort_unless(\Gate::allows('city_access'), 401);
if (!$request->country_id) {
$html="<option value="">".trans('global.pleaseSelect').'</option>';
} else {
$html="";
$cities = City::where('country_id', $request->country_id)->get();
foreach ($cities as $city) {
$html .= '<option value="'.$city->id.'">'.$city->name.'</option>';
}
}
return response()->json(['html' => $html]);
}
That’s it! The response of the Ajax call would fulfill the city drop -down list with a new HTML per country.