Динамическая зависимость блоков выбора через Ajax от Laravel, но получение данных через разные таблицы, как? - PullRequest
0 голосов
/ 14 ноября 2018

Я пытаюсь создать группу из 3 полей выбора в форме, которая зависит от приведенной выше, в пути Страна -> Штат -> Муниципалитет .

IЯ следую этому уроку , который успешно извлекает данные и заполняет первое поле выбора (в данном случае Страна).

Дело в том, что в этом уроке данные находятся внутри одногоtable , в то время как в моем приложении оно находится в нескольких таблицах.

Мне интересно как я могу получить данные по нескольким таблицам, которые соответствуют идентификатору выбранного элемента в поле выбора выше?Но способом 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');
});

Мои таблицы:

enter image description here

1 Ответ

0 голосов
/ 14 ноября 2018

Модель и отношения Ларавела могут здесь сильно помочь.Особенно hasManyThrough.Посмотрите Документы для более подробного объяснения.

Вам понадобятся три модели: Страна, Штат и Муниципалитет.Вы можете использовать artisan, чтобы сделать это через 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  |

postal_code:

| id | state_id | postal_code |
-------------------------------
  1  |     1    |   73102     |

Что касается вашего контроллера, вы можете разбить его на 3 конечные точки: getCountries, getStatesByCountry, getCitiesByState - каждая получает данные на основе переданного ему идентификатора.

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');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...