Sun's avatar
Level 1

Using Ajax to edit a form

Hello Guys,

I am new to Ajax, have tried different tutorials. So far, I THINK I have a clean one to use, but not able to submit the form to my controller. Could you please help with this? Thank you very much! I am really struggling with this. If I can learn Ajax, I can use it for a lot of things. Amazing function.

View Page

@foreach($wait_customers as $wait_customer)
                <tr>
                    <td style="vertical-align: middle">{{$wait_customer->name}}</td>
                    <td style="vertical-align: middle">{{$wait_customer->phone_number}}</td>
                    <td style="vertical-align: middle">{{$wait_customer->table_size}}</td>
                    <td style="vertical-align: middle">{{$wait_customer->started_at}}</td>
                    <td style="text-align: center;">
                        <button data-toggle="modal" data-target="#editModal" class="edit-modal btn btn-outline-primary" data-id="{{$wait_customer->id}}" data-phone_number="{{$wait_customer->phone_number}}" data-table_num="{{$wait_customer->table_num}}">
                            <i class="fa fa-paper-plane-o" aria-hidden="true"></i> Send Notification</button>
                        <a href="{{action('WaitingListController@cancel', $wait_customer)}}" class="btn btn-outline-warning"><i class="fa fa-ban" aria-hidden="true"></i> Cancel</a>
                    </td>

                    <div id="editModal" class="modal fade" role="dialog" tabindex="-1" aria-hidden="true">
                        <div class="modal-dialog modal-dialog-centered modal-md">
                            <div class="modal-content">
                                <div class="modal-header">
                                    <h5 class="modal-title"></h5>
                                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                                        <span aria-hidden="true">&times;</span>
                                    </button>
                                </div>
                                <div class="modal-body">
                                    <form class="form-horizontal" role="form">
                                        @csrf
                                        <div class="form-group row">
                                            <label for="id_edit" class="col-md-4 col-form-label text-md-right">ID</label>

                                            <div class="col-md-6">
                                                <input id="id_edit" type="text" class="form-control" name="id_edit" disabled>
                                            </div>
                                        </div>
                                        <div class="form-group row">
                                            <label for="phone_number_edit" class="col-md-4 col-form-label text-md-right">Phone Number</label>

                                            <div class="col-md-6">
                                                <input id="phone_number_edit" type="text" class="form-control" name="phone_number_edit" disabled>
                                            </div>
                                        </div>
                                        <div class="form-group row">
                                            <label for="table_num" class="col-md-4 col-form-label text-md-right">Table Number</label>

                                            <div class="col-md-6">
                                                <input id="table_num_edit" type="text" class="form-control{{ $errors->has('table_num') ? ' is-invalid' : '' }}" name="table_num" value="{{ old('table_num') }}" required>

                                                @if ($errors->has('table_num'))
                                                    <span class="invalid-feedback">
                                                        <strong>{{ $errors->first('table_num') }}</strong>
                                                    </span>
                                                @endif
                                            </div>
                                        </div>
                                    </form>
                                    <div class="modal-footer">
                                        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                                        <button type="button" class="btn btn-primary edit" data-dismiss="modal">{{ __('Send') }}</button>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </tr>
            @endforeach 

JavaScript (In the View Page)

$(document).on('click', '.edit-modal', function() {
            $('.modal-title').text('Send Notification');
            $('#id_edit').val($(this).data('id'));
            $('#phone_number_edit').val($(this).data('phone_number'));
            $('#table_num_edit').val($(this).data('table_num'));
            id = $('#id_edit').val();
            $wait_customer = $('#id_edit').val();
            $('#editModal').modal('show');
        });

        $('.modal-footer').on('click', '.edit', function() {
            $.ajax({
                type: 'PUT',
                url: 'waitinglist/' + id + '/alert',
                data: {
                    '_token': $('input[name=_token]').val(),
                    'id': $("#id_edit").val(),
                    'phone_number': $("#phone_number_edit").val(),
                    'table_num': $("#table_num_edit").val()
                }
            });
        });

Web.php

    Route::post('/waitinglist/{waitinglist}/alert', 'WaitingListController@alert')->name('waitinglist.alert');

Controller

public function alert(Request $request, Waitinglist $waitinglist)
    {
        dd($request);
        dd($waitinglist);
    }
0 likes
19 replies
Cronix's avatar

Try making the url absolute instead of relative. Start it with a /.

url: '/waitinglist/' + id + '/alert',

also, the route needs to be PUT since you're using put in the ajax request to update.

Route::put('/waitinglist/{waitinglist}/alert', 'WaitingListController@alert')->name('waitinglist.alert');
Cronix's avatar

Another problem you'll have is with your id attributes. You're creating things in a loop. In HTML, id's need to be unique, with only one per page. You can reuse classes as many times as you want though, but you can't have

<div id="one">a div</div>
<div id="one">another div</div>

there can only be 1 tag on the page with id="one"

If you were to try to get something by the id, like $('#one'), you will get inconsistent results.

Cronix's avatar

You also only need one modal on the page. You're creating them in a loop...

Sun's avatar
Level 1

@Cronix Thank you for the quick reply. I did the changes you mentioned. I tried different options and forgot I put the modal inside of the loop. The problem is still there. Once I open the modal, I can see the data for that row, however, when I click on send (Submit) button. Nothing is happening, I still can't go the alert function in the controller.

View Page

@foreach($wait_customers as $wait_customer)
                <tr>
                    <td style="vertical-align: middle">{{$wait_customer->name}}</td>
                    <td style="vertical-align: middle">{{$wait_customer->phone_number}}</td>
                    <td style="vertical-align: middle">{{$wait_customer->table_size}}</td>
                    <td style="vertical-align: middle">{{$wait_customer->started_at}}</td>
                    <td style="text-align: center;">
                        <button data-toggle="modal" data-target="#editModal" class="edit-modal btn btn-outline-primary" data-id="{{$wait_customer->id}}" data-phone_number="{{$wait_customer->phone_number}}" data-table_num="{{$wait_customer->table_num}}">
                            <i class="fa fa-paper-plane-o" aria-hidden="true"></i> Send Notification</button>
                        <a href="{{action('WaitingListController@cancel', $wait_customer)}}" class="btn btn-outline-warning"><i class="fa fa-ban" aria-hidden="true"></i> Cancel</a>
                    </td>
                </tr>
            @endforeach 

{{--Edit Model--}}
        <div id="editModal" class="modal fade" role="dialog" tabindex="-1" aria-hidden="true">
            <div class="modal-dialog modal-dialog-centered modal-md">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title"></h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">×</span>
                        </button>
                    </div>
                    <div class="modal-body">
                        <form class="form-horizontal" role="form">
                            @csrf
                            <div class="form-group row">
                                <label for="id_edit" class="col-md-4 col-form-label text-md-right">ID</label>

                                <div class="col-md-6">
                                    <input id="id_edit" type="text" class="form-control" name="id_edit" disabled>
                                </div>
                            </div>
                            <div class="form-group row">
                                <label for="phone_number_edit" class="col-md-4 col-form-label text-md-right">Phone Number</label>

                                <div class="col-md-6">
                                    <input id="phone_number_edit" type="text" class="form-control" name="phone_number_edit" disabled>
                                </div>
                            </div>
                            <div class="form-group row">
                                <label for="table_num" class="col-md-4 col-form-label text-md-right">Table Number</label>

                                <div class="col-md-6">
                                    <input id="table_num_edit" type="text" class="form-control{{ $errors->has('table_num') ? ' is-invalid' : '' }}" name="table_num" value="{{ old('table_num') }}" required>

                                    @if ($errors->has('table_num'))
                                        <span class="invalid-feedback">
                                                        <strong>{{ $errors->first('table_num') }}</strong>
                                                    </span>
                                    @endif
                                </div>
                            </div>
                        </form>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                            <button type="button" class="btn btn-primary edit">{{ __('Send') }}</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>

JavaScript (Same View Page)

$(document).on('click', '.edit-modal', function() {
            $('.modal-title').text('Send Notification');
            $('#id_edit').val($(this).data('id'));
            $('#phone_number_edit').val($(this).data('phone_number'));
            $('#table_num_edit').val($(this).data('table_num'));
            id = $('#id_edit').val();
            $wait_customer = $('#id_edit').val();
            $('#editModal').modal('show');
        });

        $('.modal-footer').on('click', '.edit', function() {
            $.ajax({
                type: 'PUT',
                url: '/waitinglist/' + id + '/alert',
                data: {
                    '_token': $('input[name=_token]').val(),
                    'id': $("#id_edit").val(),
                    'phone_number': $("#phone_number_edit").val(),
                    'table_num': $("#table_num_edit").val()
                }
            });
        });

web.php

    Route::put('/waitinglist/{id}/alert', 'WaitingListController@alert')->name('waitinglist.alert');

Controller

public function alert(Request $request, $id)
    {
        dd($request);
    }
Cronix's avatar

And what does your dev tools in the browser tell you for that ajax request? Look on the network tab.

Sun's avatar
Level 1

@Cronix Nothing is showing up in the console. I have two errors but they are from a bootstrap addon, it is not related to this form.

Cronix's avatar

I didn't mention the "console"... the network tab. You'll really want to learn how to use the dev tools in your browser. They are invaluable.

It will show the url it was submitted to, the status of the request, all headers sent, the data sent, the data received, etc. Important stuff while troubleshooting this kind of thing.

jlrdw's avatar

quote

<div id="one">a div</div>
<div id="one">another div</div>

unquote

Pretty please, take some basic tutorials before going overboard with laravel. There are free videos by Jeffrey, youtube videos, etc on

  • Basic html
  • jquery basics
  • jquery ajax basics
  • css
  • Regular javascript

The knowing of id vs class, and when to use which would be covered in many free tutorials.

Back in the 1980's before Windows, google, and a World of information at a click, I had to get Library books to better myself in programming.

With hundreds of free tutorials these days, ????

shadrix's avatar

I'm curious why don't you use Axios? It's soo freaky simple!

Cronix's avatar

Why use axios if you're already using jquery? It's just another library to load that is unnecessary if you're already using jquery. If you're not already using a library that has ajax functionality built into it, I'd agree!

Sun's avatar
Level 1

@Cronix I am using Google Chrome for this. I see something under network in the inspection. It says the message below. I have only used console before, and still confusing. Thank you for your help.

Request URL: http://homestead.test/waitinglist/7/alert
Request Method: PUT
Status Code: 200 OK
Remote Address: 192.168.10.10:80
Referrer Policy: no-referrer-when-downgrade

Am I looking for the right place? I have never

Cronix's avatar

In the network tab, you see the urls that get requested. Click on the one for your ajax call. There should now be different tabs on the right. Look at the "preview" and "response" tab. Preview should show the data being sent, response shows what is being sent back.

You should probably also change this

public function alert(Request $request, $id)
{
        //dd($request);
    return $request->all();
}

and add this to your ajax parameters:

dataType: 'json',
Sun's avatar
Level 1

@Cronix Interesting! Under Headers, I can see my form data below.

_token: 1bYst9oVq9CWWdOs4BfM2CiB7ELBYQ6xyookkjik
id: 7
phone_number: (512) 769-0957
table_num: 6D

For Previews, I am having errors below.

exception:"ErrorException"
file:"/home/vagrant/textapp/app/Http/Controllers/WaitingListController.php"
line:97message:"Creating default object from empty value"

Because I am trying to update the data from the table. The controller is below.

public function alert(Request $request, $id)
    {
        $waitinglist = Waitinglist::find('id');

        $waitinglist->table_num = $request->table_num;

        return $request->all();
}
Sun's avatar
Level 1

@Cronix I shouldn't use Waitinglist::find('id'); I got something in the preview now. I will keep trying. Please don't answer me yet. I am close. Thx.

Cronix's avatar
Cronix
Best Answer
Level 67

Look at your code... You're not retrieving it by the $id, you're using 'id' which doesn't exist...

//$waitinglist = Waitinglist::find('id');
$waitinglist = Waitinglist::find($id);

You'll probably also want to save the changes you make to the model, or it's not really doing anything.

$waitinglist->table_num = $request->table_num;
$watinglist->save();
Sun's avatar
Level 1

@Cronix I got it working, finally. Thank you! However, I have to manually refresh the page to see the changes. I added window.location.reload(); to the submit button, it doesn't always work based on the internet speed. Are there any examples I can check out?

Cronix's avatar

Sure, you're not doing anything to change the page... just submitting data.

Look at the success() event of jquery ajax. That's where you receive the response from the ajax request (if it was successful), and the can manipulate the page.

example (won't do anything for you...just an example)...

success: function(data) {
    console.log(data); // for debugging to see what was returned from the ajax call

    // change a div's contents with "table_num" from the result from the data returned
    $('#someDiv').html('Table #: ' + data.table_num);
}

You don't want to refresh the page or redirect. That defeats the whole point of using ajax.

Sun's avatar
Level 1

@Cronix It's working! I used the preview and response solved the problem! haha. Thank you! I will check on how to pop up a success message after it is done. I don't think that is hard. I will figure it out myself. Thank you for your help today!

Please or to participate in this conversation.