我试图以 Country-> State-> Municipality 的方式,使一组3个选择框的形式与上述选择框相关。
我关注的是this tutorial,它成功获取了数据并填充了第一个选择框(在本例中为Country)。
问题在于,在该教程中数据位于单个表中,而在我的应用程序中,数据位于多个表中。
我想知道如何在与上述选择框中的所选项目的ID相对应的多个表中获取数据?但是以LARAVEL的方式吗?
我的HTML(全部基于上面链接的教程):
{{-- Muestra los estados sacados de la base de datos. --}}
<div id="inputs-estado">
<div class="form-group">
{{-- Estados --}}
<label for="">Estado</label>
<select name="state" id="state" class="form-control dynamic" data-dependant="state">
@foreach ($estados as $estado)
<option value="{{ $estado->state }}">{{ $estado->state }}</option>
@endforeach
</select>
<br>
{{-- Municipio/Delegación --}}
<label for="">Ciudad</label>
<select name="state" id="state" class="form-control dynamic" data-dependant="city">
<option value="">Selecciona la ciudad</option>
</select>
<br>
{{-- Colonia --}}
<label for="">Municipo</label>
<select name="state" id="state" class="form-control dynamic" data-dependant="municipality">
<option value="">Selecciona el municipio</option>
</select>
</div>
</div>
JS:
formDynamic.change(function () {
if ($(this).val() != '') {
let select = $(this).attr('id');
let value = $(this).val();
let dependent = $(this).data('dependent');
let _token = $('input[name="_token"]').val();
$.ajax({
url: "{{ route('postscontroller.fetch') }}",
method: "POST",
data: {
select: select,
value: value,
_token: _token,
dependent: dependent
},
success: function (result) {
$('#' + dependent).html(result);
}
})
}
});
控制器:
public function create()
{
// Toma los estados de la base de datos.
$estados = DB::connection('db_postalcodes')
->table('state')
->groupBy('state')
->get();
// El with hace que se adjunten variables al view.
return view('admin.posts.create')->with('estados', $estados);
}
public function fetch(Request $request)
{
$state_id = DB::connection('db_postalcodes')->table('city')->get();
$select = $request->get('select');
$value = $request->get('value');
$dependent = $request->get('dependent');
$data = DB::connection('db_postalcodes')
->table('city')
->where($select, $state_id->state_id)
->groupBy($dependent)
->get();
$output = '<option value="">Select '.ucfirst($dependent).'</option>';
foreach($data as $row){
$output .= '<option value="'.$row->$dependent.'">'.$row->$dependent.'</option>';
}
echo $output;
}
Routes.php
Route::group(['prefix' => 'admin', 'namespace' => 'Admin', 'middleware' => 'auth'], function () {
Route::get('/', 'AdminController@index')->name('admin');
Route::get('posts', 'PostsController@index')->name('admin.posts.index');
Route::get('posts/create', 'PostsController@create')->name('admin.posts.create');
Route::post('posts/create', 'PostsController@fetch')->name('postscontroller.fetch');
Route::post('posts', 'PostsController@store')->name('admin.posts.store');
});
我的桌子:
答案 0 :(得分:1)
Laravel的模型和关系在这里可以提供很大帮助。特别是hasManyThrough
。请查看Docs,以获取更多详细说明。
您将需要三个模型:国家/地区,州和城市。您可以使用工匠通过php artisan make:model modelName
进行制作,也可以在您的项目中手动创建它们。无论哪种方式,它都应如下所示:
国家型号
use Illuminate\Database\Eloquent\Model;
class Country extends Model {
// A Country can have many Municipalities but they do not directly belong
// to the Country they belong to the State -- Which belongs to the Country
public function municipalities() {
return $this->hasManyThrough('App\Municipality', 'App\State');
}
// Each Country can have many States
public function states() {
return $this->hasMany('App\State');
}
}
状态模型
use Illuminate\Database\Eloquent\Model;
class State extends Model {
// Assuming each State can only belong to One Country
public function country() {
return $this->belongsTo('App\Country');
}
// Each State can have many Municipalities
public function municipalities() {
return $this->hasMany('App\Municipalities');
}
}
市政模型
use Illuminate\Database\Eloquent\Model;
class Municipality extends Model {
// Assuming each Municipality can belong to only one State
public function state() {
return $this->belongsTo('App\State');
}
// Should you ever need this Municipality's Country
public function country() {
return $this->state->country;
}
}
所有这些工作都基于您具有类似于以下内容的表结构:
国家/地区:
| id | name | another_column |
-----------------------------
1 | USA |
状态:
| id | country_id | name | another_col |
----------------------------------------
1 | 1 | OK |
市镇
| id | state_id | postalcode_id | name | another_col |
------------------------------------------------------
1 | 1 | 1 | OKC |
邮政编码:
| id | state_id | postal_code |
-------------------------------
1 | 1 | 73102 |
对于控制器,您可以将其分为3个端点:getCountries
,getStatesByCountry
,getCitiesByState
-每个端点都基于传递给它的ID来获取数据。
public function getCountries(Request $request) {
$id = $request->get('id');
if ( $id ) {
// Or return some string you want to return
return response()->json(Country::find($id));
}
$countries = Country::all();
// or loop over all $countries and make a string
return response()->json($countries);
}
public function getStatesByCountry(Request $request) {
$id = $request->get('country_id');
return response()->json(Country::find($id)->states);
// Or
// return response()->json(State::where('country_id', '=', $id)->get());
}
public function getCitiesByState(Request $request) {
$id = $request->get('state_id');
return response()->json(State::find($id)->municipalities);
// or return response()->json(Municipality::where('state_id', '=', $id)->get());
}
每次更改动态选项之一时,您都要求降低一级。因此,如果您更改国家/地区,则将请求getStatesByCountry
-如果州/州更改,则将请求getCitiesByState
。
最后,如果您想按国家/地区访问所有城市
public function getCitiesByCountry(Request $request) {
$id = $request->get('country_id');
return response()->json(Country::find($id)->municipalities);
}
您将把每个这些功能放在控制器中以处理请求。您还需要更新路由web.php
,并为每个函数添加路由和处理程序。
// {id?} signifies an optional parameter. Based on the func. passing
// no ID gets all Countries - specifying one only gets the one.
Route::get('/posts/get-countries/{id?}', 'PostController@getCountries');
Route::get('/posts/get-states-by-country/{id}', 'PostController@getStatesByCountry');
Route::get('/posts/get-cities-by-state/{id}', 'PostController@getCitiesByState');