0

I am new to Laravel and I am trying to update a table of data using an Ajax call. The 'rent' field in the table should be the only field that can be edited, but I have been unable to get the changes to persist to the database as of yet. The error I am receiving at present states that my 'rent' index is undefined, which I don't understand as the current data for the rent field is being displayed in the table - it is only when I try to update this field that the error appears. When using Ajax, the 'rent' field does not appear to be recognised and I receive the error message 'undefined index: 'rent''. When I try to update the table without Ajax the error message I receive is 'SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'rent' cannot be null'. I will include snippets of my code for clarity - any help with this issue, or suggestions of how to better achieve my goal would be greatly appreciated!

Index page (Form for the datatable)

<div class="flex justify-end content-end items-end mt-4">
  <button type="button" class="shadow md:shadow-lg rounded-full mr-4 font-bold px-10 grantors-btn text-white">
    <img class="inline-block mb-2 mt-2 w-4 h-4 mr-2" src="../../img/Icon-plus-white.png" alt="plus icon">
    <a class="no-underline inline-block text-white " onclick="toggleModal('modal-example-small')">New Apparatus Code</a>
  </button>
</div>
<table id="datatable" class="stripe hover dt-responsive display nowrap" style="width:100%; padding-top: 1em;  padding-bottom: 1em;">
      <thead>
        <tr>
          <th>ID</th>
          <th >Apparatus Code</th>
          <th>Description</th>
          <th>Rent</th>
          <th></th>
        </tr> 
      </thead>
<!--start of for loop-->

@foreach ($apparatusCodes as $apparatusCode)

      <tbody>
<form method="POST" action= "{{ route('apparatus_codes.update' , $apparatusCode->id )}}" class="is-readonly" > 
                @csrf
                @method('PUT')


         <tr id="table{{ $apparatusCode->id}}" data-target=".table{{ $apparatusCode->id}}"> 
          <td class="main-bg"> {{ $apparatusCode->id}} </td>
          <td class="main-bg">{{ $apparatusCode->apparatus_code}} </td>  
          <td class="main-bg"> {{ $apparatusCode->description}}</td>
          <td class="data main-bg" id ="rent" name ="rent" value = "{{ $apparatusCode->rent}}">{{ $apparatusCode->rent}}</td>
                        
          <td class="main-bg"> <img class="mb-1 duration-300  h-6 w-6" 
            src="../img/Icon-arrow-dropdown-white.png" data-toggle="collapse" data-target=".table{{ $apparatusCode->id}}" alt="arrow down"/></a>
          </td>
          <td><button type="button" id="edit-button" class="edit"><img class="mb-1 duration-300 ml-4 inset-0 h-6 w-6" src="../img/edit-icon.svg" alt="edit"></button>
          <button id="save-button" class="save"><img class="mb-1 duration-300 ml-4 inset-0 h-6 w-6" src="/../../img/save-icon.svg" alt="save icon"></button>
      </div>
        <div class="row">
            @if ($errors->any()) <span>{{ $errors }}</span> @endif
        </div>
        </td>

      </form>

Index page (Ajax call)

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

    $(document).on("click", "#save-button", function() { 
        var url = "{{ route('apparatus_codes.update' , $apparatusCode->id )}}";
        var rent = $("#rent").val();
        console.log(rent);
        $.ajax({
            url: url,
            type: "POST",
            cache: false,
            data:{ 'rent':rent
                

            },
            success: function(dataResult){
                dataResult = JSON.parse(dataResult);
             if(dataResult.statusCode)
             {
                window.location = "{{ route('apparatus_codes.index' , $apparatusCode->id )}}";
             }
             else{
                 alert("Internal Server Error");
             }
                
            }
        });
    }); 
});

    </script>

Upadate Method in Controller

public function update(ApparatusCodesRequest $request, $id)
    {
    
        $validated = $request->validated();
         // find selected apparatus code details
         $apparatusCodes = ApparatusCodes::find($id);
         $apparatusCodes->rent = $request->input('rent');

        
        //$rent = $_POST['rent'];
         if (empty($rent)) {
           echo "Rent is empty";
         } else {
        echo 'rent is'. $_POST['rent'];
         }

Routes file

Route::post('/apparatus_codes/{id}', [App\Http\Controllers\ApparatusCodesController::class, 'update'] )->name('apparatus_codes.update');
  • "rent index is undefined" as in a JS error or a PHP error? – Dan H Jan 24 '22 at 10:02
  • I believe it is a PHP error, when I printr() the $_POST in the controller it just returns 'Array ()' so for some reason the rent variable is not being picked up – Conlaodh Quinn Jan 24 '22 at 10:07
  • Please share more details, like the error message you are facing (the whole one, not any shorter version!), and your attempts to resolve the problem – Nico Haase Jan 24 '22 at 11:20
  • Also, please check whether this is a JS problem or a PHP problem, and remove the parts that are not relevant from your question – Nico Haase Jan 24 '22 at 11:21
  • Apologies, like I said I am new to Laravel so please have patience with me as I describe my issue - when I use Ajax, the 'rent' field does not appear to be recognised and I receive the error message 'undefined index: 'rent''. When I try to update the table without Ajax the error message I receive is 'SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'rent' cannot be null', so the problem must lie in the rent variable not being picked up - I just do not understand why, thank you – Conlaodh Quinn Jan 24 '22 at 11:31
  • Please add all clarification to your question by editing it. Don't use the comment section for such important information – Nico Haase Jan 24 '22 at 11:40
  • "When using Ajax, the 'rent' field does not appear to be recognised" - what does that mean? Is that value sent properly through the AJAX request? How do you pick it up in your controller? Currently, `$rent` is obviously undefined in the `update` method you've shared – Nico Haase Jan 24 '22 at 11:48
  • As in when I printr($_POST)/ echo $_POST, it returns 'Array()' and '[]' - there appears to be no data in the 'rent' variable, even though when I load the original datatable the values for rent are present – Conlaodh Quinn Jan 24 '22 at 11:53
  • So, what did you try to check for errors? Looks like the AJAX request does not sent that data? – Nico Haase Jan 24 '22 at 12:37
  • Yes that's my question, is there a way to ensure that the 'rent' variable can be recognised and be able to be posted to the controller using ajax? The ajax call appears to work, but the 'rent' field is being considered null, instead of picking up the correct value. – Conlaodh Quinn Jan 24 '22 at 13:55
  • Feel free to add all clarification to your question. Why not check what the request contains? "Appears to work" sounds like you should open your browser's network console to check this further – Nico Haase Jan 24 '22 at 14:01

1 Answers1

0

With Laravel there is no need, and in fact, you should never use $_POST at all. If you are using a framework, let the framework handle and sanitise your input.

public function update(ApparatusCodesRequest $request, $id)
{
     // find selected apparatus code details
     $apparatusCodes = ApparatusCodes::find($id);
     $apparatusCodes->rent = $request->input('rent');
     $apparatusCodes->save();

     // dd($request->input('rent'));
}

Also, the request will already be validated before it even hits your controller. So there is no need to call $validated = $request->validated() either.

By the way, you have an issue in your JS when accessing the value of "rent". Change your JS like so:

// Instead of 
var rent = $("#rent").val();

// Change it for
var rent = $("#rent").text();

.val() should only be used for input fields. Or you could alternatively add an input field to render the value coming from the backend and leave the JS intact. Like so:

<td class="data main-bg">
    <input id="rent" name="rent" type="text" value="{{ $apparatusCode->rent }}" />
</td>
Dan H
  • 3,524
  • 3
  • 35
  • 46
  • Thanks for you answer, I had originally tried the method you are suggesting but received the error message 'SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'rent' cannot be null'. I then attempted to use Ajax to solve the problem, but I think the main issue revolves around the 'rent' variable not being recognised - would you have any suggestions as to how to correct this? Thank you – Conlaodh Quinn Jan 24 '22 at 11:28
  • Your issue is here: {{ $apparatusCode->rent}} You should change your JS to use var rent = $("#rent").text() instead of .val(). .val() should only be used for input fields. – Dan H Jan 24 '22 at 11:30
  • Thanks again, I implemented your suggestion however the printr() still returns 'Array()' so the 'rent' field is still not being recognised unfortunately – Conlaodh Quinn Jan 24 '22 at 11:35
  • Might be easier to just leave the JS as it was and update the HTML as shown in my edited answer. – Dan H Jan 24 '22 at 11:40