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.
CodePudding user response:
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.
CodePudding user response:
What happens if you try the helper function redirect()->route('route.name', 'data' => $data);
instead of using the \Redirect::route()
static method?