Dynamic Combobox with jQuery + Laravel

0

I am on a sign-up screen where there is a combobox of State and Cities.

City must be populated after state is selected.

I have create.blade.php

<div class="form-group">
        {!! Form::label('estado', 'Estado:') !!}
        {!! Form::select('estado', $estados) !!}
    </div>

    <div class="form-group">
        {!! Form::label('cidade', 'Cidade:') !!}
        {!! Form::select('cidade', []) !!}
    </div>

<script type="text/javascript">
    $('select[name=estado]').change(function () {
        var id_estado = $(this).val();

       // $('select[name=cidade]').html('').append('<option value="">  Carregando...  </option>');
        $.get('/cidades/' + id_estado, function (cidades) {
            $('select[name=cidade]').empty();
            $.each(cidades, function (key, value) {
                $('select[name=cidade]').append('<option value=' + value.id_cidade + '>' + value.nome + '</option>');
            });
        });
    });
</script>

And the controller:

class CidadeController extends Controller
{
    private $estadoModel;

    public function __construct(Estado $estado)
    {
        $this->estadoModel = $estado;
    }

    public function index()
    {
        $estados = $this->estadoModel->lists('nome', 'id_estado');

        return view('contas.create', compact('estados'));
    }

    public function getCidades($id_estado)
    {

        $estado = $this->estadoModel->find($id_estado);

        $cidades = $estado->cidades()->getQuery()->get(['id_estado', 'nome']);

        return Response::json($cidades);

    }

But using the laravel debug is doing the wrong query:

select * from 'estados' where 'estados'.'id_estado' = '3' limit 1

select 'id_estado', 'nome' from 'cidades' where 'cidades'.'id_cidade' = '3' and 'cidades'.'id_cidade' is not null

Can anyone help me because you are doing the wrong query?

    
asked by anonymous 10.06.2015 / 16:38

2 answers

0

After commenting on your question, I noticed that your mistake is in the definition of the State relationship with Cities (hasMany).

The function hasMany expects the following parameters:

  • The model (+ namespace)
  • The foreign key (FK) in this model, ie the field that makes the connection from city to state, which in this case is id_estado
  • And the primary key (PK) of the current model, in this case state (not required)

So the correct way to do this relationship would be:

return $this->hasMany('Realito\Cidade','id_estado');

Some points for you to check in your code:

Model state

Definition of the relationship with the model City (hasMany - there are / there are many)

class Estado extends Model
{

    // outros códigos

    public function cidades()
    {
        return $this->hasMany('Realito\Cidade', 'id_estado')
    }

    // outros códigos

}

City model

Definition of the relationship with the model Status (belongsTo - belongs to ...).

class Cidade extends Model
{

    // outros códigos

    public function estado()
    {
        return $this->belongsTo('Realito\Estado', 'id_estado')
    }

    // outros códigos

}

I always advise to define the controller name in Plural, after all, it is a Laravel convention and many other frameworks.

class CidadesController extends Controller
{
    // outros códigos

    public function getCidades($id_estado)
    {
        $estado = $this->estadoModel->findOrFail($id_estado);
        $cidades = $estado->cidades()->lists('nome', 'id');

        // não entendi porque você está selecionando o campo id_estado 
        // ->get(['id_estado', 'nome']);

        return Response::json($cidades);
    }

    // outros códigos
}

The use of findOrFail avoids problems with invalid ids, but this can also be treated in "n" different ways, with a simple if or even a try catch.

As for lists() , it is incredibly easier to use it to return an arrary containing only the id and name / value chosen.

On the plus side, I ask you to validate your code and compare it with mine.

Leave a comment so I can help you if you have any questions.

    
10.06.2015 / 19:02
0

I'm using Laravel 5.0 version

    class Estado extends Model {
    protected $primaryKey = 'id_estado';

    protected $fillable = [

        'nome',
        'regiao',
        'sigla'

    ];

    public $timestamps  = false;

    public function cidades()
    {
        return $this->hasMany('Realito\Cidade','id_cidade');
    }





class Cidade extends Model {

    protected $primaryKey = 'id_cidade';

    protected $fillable = ['id_estado','nome'];



    public function estado()
    {
        return $this->belongsTo('Realito\Estado','id_estado');
    }

}
    
10.06.2015 / 18:47