Laravel Forms: Select Dependent Dropdowns with jQuery and AJAX

Founder of QuickAdminPanel
Imagine you have a form where dropdowns depend on each other. Common example is a city select, where you need to choose a country first, and then cities list is refreshed. How to do it in Laravel?
To be honest, this topic is as old as jQuery, and there are tons of examples online, but since it was one of the most popular questions from our audience, we decided to write our own example within QuickAdminPanel.
Step 1. Generated form code
Here’s the form generated by QuickAdminPanel. We will input offices with their cities, and city depends on country.
We’re mostly interested in Blade code from 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’re listing only the Countries options, cities are empty at first.
Here’s 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. jQuery code for AJAX call
In our Blade resources/views/admin/offices/create.blade.php file we have this:
@extends('layouts.admin')
In that “parent” Blade file resources/views/layouts/admin.blade.php we have this at the bottom:
// ... Loading jQuery from CDN // ... Some other global JavaScript @yield('scripts') </body> </html>
This means that in every child Blade file we can implement @section(‘scripts’) with custom JavaScript code. So we will do exactly that in our offices/create.blade.php at the bottom:
@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: {{ route(‘admin.cities.get_by_country’) }}. The idea here is that would return full HTML for select input to us.
Let’s build the response for this AJAX request:
routes/web.php:
Route::get('cities/get_by_country', 'CitiesController@get_by_country')->name('admin.cities.get_by_country');
app/Http/Controllers/Admin/CitiesController.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! AJAX call response would fill in the city dropdown with new HTML by country.
Try our QuickAdminPanel generator!
19 Comments
Leave a Reply Cancel reply
Recent Posts
Try our QuickAdminPanel Generator!
How it works:
1. Generate panel online
No coding required, you just choose menu items.
2. Download code & install locally
Install with simple "composer install" and "php artisan migrate".
3. Customize anything!
We give all the code, so you can change anything after download.
Can I get this project for dependent drop down
I didn’t save it as separate project, so don’t have it anymore.
Thank You so much for your helpfull post. Its working fine with my laravel project.
It returns unauthorized 401 error…. Whats wrong with me???
comment it
//abort_unless(\Gate::allows(‘office_create’), 401);
thank you very much
After validation redirect, option are empty. have to reselect country again to show option., Help.
How many tables do you have in the database for this example?
Two tables – countries and cities
Nice. Thanks. It helps
It throws 500 error although i put csrf. Why it occurs ?
Missing required parameters for [Route: get_institusi_detail] [URI: get_institusi_detail/{id}]. (View: /home/teknodai/public_html/laravel/resources/views/penerima_pengajians/fields.blade.php)
Got error on this route problem…how could you pass that..?
Hi. Thank you for your example. I would like to ask a little here. I succeeded dropdown ajax according to your code, but the city value cannot be saved in database. It comes out null value. How should I change in this code?
Thank you. But I followed above instructions but its shows me 404 error. Can you tell me what is issue?
I’m having same problem…
After submitting this form if anyone wants to back with the browser back button then would it be selected with previous old data??
if not selected then how to handle that state?
thanks lot!! How do I update this system?
Thank you very much
i have a single table with multiple select options grouped_by i.e. region, objectives
How can i filter each dropdown independently from each other?