Carlos
Carlos

Reputation: 237

Fill select using JQuery

I have the following select html:

<div class="form-group col-lg-6 row">
   {{ Form::select( 'state',array( 0 => '' ),null, array( 'class' => 'form-control', 'data-placeholder' => 'State','id' => 'state' ) ) }}
</div>

or

<select class="form-control" id="state" data-placeholder="Selecione">
</select>

I want populate with Bootstrap + Chosen using the following code in JQuery:

$(document).ready( function () {
            var token = $('#token').val();
            var estados = $('#state');

            $.ajax({
                url : './estados',
                dataType : 'json',
                type : 'post',
                data : {
                    _token : token
                },
                success : function ( data ) {

                    estados.find('option').remove();
                    estados.append( $('<option>').val( 0 ).text( '' ));
                    //console.log( data );
                    $.each(data, function (i, j) {
                        console.log( j.sigla+" "+j.descricao );
                        var option  = $('<option>').val( j.sigla ).text( j.descricao ) ;
                        estados.append( option );
                    });
                    estados.trigger('chosen:updated');
                }
            });
        });

But doesn't work. If I look in console.log show the data successfully.

At PHP I can populate, but I want use with laravel.

[EDIT 1]

The result from data is:

AC Acre
AL Alagoas
AP Amapá
AM Amazonas
BA Bahia
CE Ceará
DF Distrito Federal
ES Espírito Santo
GO Goiás
MA Maranhão
MT Mato Grosso
MS Mato Grosso do Sul
MG Minas Gerais
PA Pará
PB Paraíba
PR Paraná
PE Pernambuco
PI Piauí
RJ Rio de Janeiro
RN Rio Grande do Norte
RS Rio Grande do Sul
RO Rondônia
RR Roraima
SC Santa Catarina
SP São Paulo
SE Sergipe
TO Tocantins

enter image description here

Upvotes: 0

Views: 493

Answers (1)

Farrukh Subhani
Farrukh Subhani

Reputation: 2038

I think this would stand as a solution to all laravel based ajax population with select 2. Summary:

  1. Create a route for ajax return value
  2. Create a controller that obtains data from database/enum etc
  3. Return a generic select list item (Model) to a fill in a view
  4. Create a partial view with select Model you can use this with multiple items then.
  5. Create an ajax call to get relevant data
  6. Fill dom with ajax response and apply select2 on it.
  7. Optionally create a refresh method to reload items from database

Here is all the relevant code with explanation.

I would start with a route created in laravel for ajax call so it is defined like this

//DropDowns
Route::group([
'prefix'=>'dropdown',
],function(){
    Route::get('/myObject/{selectedID?}/{terid?}/{sID?}',['as'=>'countryDropdown','uses'=>'Widgets\DropDownsController@myObjects']);
    Route::get('/states/{selectedID?}/{regid?}/{sID?}',['as'=>'stateDropdown','uses'=>'Widgets\DropDownsController@states']);
});

You can have different structure but I prefer to keep dropdowns in one controller as they were only 4/5 and can be reused and remembered easily. Its not a hard rule where they are.

Then you create your controller to send json out.

public function states($selectedID=0,$regid=null,$sID='stateSelect',$sClass='stateSelect',$sName='stateSelect',$optClass='state',$single=true)
{
    $dropdownhelper = new DropDownModel();
    $branches = $dropdownhelper->getStates($regid); //This contains database logic to obtain states etc
    $returnObject = $dropdownhelper->getObjectfromArray($branches, $selectedID, $sID, $sClass, $sName, $optClass);
    //return response()->json($returnObject);
    return view('layouts.twitterbootsrapshared._singleSelect',$returnObject);
}

These methods to obtain states are set in Models for example to get states you can have

// Get states method is like this
public function getStates($countryID = null)
{
    $branches = [];
    try {
        if($countryID==null)
        {
            //Obtain All States
            $states = DB::select('SELECT id,name FROM states ORDER BY name ASC');
        }
        else
        {
            $states = DB::select('SELECT id,name FROM states WHERE country_id = '.$countryID.' ORDER BY name ASC');
        }

    } catch (Exception $e) {
        //Log that we are not able to obtain States
    }
    return $states;
}

I use a dropdown Model to obtain a dropdown object that I would use in view to populate it. This is simple method to take params and convert it to object ready for view.

/// DropdownModel has getObjectfromArray method like this
public function getObjectfromArray($arrayofElements,$selectedID=0,$selectID='',$selectClass='',$selectName='',$optionClass='')
{
    $returnobject = [
        'selectItems'=>$arrayofElements,
        'selectedID'=>$selectedID,
        'selectID'=>$selectID,
        'selectClass'=>$selectClass,
        'selectName'=>$selectName,
        'optionClass'=>$optionClass
    ];
    return $returnobject;
}

My view is a shared view in a twitterbootstrapshared folder under my layouts folder as you can see from controller call that it takes the model there and obtain a view like this

<select id="{{$selectID}}" class="{{$selectClass}}" name="{{$selectName}}">
  @foreach ($selectItems as $option)
    <option class="{{$optionClass}}" data-key="{{$option->id}}" data-name="{{$option->name}}"@if ($selectedID==$option->id) selected="selected" @endif value="{{$option->id}}">{{$option->name}}</option>
  @endforeach
</select>

Next this contains the actual answer to your question when i need to call this dropdown anywhere on client side.

var getStates = function(){
    var selectedID = $('#stateSelect option:selected').data('key');
    if(!selectedID){selectedID=0;}
    // I have another dropdown for selected country first but if you dont have you can ignore this. and pass nothing.
    var selectedCountryID = $('#countrySelect option:selected').data('key');
    if(!selectedCountryID){selectedCountryID=0;}
    // Here i prepare what i need to send to ajax call
    dataToSend={
        'selectedID':selectedID,
        'countryid':selectedCountryID==0?null:selectedCountryID,
        'sID':"stateSelect",
    };
    // This is simple get request to that defined route
    $.get('{{route('stateDropdown')}}',dataToSend,function(data){
            if(data){
                $('.stateContainer').html(data);
                // Once obtained I will call select2 to populate it with data. 
                $('#stateSelect').select2({
                    placeholder:"Select a State",
                    width:'100%',
                });
            }
        });
};
getStates();

My html on the page is like this in case you need to know what ID etc are in there

             <div class="form-group">
                <label class="control-label col-sm-2 font-noraml">States</label>
                <div class=" col-sm-6 statesContainer">
                </div>
                <div class="col-sm-2"><button class="btn btn-sm btn-primary"><i class="fa fa-refresh refreshStates" title="Reload States"></i></button></div>
            </div>

I have given a refresh button next to dropdown so in case it fails user can press refresh to obtain states again. Code for refesh button is this

$('.refreshState').on('click',function(){ getStates(); });

There are some assumptions and naming conventions that I follow but you are independent to do it your way.

Upvotes: 1

Related Questions