0

I'm trying to click on a button and load the previous month data onto the screen. Initially it passes the current month and year and the page load works fine. Since the nav button click could be done in any month there it calculates the new month and passes to the same method. But the page load after each button click only returns the response, doesn't display data on screen. Can you please help me to find what causes this issue and sort this out. Here are my code snippets.

jquery

$(".month-nav-left").click(function(e){

    e.preventDefault();

    // currently hard coded - just to check
    var month = 8;
    var year = 2024;
    var monthDir = "mBack";

    $.ajax({
       type:'POST',
       url:"{{ route('monthBack') }}",
       data:{month:month, year:year, monthDir:monthDir},
       success:function(data){
        //   alert(data.success);
        //   console.log(data);
       }
    });

routes

use App\Http\Controllers\CalendarSetupController;
Route::get('/', [CalendarSetupController::class, 'index']);
Route::get('/{year}/{month}', [CalendarSetupController::class, 'monthToDisplay'])->name('selectCalendar');
Route::post('/mback', [CalendarSetupController::class, 'selectMonth'])->name('monthBack');

controller

<?php

 namespace App\Http\Controllers;

 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\View;

class CalendarSetupController extends Controller
{
public function index()
{
    $month = (int)date('m');
    $year = (int)date('Y');

    // This displays data correctly on initial load.
    return \Redirect::route('selectCalendar', [$year, $month]);
}


public function monthToDisplay()
{    
    $year = request()->segment(1);
    $month = request()->segment(2);

    $list=array();

    
    $month=(date("F", mktime(12, 0, 0, $month, 1, $year)));

    return View::make('mainPage', ['date' => $list, 'month' => $month, 'year' => $year]);
}




function selectMonth(Request $request)
{
    $input = $request->all();

    $month = $input["month"];
    $year = $input["year"];


    switch($input["monthDir"])
    {
        case "mBack":
            $month = (int)strftime('%m', strtotime('+1 month', mktime(0, 0, 0, $month, 1, $year)));
            break;
    }

    // This only have the correct view in the response, but does not load on the screen.
    return \Redirect::route('selectCalendar', [$year, $month]);
}

}

Thank you.

3 Answers3

1

monthBack is a web route and all requests that target it will pass throught the VerifyCsrfToken middleware which checks for a valid token.

Since your ajax request includes no valid _token key it will be rejected (unauthorized, You can see the HTTP answer in your live artisan serve log).

If you didn't edit your HTML layout the header will already include a valid token.

<meta name="csrf-token" content="{{ csrf_token() }}" />

Here is how to add that token to your POST request:

$.ajax({
  type: "POST",
  url: "{{ route('monthBack') }}",
  data: {
    month:month, year:year, monthDir:monthDir,
    _token:$('meta[name="csrf-token"]').attr('content')
  },
  success: success,
  dataType: dataType
});

Or add

 headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},

Note that the token stays valid for a limited period of time, if you do not refresh your page for a while the button will not work.

medilies
  • 1,811
  • 1
  • 8
  • 32
  • Thank you @medilies but it didn't work either. I added a javascript redirect to update the link, and it worked. Don't know if it's a best practice or not. I will mention that below. – Sithara Kalpani Feb 19 '22 at 16:29
  • 1
    @SitharaKalpani I don't feel like I can judge if it is best practice of not now. but you may be intrested in https://stackoverflow.com/a/1534662/17873304 – medilies Feb 19 '22 at 18:02
0

I added a line to redirect to the desired url in the javascript code. I am not sure if it's a best practice or not, but it did as expected. Thank you for your time.

 $.ajaxSetup({
     headers: {
         'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
     }
 });

 $(".month-nav-left").click(function(e){

      e.preventDefault();

      // currently hard coded - just to check
      var month = 8;
      var year = 2024;
      var monthDir = "mBack";

      $.ajax({
          type:'POST',
          url:"{{ route('monthBack') }}",
          data:{month:month, year:year, monthDir:monthDir},
          success:function(data){
              //   alert(data.success);
              //   console.log(data);
          }
       });
       window.location.replace("http://127.0.0.1:8000/"+year+"/"+month);

   });
-1

What happens if you try the helper function redirect()->route('route.name', 'data' => $data); instead of using the \Redirect::route() static method?