Dynamic dropdowns using select2, json request and Laravel
Asked Answered
J

2

9

I am trying to get dynamic drop downs working with Laravel and Select2. There are two drop downs; one for companies i.e. "company2" and one for locations that belong to that company i.e. "location2".

For the life of me, I cannot figure out how to make the "company2" drop down fire a event to read that companies locations, if it is changed! What am I doing wrong in the javascript section of this code! (everything else works)

Route

Route::controller('api', 'ApiController');

Controller (ApiController)

public function getLocations($companyId)
{
    return Location::where('company_id', $companyId)->lists('id', 'name');
}

Example output from address "api/locations/7"

{"Yellowstone":"8"}

View (form open/close section omitted)

{!! Form::select('company_id', $companies, null, ['class' => 'company2 form-control']) !!}
{!! Form::select('location_id', $locations, null, ['class' => 'location2 form-control']) !!}

View (Javascript)

<script type="text/javascript">
    $(document).ready(function() {
        $(".company2").select2();
        $(".location2").select2();
    });

$(".company2").select2().on('change', function() {
    var $company2 = $('.company2');
    $.ajax({
        url:"../api/locations/" + $company2.val(),
        type:'GET',
        success:function(data) {
            var $location2 = $(".location2");
            $location2.empty();
            $.each(data, function(value, key) {
                $location2.append($("<option></option>").attr("value", value).text(key));
            }); 
            $location2.select2();
        }
    });
}).trigger('change');
</script>

The view is passed a list of active companies when initialized i.e.

$companies = Company::lists('trading_name', 'id');
Jordonjorey answered 16/5, 2015 at 7:49 Comment(5)
I've not used select2 before but coded this fiddle up after having a quick glance at the docs and it has an example of a way to trigger a function on a change event. jsfiddle.net/oy14tdus - does that help? I'm unsure if you need to move your $('.company2').select2().on('change' ... event/listener into the document ready function - perhaps give it a shotKan
sorry if I'd misunderstood, are you having trouble getting the event to fire or are you having trouble on how to update the values of the location dropdown when the company dropdown has been changed? Also, you don't seem to be passing your ajax event a success function, you need to do something with the data you're receiving - is this what you're missing?Kan
@Kan sorry, yes the change event is firing fine; I need to know how to pass the data from the route to the "location2" dropdownJordonjorey
Give your $.ajax function a third argument success: function(data) { console.log(data)} and you'll see your data when the event is triggered - this is where you should be doing the logic to add the location values to the drop down. I'll try to throw together an exampleKan
Does this do what you want? jsfiddle.net/L8su2/878Kan
K
9

Replace your javascript with the following, you may need to tweak some of it. Please make sure you look through the comments.

var $company2 = $('.company2');
var $location2 = $(".location2");

$company2.select2().on('change', function() {
    $.ajax({
        url:"../api/locations/" + $company2.val(), // if you say $(this) here it will refer to the ajax call not $('.company2')
        type:'GET',
        success:function(data) {
            $location2.empty();
            $.each(data, function(value, key) {
                $location2.append($("<option></option>").attr("value", value).text(key)); // name refers to the objects value when you do you ->lists('name', 'id') in laravel
            });
            $location2.select2(); //reload the list and select the first option
        }
    });
}).trigger('change');

Change the following when you grab the location data from the controller

public function getLocations($companyId)
{
    return Location::where('company_id', $companyId)->lists('name', 'id');
}
Kan answered 16/5, 2015 at 9:12 Comment(8)
Cannot seem to get your solution to work? The select2 box can no longer select anything and the variables "company2"/"data" show as undefined?Jordonjorey
Sorry the ajax data should be empty as you're passing the parameter in the url - see update, accidentally included it when copy pasting from the fiddle. But that shouldn't be a major issue. Are you getting any javascript errors? Did you check out this fiddle: jsfiddle.net/L8su2/878 ?Kan
ajax type should also be get, wow sorry for all the things I missed!Kan
When you said "the variables "company2"/"data" show as undefined" you mean $company2 at the beginning of the ajax call? And data in the success function? Did you try updating your controller method as I suggested? Sorry for all the questions just trying to cover all the potential issues that could be causing it not to work!Kan
I edited your code a little... it now works! I have one more question - how do I get it so that the selected value in the "location2" dropdown changes to the first entry in the (newly loaded) list? If a value is not selected, after the new location list is loaded, it is possible to select a location name from the previously selected company! (this is bad!)Jordonjorey
I found a bug in the function - if you select a new company, the location drop down loads successfully, but you are unable to select the first entry in the newly loaded location list - the only way to select the first entry in the location list is by selecting the second entry and then flicking back to the first entry... strange?Jordonjorey
are you okay to take this to chat? Thanks for your edits to the answer, I added in a way to select the first dropdown item.Kan
Let us continue this discussion in chat.Jordonjorey
L
1

you can try this :

$.getJSON("getOptions.php", function (json) {
      $("#inputs").select2({
         data: json,
         width: "180px"
      });
 });

example json output :

    {id:0,text:"Text 1"},
    {id:1,text:"Text 2"},
    {id:2,text:"Text 3"},
    {id:3,text:"Text 4"},
    {id:4,text:"Text 5"}
Lorindalorine answered 5/6, 2015 at 0:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.