web-dev-qa-db-fra.com

Laravel pays et état de la liste déroulante dynamique

J'essaie de créer deux menus déroulants. Ce sont les sélections de pays et d'états de ma base de données. Mon problème est de ne pas savoir comment créer des conditions selon lesquelles les États doivent dépendre des pays. Lorsque je sélectionne [countryname], cela donnera une sélection différente de nom d'états dans ma liste déroulante. Jusqu'ici, voici ce que j'ai fait jusqu'à présent.

AdminController.php

public function user_register()
    {
        $countryname = DB::table('countries')
            ->get();
        $statename = DB::table('states')
            ->get();

        $title = ucwords(Lang::get('constants.user') . ' ' . Lang::get('constants.register')); 
        return View::make('register.user_register')
            ->with('title', $title)
            ->with('page', 'user_register')
            ->with('countryname', $countryname)
            ->with('statename', $statename)
    }

ser_register.blade.php

<select class="form-control" id="countries" name="countries">
    <option value="">Please select</option>
        <?php foreach ($countryname as $key=>$countryname): ?>
        <option value="<?php echo $countryname->sortname; ?>"<?php
         if (isset($countries) && Input::old('countries') == $countryname->sortname) 
         {
             echo 'selected="selected"';
         }
         ?>>
         <?php  echo $countryname->sortname ." - ". $countryname->name  ; ?>
    </option>
    <?php endforeach; ?>
</select>


<select class="form-control" id="states" name="states">
    <option value="">Please select</option>
        <?php foreach ($statename as $key=>$statename): ?>
        <option value="<?php echo $countryname->name; ?>" <?php
        if (isset($states) && Input::old('states') == $statename->name)
        {
            echo 'selected="selected"';
        }
        ?>>
        <?php  echo $statename->name; ?></option>
        <?php endforeach; ?>
</select>

Dans ma base de données

Tableau: pays

+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| country_id| int(11)      | NO   | PRI | NULL    | auto_increment |
| sortname  | varchar(3)   | NO   |     | NULL    |                |
| name      | varchar(150) | NO   |     | NULL    |                |
| phonecode | int(11)      | NO   |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+

Tableau: états

+------------+------------------+------+-----+---------+----------------+
| Field      | Type             | Null | Key | Default | Extra          |
+------------+------------------+------+-----+---------+----------------+
| id         | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name       | varchar(255)     | NO   |     | NULL    |                |
| country_id | int(11)          | NO   |     | NULL    |                |
+------------+------------------+------+-----+---------+----------------+
9
Kevin

Voici comment faire une liste déroulante dynamique dans Laravel:

Vous pouvez voir une démonstration de son fonctionnement ici https://www.dronejobs.co/

Avertissement: je n'ai pas testé cela mais cela devrait fonctionner. N'hésitez pas à commenter et je mettrai à jour ????

app/Http/Contrôleurs/HomeController.php

<?php

namespace App\Http\Controllers;

use App\{Country, State};

class HomeController extends Controller
{
    public function index()
    {
        return view('home', [
            'countries' => Country::all(),
            'states' => State::all(),
        ]);
    }
}

ressources/vues/home.blade.php

<select name="country">
    @foreach ($countries as $country)
        <option value="{{ $country->id }}">{{ $country->name }}</option>
    @endforeach
</select>

<select name=“state”>
    @foreach ($states as $state)
        <option value="{{ $state->id }}">{{ $state->name }}</option>
    @endforeach
</select>

<script>
    $(function() {
        $('select[name=country]').change(function() {

            var url = '{{ url('country') }}' + $(this).val() + '/states/';

            $.get(url, function(data) {
                var select = $('form select[name= state]');

                select.empty();

                $.each(data,function(key, value) {
                    select.append('<option value=' + value.id + '>' + value.name + '</option>');
                });
            });
        });
    });
</script>

app/Country.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Country extends Model
{   
    public function states()
    {
        return $this->hasMany('App\State');
    }

app/State.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

Class State extends Model
{   
    public function country()
    {
        return $this->belongsTo('App\Country');
    }

routes/web.php

Route::get('country/{country}/states', 'CountryController@getStates');

app/Http/Controllers/CountryController.php

<?php

namespace App\Http\Controllers;

use App\Country;

class CountryController extends Controller
{
    public function getStates(Country $country)
    {
        return $country->states()->select('id', 'name')->get();
    }
}
10
tompec

Je voudrais mettre à jour ce message, j'ai déjà résolu mon problème. Je veux juste partager ces solutions pour la communauté :)

Je viens d'ajouter quelques codes ajax pour cela dans mon ser_register.blade.php:

    <div class="form-group">
        <label for="title">Select Country:</label>
        <select name="country" class="form-control">
            <option value="">--- Select country ---</option>
            @foreach ($countries as $key => $value)
                <option value="{{ $value }}">{{ $value }}</option>
            @endforeach
        </select>
    </div>
    <div class="form-group">
        <label for="title">Select state:</label>
        <select name="state" class="form-control">
        </select>
    </div>
    <script type="text/javascript">
    $(document).ready(function() {
    $('select[name="country"]').on('change', function() {
        var countryID = $(this).val();
            if(countryID) {
            $.ajax({
                url: '/admin/user_register/ajax/'+encodeURI(countryID),
                type: "GET",
                dataType: "json",
                success:function(data) {
                $('select[name="state"]').empty();
                $.each(data, function(key, value) {
                    $('select[name="state"]').append('<option value="'+ value +'">'+ value +'</option>');
                    });
                }
            });
            }else{
            $('select[name="state"]').empty();
              }
           });
        });
    </script>

Que j'ai spécifié où obtenir les données en fonction de l'ID du pays et que je transmettrai à mes itinéraires.php:

url: '/admin/user_register/ajax/'+encodeURI(countryID),

Dans mon routes.php:

    //dynamic dropdown country and states
Route::get('/admin/user_register/ajax/{country_id}',array('as'=>'user_register.ajax','uses'=>'AdminController@stateForCountryAjax'));

Enfin, j'ai ajouté quelques codes dans mon AdminController.php quoi faire:

public function stateForCountryAjax($country_name)
{
    $country_name = urldecode($country_name);
    $country_id = $this->_stateCountryIDForCountryName($country_name);
    $states = DB::table("states")
                ->where("country_id",$country_id)
                ->lists('name','id');
    return json_encode($states);
}

private function _stateCountryIDForCountryName($country_name)
{
    return DB::table('countries')->where("name","$country_name")->first()->country_id;
}

Cette méthode fonctionne pour moi. J'ai maintenant pu mettre à jour dynamiquement l'option de liste déroulante (états) en fonction de l'ID du pays.

3
Kevin