osherdo's avatar

Getting multiple <select> options

I want to get multiple options user's checking. I need them to query the database (see if the string of the select is matching the same string in the database).

How do I get the results from the jquery code and use it in laravel? Big thanks in advance. Here's my code:

Controller's function:

protected function query(Request $request)
    {
        $user = $request->user();
        $userSelect = $request->get('select_preferences');
    }

And the multi-select in the view:

<div class="second_select col-sm-4">
            <form action="{{ route('search') }}" method="post">
                        <!-- preferences search: -->
                        <select id="select_preferences" multiple="multiple">
                            <option class="options" value="Anaerobic"> Do Anaerobic Routines</option>
                            <option class="options" value="Aerobic">Do Aerobic Routines</option>
                            <option class="options" value="Diet">Diet Healthy</option>
                        </select></form>
                    </div>
0 likes
15 replies
Snapey's avatar

Not really clear what the question is. How is this related to jquery?

1 like
ARCANEDEV's avatar

Can you show us your jquery AJAX POST code ?

So you want to get the $userSelect as an array (selected options), right ??

Try to dd() the $userSelect variable and show us what you've got as data:

protected function query(Request $request)
{
    $user = $request->user();
    $userSelect = $request->get('select_preferences');

    dd($userSelect); // or dd($request->all());
    // ...
}
osherdo's avatar

@Snapey @ARCANEDEV I am using Jquery for returning the chosen options. I also use a jquery's range slider to get the age range from the slider.

So first I want to get the values the user picked (options and age range).

Next - I want to query the db with these results (already have db tables setup fro this)

Code for the jquery's script:

<!-- Script for the multi-select. -->

    <script>
    $(document).ready(function() {

    $('#select_preferences').multiselect({
        buttonText: function(options, select) {
            return 'Look for users that:';
        },
        buttonTitle: function(options, select) {
            var labels = [];
            options.each(function() {
                labels.push($(this).text()); // get the options in a string (with .text method). later it would be joined with - seperated between each.
            });
            $('#range-div,#range-options').toggleClass('hide', labels.length === 0); // hiding both range-div and range-options divs.

             // The class 'hide' hide the content.
             //So I remove it so it would be visible.
             //If the labels array is empty - then do use the hide class to hide the range-selector
            return labels.join(' - ');
 // the options seperated by ' - '
        // This returns the text of th options in labels[].
        }
    });

});
  </script>

<!-- Jquery's range slider script -->
  <script>
  $(function() {
    $( "#range-div" ).slider({
      range: true,
      min: 16,
      max: 120,
      values: [ 16, 45 ],
      slide: function( event, ui ) {
        $( "#amount" ).val( ui.values[ 0 ] + " - " + ui.values[ 1 ] );
      }
    });
    $( "#amount" ).val($( "#range-div" ).slider( "values", 0 ) +
      " - " + $( "#range-div" ).slider( "values", 1 ) );
  });
  </script>

options and age slider html code:

    <div class="second_select col-sm-4">
            <form action="{{ route('multi_search') }}" method="post">
                        <!-- preferences search: -->
                        <select id="select_preferences" multiple="multiple">
                            <option class="options" value="Anaerobic"> Do Anaerobic Routines</option>
                            <option class="options" value="Aerobic">Do Aerobic Routines</option>
                            <option class="options" value="Diet">Diet Healthy</option>
                        </select></form>
                    </div>
                            <!-- html code for age-range selector -->
                
                    <div class="col-sm-3">
                        <div id="range-div" class="hide">
                        </div>
                        <div id="range-options" class="hide-2">
                        <label for="amount">within the ages:</label>
                        <br><br><input id="amount">
                        <a href="#" class="button button-circle button-flat-action">Search</a>
                        </div>
                    </div>
michaelmcmullen's avatar

Since you are not posting the data via Ajax you will need to do a small html change in order to have your select work properly (return multiple).

So even though you have

<select id="select_preferences" multiple="multiple">

That is just not enough, you need to tell the html that it can store those multiple choices, and you can do that by making select_preferences an array

<select id="select_preferences[]" multiple="multiple">

If you do a dd($request->all()); you will see that the select_preferences is now an array of your selected items.

2 likes
ARCANEDEV's avatar

As @michaelmcmullen said, you need to change the select attributes by adding the name attribute instead of changing the id (May break the app).

<select id="select_preferences" name="select_preferences[]" multiple="multiple">
    ...
</select>

Use the id attribute for javascript/Jquery stuff and name attribute for Laravel.

2 likes
osherdo's avatar

@michaelmcmullen thanks for poiting that out for me.

@ARCANEDEV thanks for the fix! I was trying to add [] in the id and it messed the appearance of the multi-select. Really thanks :)

Still when trying to submit the data and dd() - it returns to the same page - even though I have this form-action for the multi-select :

<form action="{{ route('multi_search') }}" method="post">

This is my route for the form:

    Route::post('search_multiple','SearchController@multi_select')->name('multi_search'); // Route for multi-select search.

And the controller part:

protected function multi_select(Request $request)

    {
        $user = $request->user();
        $userSelect = $request->get('select_preferences');
        dd($request->all());
    }
ARCANEDEV's avatar

IMO, use the traditional route :

Route::post('search_multiple', [
    'as'   => 'multi_search',
    'uses' => 'SearchController@postMultiSelect',
]);

The controller method must be public instead of protected:

public function postMultiSelect(Request $request)
{
    dd($request->all());

    $user       = $request->user();
    $userSelect = $request->get('select_preferences');
    // ...
}

Try to change the multi_select to postMultiSelect for the route method and the controller method (name conventions thing).

osherdo's avatar

@ARCANEDEV I did it as you've suggested.

Still won't return the dd() results but return the same page..

Any other suggestion maybe?

syaiful6's avatar

do you forget to add csrf token on this form?

osherdo's avatar

@syaiful6 I have added it now the form. Now this appears at the top of the form:

<form action="{{ route('multi_search') }}" method="post">
                        <!-- preferences search: -->
            <meta name="csrf-token" content="{{ csrf_token() }}">
ARCANEDEV's avatar

This is the correct way:

<form action="{{ route('multi_search') }}" method="post">
    <input type="hidden" name="_token" value="{{ csrf_token() }}">
    <!-- OR -->
    {!! csrf_field() !!}
osherdo's avatar

changed it to {!! csrf_field() !!} I have done as you requested and tried to dd() either $userSelect or dd($request->all());

Still when I click the search button it returns the same page and does not show any information about the variable.

Here's my jquery function for both the multi-select and range-slider:

<!-- Script for the multi-select. -->

    <script>
    $(document).ready(function() {

    $('#select_preferences').multiselect({
        buttonText: function(options, select) {
            return 'Look for users that:';
        },
        buttonTitle: function(options, select) {
            var labels = [];
            options.each(function() {
                labels.push($(this).text()); // get the options in a string (with .text method). later it would be joined with - seperated between each.
            });
            $('#range-div,#range-options').toggleClass('hide', labels.length === 0); // hiding both range-div and range-options divs.

             // The class 'hide' hide the content.
             //So I remove it so it would be visible.
             //If the labels array is empty - then do use the hide class to hide the range-selector
            return labels.join(' - ');
 // the options seperated by ' - '
        // This returns the text of th options in labels[].
        }
    });

});
  </script>

<!-- Jquery's range slider script -->
  <script>
  $(function() {
    $( "#range-div" ).slider({
      range: true,
      min: 16,
      max: 120,
      values: [ 16, 45 ],
      slide: function( event, ui ) {
        $( "#amount" ).val( ui.values[ 0 ] + " - " + ui.values[ 1 ] );
      }
    });
    $( "#amount" ).val($( "#range-div" ).slider( "values", 0 ) +
      " - " + $( "#range-div" ).slider( "values", 1 ) );
  });
  </script>

Thanks for helping!! :)

ARCANEDEV's avatar

Your jquery code is unrelated to your issue.

I think its related to your routes/controller or something else (like validation).

Please or to participate in this conversation.