Home » Php » php – laravel-> on select change, submit to Controller show

php – laravel-> on select change, submit to Controller show

Posted by: admin July 12, 2020 Leave a comment

Questions:

I must be missing something. I’m trying to get the on submit from a select, to show fields on the selected item.

//the view
{{ Form::open(array('route' => 'user.show', 'name' => "frm_select_client")) }}

        {{Form::select('client_id', array('-1' => 'Please select...') + $usersperclient, null, array('class' => 'selectpicker', 'id' => 'client_id', 'name' => 'client_id', "onchange" => "document.frm_select_client.submit();") );}}

{{ Form::close() }}

//routes.php
Route::resource('user', 'UserController');

I looking for a way to put the URL user/id (user/1901) to then go to UserController::show().
All the examples i’ve been seeing go directly from a link to the show:

<a class="btn btn-small btn-success" href="{{ URL::to('user/' . $value->id) }}">Show this user</a>

I know i could do this in javascript, but i’m looking to do it in the best way, since i’ll be doing this probably a lot. Hope this is clear.
Thx in advance!

EDIT:
I was looking for a way to format the form submit to accomplish the resourceful format, in this case (user/{id} for the show).

How to&Answers:

You have to use JavaScript to fire the select’s change event and you may try this:

var select = document.getElementById('client_id');
select.addEventListener('change', function(){
    this.form.submit();
}, false);

This will submit the form on change event and you may also try this as well:

var select = document.getElementById('client_id');
select.onchange = function(){
    this.form.submit();
};

Using jQuery, you may try this:

$('#client_id').on('change', function(e){
    $(this).closest('form').submit();
});

Or using inline event handling, you may try this (Add this in the attribute’s array):

"onchange" => "this.form.submit()"

Above code will produce something like this:

<select onchange="this.form.submit()">

To generate the url you may use this:

{{ Form::open(array('url' => 'user/' . $user->id, 'name' => "frm_select_client")) }}

Also, you may use route like this (assumed user.show is the route name for url user/{id}):

{{ Form::open(array('route' => array('user.show', $user->id), 'name' => "frm_select_client")) }}

Make sure you pass the $user object to your view when loading the form, using something like this (Basically from a Controller):

public function edit($id)
{
    $user = User::find($id);
    return View::make('userform')->with('user', $user);
}

Update:

Since the user id is being selected dynamically from the select so you have to use JavaScript to set the form action with id and in this case, you may try following approach:

// Add this line before you submit the form
this.form.action = 'user/' + this.value;
// Now submit
this.form.submit();

Or using jQuery you may try this:

$('#client_id').on('change', function(e){
    var select = $(this), form = select.closest('form');
    form.attr('action', 'user/' + select.val());
    form.submit();
});

In this case, keep the form action blank, use a blank string like url => ''.

Answer:

Here’s a pretty easy answer that does not require the form to be submitted.

Route to show the page

Route::get('select', function()
{
    return View::make('select')->with('opts', User::lists('username', 'id'));
});

The lists() function is amazing for setting up options in a select dropdown. It’s just creating a key-value array for us right from the database.

Setting up the form

{{ Form::open() }}
    {{ Form::select('user', $opts, null, array('id' => 'userid')) }}
{{ Form::close() }}

<span id='username'></span>
<span id='email'></span>

Just pass the array we made with the lists() function as the second argument when setting up our dropdown. Also made places to set the username and email just for an example. The third argument would be the default if you wanted to set one, and the 4th is setting the properties of the element. You really just need an id for this example so jQuery can easily grab onto it.

Event handler using jQuery

    $(document).ready(function() {
        $('#userid').on('change', function() {
            var data = {
                'id': $(this).val()
            };
            console.log(data);
            $.post('{{ route("ajax.user_select") }}', data, function(data, textStatus, xhr) {
                /*optional stuff to do after success */
                console.log(data);
                $('#username').html(data.username);
                $('#email').html(data.email);
            });
        });
    });

Using the route() function provided by Laravel makes it very easy to call whatever route you want from javascript. The only downside is you must place this in a blade template file. I usually create a scripts section on my master template just for this. We will set that route up next.

We are using Javascript to set the username and email pages on our view to the value of the selected user.

Route being called by the Javascript event handler

Route::post('select', array('as' => 'ajax.user_select', 'uses' => '[email protected]'));

Very easy here, it’s just saying it is expecting a post and it tells it where to route the post. The name here matches the argument we sent to the route() function in the previous step.

Our function to get the user as was defined in the last step

public function getUser()
{
    return Response::json(User::find(Input::get('id')));
}

Nothing difficult here. Just getting the user we wanted and returning it as a json response.

Note:

This method would allow people to see other user’s hashed password. Even hashed, you probably don’t want to show that information. To hide a piece of information when doing these things, you can add public $hidden = array('password'); to your User model. You could also add other column names from your database as well if you wish for those to remain hidden.