little bit stuck with redirecting to other page after successful login for quite a long time. I believe that my understanding about sanctum auth is a bottleneck for this issue( Or maybe I am wrong ). However, after reading the docs still couldn't find the answer to my issue. Situation: I have declared few public routes and one private. I have created a user in my database and whenever I try successfully to log in it does not redirect to other page, and my credentials are 110% correct, but anyway after submit it only displays:
Symfony\Component\Routing\Exception\RouteNotFoundException
Route [/dashboard] not defined.
However, I have that route, it's protected but after sign in I assign it. Maybe I am doing in a wrong way?
welcome.blade:
#section('content')
<div class="container-fluid">
<div class="container">
<div class="form-group">
#if ($errors->any())
<div class="alert alert-danger">
#foreach ($errors->all() as $error)
<p>{{ $error }}</p>
#endforeach
</div>
#endif
<form action="{{action('App\Http\Controllers\AuthController#login')}}" method="POST">
#csrf
<input type="text" class="form-control" placeholder="Email address" name="username" required>
<input type="password" class="form-control" placeholder="Password" name="password" required>
<div class="login-btn">
<button type="submit" class="btn btn-success">Sign in</button>
</div>
</form>
</div>
</div>
</div>
#endsection
AuthController:
public function login(Request $request)
{
$fields = $request->validate([
'username' => 'required',
'password' => 'required',
]);
$user = User::where('username', $fields['username'])->first();
if (!$user || !Hash::check($fields['password'], $user->password)) {
return Redirect::back()->withInput()->withErrors('Incorrect username or password');
} else {
$token = $user->createToken($request->username);
return redirect()->route('/dashboard')->with('token', $token);
}
}
web.php :
// Private routing
Route::group(['middleware' => ['auth:sanctum']], function () {
// Agents dashboard
Route::get('/dashboard', function () {
return view('dashboard.main');
})->name('dashboard');
});
// Public routing
Route::get('/', function () {
return view('welcome');
});
Route::post('/login', [AuthController::class, 'login'])->name('login');
Dashboard -> main:
#extends('layouts.app')
#section('content')
<h1>Private</h1>
#endsection
change ->route('/dashboard') to ->route('dashboard'). This value references the name value on a route. eg:
Route::get('/dashboard', function () {
return view('dashboard.main');
})->name('dashboard');
Related
I have a contact form that when submitted, is successfully going to the DB. The issue is, when I check for validation on my webpage, the errors appear properly using Larvael $error validation, the problem is that my webpage always redirects back to home when errors show up instead of the page remaining still and showing the errors. I have to keep scrolling down to where my contact form is to see the errors; this will be annoying for my future users. How do I get the page to remain where it is if there are errors? NOTE: My page redirects correctly when the form is valid and submitted, this is not an issue. NOTE-2: I have created a single page webpage that the nav-links take you to, there are no redirects. Instead, it is one HTML page.
Web.php
Route::get('/', 'HomeController#index')->name('home');
Route::post('/contact/submit', 'MessagesController#submit');
MessagesController.php
namespace App\Http\Controllers;
use App\Message;
use Illuminate\Http\Request;
class MessagesController extends Controller
{
public function submit(Request $request)
{
$validatedData = $request->validate([
'name' => 'required|min:2',
'email' => 'required|max:255',
'phonenumber' => 'required|min:10|max:10',
'message' => 'required|min:5',
]);
Message::create($validatedData);
return redirect('/')->with('success', 'Your message has been
successfully sent. We will reach out to you soon');
}
}
contact.blade.php
{{--CONTACT FORM--}}
<section id="contact">
<div class="container-fluid padding">
<div class="row text-center padding">
<div class="col-12">
<h2 class="lead display-3">Contact Us</h2>
<hr class="my-4">
<form action="/contact/submit" method="POST">
#csrf
<div class="field">
<label for="name" class="label">Name</label>
<div class="control">
<input type="text" class="input {{$errors->has('name') ? 'is-danger' : 'is-success'}}"
name="name" placeholder="Project Title" value="{{old('name')}}">
</div>
</div>
<div class="field">
<label for="name" class="label">Email</label>
<div class="control">
<input type="text" class="input {{$errors->has('email') ? 'is-danger' : 'is-success'}}"
name="email" placeholder="Project Title" value="{{old('email')}}">
</div>
</div>
<div class="field">
<label for="name" class="label">Phone Number</label>
<div class="control">
<input type="text"
class="input {{$errors->has('phonenumber') ? 'is-danger' : 'is-success'}}"
name="phonenumber" placeholder="Project Title" value="{{old('phonenumber')}}">
</div>
</div>
<div class="field">
<label for="message" class="label">Message</label>
<div class="control">
<textarea name="message"
class="textarea {{$errors->has('message') ? 'is-danger' : 'is-success'}}"
placeholder="Project description">{{old('message')}}</textarea>
</div>
</div>
<div class="field">
<div class="control">
<button type="submit" class="button is-link">Create Project</button>
</div>
</div>
<!--Errors variable used from form validation -->
#if($errors->any())
<div class="notification is-danger">
<ul>
#foreach($errors->all() as $error)
<li>{{$error}}</li>
#endforeach
</ul>
</div>
#endif
</form>
</div>
</div>
</div>
</section>
You need to create a manual validator so that you have control over the redirect if the validation fails (which I assume is what you are having issues with).
public function submit(Request $request)
{
$validator = Validator::make($request->all(),[
'name' => 'required|min:2',
'email' => 'required|max:255',
'phonenumber' => 'required|min:10|max:10',
'message' => 'required|min:5',
]);
if ($validator->fails()) {
return redirect(url()->previous() .'#contact')
->withErrors($validator)
->withInput();
}
Message::create($request->all());
return redirect('/')->with('success', 'Your message has been
successfully sent. We will reach out to you soon');
}
First, move the errors to the top of the form so you can see them.
<form action="/contact/submit" method="POST">
#csrf
#if($errors->any())
<div class="notification is-danger">
<ul>
#foreach($errors->all() as $error)
<li>{{$error}}</li>
#endforeach
</ul>
</div>
#endif
A better way of handling validation is to separate it using a form request.
php artisan make:request SendMessageRequest
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class SendMessageRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required|min:2',
'email' => 'required|max:255',
'phonenumber' => 'required|min:10|max:10',
'message' => 'required|min:5',
];
}
}
If validation fails, a redirect response will be automatically generated to send the user back to their previous location.
Now update your controller.
use App\Http\Requests\SendMessageRequest;
use App\Message;
class MessagesController extends Controller
{
public function submit(SendMessageRequest $request)
{
Message::create($request->validated());
return redirect('/')->with('success', 'Your message has been
successfully sent. We will reach out to you soon');
}
}
You can leave the validation in your controller using the Validator and back() redirection, but the first is the better way.
public function submit(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required|min:2',
'email' => 'required|max:255',
'phonenumber' => 'required|min:10|max:10',
'message' => 'required|min:5',
]);
if ($validator->fails()) {
return back()->withInput()->withErrors($validator);
}
Message::create($request->all());
return redirect('/')->with('success,' 'Your message has been
successfully sent. We will reach out to you soon');
}
Laravel basics:
I have the following routes:
Route::group(['prefix' => 'pps', 'as' => 'pps.', 'middleware' => ['auth']], function (){
Route::get('/index', 'PPS\PPSController#index')->name('index');
/**
* Templates
*/
Route::group(['prefix' => 'templates', 'as' => 'templates.', 'middleware' => ['auth']], function (){
Route::get('/', 'PPS\Template\TemplateController#index')->name('index');
/**
* Sequence group
*/
Route::group(['prefix' => 'sequenceGroup', 'as' => 'sequenceGroup.', 'middleware' => ['auth']], function (){
Route::get('/', 'PPS\Template\SequenceGroupController#index')->name('index');
Route::get('/create', 'PPS\Template\SequenceGroupController#create')->name('create');
Route::post('/store', 'PPS\Template\SequenceGroupController#store')->name('store');
Route::get('/edit/{sequenceGroup}', 'PPS\Template\SequenceGroupController#edit')->name('edit');
Route::put('/update/{sequenceGroup}', 'PPS\Template\SequenceGroupController#update')->name('update');
Route::delete('/delete/{sequenceGroup}', 'PPS\Template\SequenceGroupController#delete')->name('delete');
});
/**
* Sequence template
*/
Route::group(['prefix' => 'sequenceTemplates', 'as' => 'sequenceTemplates.', 'middleware' => ['auth']], function (){
Route::get('/{sequenceGroup}', 'PPS\Template\SequenceTemplateController#index')->name('index');
Route::get('/create/{sequenceGroup}', 'PPS\Template\SequenceTemplateController#create')->name('create');
Route::post('/store', 'PPS\Template\SequenceTemplateController#store')->name('store');
Route::get('/edit/{sequenceTemplate}', 'PPS\Template\SequenceTemplateController#edit')->name('edit');
Route::put('/update/{sequenceTemplate}', 'PPS\Template\SequenceTemplateController#update')->name('update');
Route::delete('/delete/{sequenceTemplate}', 'PPS\Template\SequenceTemplateController#delete')->name('delete');
});
});
});
When i update the sequence group, everything works well.
But when i will update the sequence template, laravel goes allways to edit method and not to the update method.
Here my form:
<form action="{{ route('pps.templates.sequenceTemplates.update', $sequenceTemplate->id) }}" method="post">
{{ csrf_field() }}
{{ method_field('put') }}
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
<label for="name" class="control-label">#lang('pps.name')</label>
<input type="text" name="name" id="name" class="form-control" value="{{ old('name', $sequenceTemplate->name) }}">
#if ($errors->has('name'))
<span class="help-block">
<strong>{{ $errors->first('name') }}</strong>
</span>
#endif
</div>
<div class="form-group{{ $errors->has('description') ? ' has-error' : '' }}">
<label for="description" class="control-label">#lang('pps.description')</label>
<input type="text" name="description" id="description" class="form-control" value="{{ old('description', $sequenceTemplate->description) }}">
#if ($errors->has('description'))
<span class="help-block">
<strong>{{ $errors->first('description') }}</strong>
</span>
#endif
</div>
<button type="submit" class="btn btn-primary">#lang('pps.save')</button>
</form>
The controller:
public function edit(SequenceTemplate $sequenceTemplate)
{
return view('pps.template.sequenceTemplate.edit', compact('sequenceTemplate'));
}
public function update(UpdateSequenceTemplateRequest $request, SequenceTemplate $sequenceTemplate)
{
$sequenceTemplate->update($request->except('_token', '_method'));
return redirect()->route('pps.templates.sequenceTemplate.index')->withSuccess(__('sequenceTemplateUpdated'));
}
The request:
<?php
namespace App\Http\Requests\PPS\Template;
use Illuminate\Foundation\Http\FormRequest;
class UpdateSequenceTemplateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'sequence_group_id' => 'required|integer',
'name' => 'required|string|min:3',
];
}
}
What is wrong? i do not find the bug.
When you fill the form and press submit button, Laravel validates the data and redirects you back because there is no sequence_group_id in the form and the field is required:
'sequence_group_id' => 'required|integer',
And you don't see any error message because you're not trying to display it for sequence_group_id. To test it put this to the top of the form:
Errors: {{ dump($errors->all()) }}
And try to submit the form.
Having creating a code for Excel upload I am getting the below mentioned error...
MethodNotAllowedHttpException in RouteCollection.php
The codes written in VIEW is
views/items/items
#extends('layouts.master')
#section('content')
<div class="row">
<div class="col-md-4"></div>
<div class="col-md-6">
<div class="row">
<form action="{{route('items.import')}}" method="POST" enctype="multipart/form-data">
<div class="col-md-6">
{{csrf_field()}}
<input type="file" name="imported-file"/>
</div>
<div class="col-md-6">
<button class="btn btn-primary" type="submit">Import</button>
</div>
</form>
</div>
</div>
<div class="col-md-2">
<!-- <button class="btn btn-success">Export</button> -->
</div>
</div>
#endsection
The codes written in route.php is...
Route::get('/items', 'ItemController#index');
Route::post('/items/import',[ 'as' => 'items.import', 'uses' => 'ItemController#import']);
ItemController.ASPX
public function index()
{
return view('items.items');
}
/**
* Show the form for creating a new resource.
*
* #return Response
*/
public function import(Request $request)
{
if($request->file('imported-file'))
{
$path = $request->file('imported-file')->getRealPath();
$data = Excel::load($path, function($reader) {
})->get();
if(!empty($data) && $data->count())
{
$data = $data->toArray();
for($i=0;$i<count($data);$i++)
{
$dataImported[] = $data[$i];
}
}
Inventory::insert($dataImported);
}
return back();
}
Can anyone please help me what am missing in my coding that outputs the error...
Try this code instead of yours:
Route::post('/items/import',[ 'as' => 'items/import', 'uses' => 'ItemController#import']);
The trick is - the route needs to be named.
To avoid future confusion, it's better to name it as "items.import", so later you can identify for yourself that this is a "name" of a route.
So the final code would be:
Route::post('/items/import',[ 'as' => 'items.import', 'uses' => 'ItemController#import']);
and in blade template u call it like that:
<form action="{{route('items.import')}}"...
I am using Laravel 5.2 and trying to submit a form on dropdown selection. Even though i can do it. But it always redirect to store function which is registered as a resource route.
My routes.php file have routes define like this:
Route::group(['middleware' => ['web']], function () {
Route::group(['middleware' => 'auth'], function () {
Route::get('dashboard', function () {
return view('dashboard.dashboard');
});
Route::get('getcurrency', 'QuoteController#getCurrency'); <!--------This is where i have problem--------->
Route::resource('quotes','QuoteController');
});
});
I tried naming route as well. But it always take me towards the store function
here is how my dropdown looks like:
<form method="post" action={{ action('QuoteController#getCurrency') }}>
<div class="form-group">
<label class="control-label col-md-1">Name</label>
<div class="col-md-5">
<select class="form-control select2me selectCurrency" name="user_id" onchange="this.form.submit()">
#foreach($users as $user)
<option value="{{$user->id}}">{{ $user->name }}
#if(!empty($user->companyname))
({{$user->companyname }})
#else
({{$user->email}})
#endif
</option>
#endforeach
</select>
</div>
</div>
</form>
I am not able to understand why its always force send the value to store function only, when i have even try to mentioned route, method, url and action. Non of the system working for me.
Is laravel have predefined tendency to take SUBMIT BUTTON to a specific function only?
Here is what my URL is when i have my form :
http://localhost/laravel/public/quotes
Does anyone know why this happens? And how can i fix it?
Thank you!
Route.php
Route::group(['middleware' => ['web']], function () {
Route::group(['middleware' => 'auth'], function () {
Route::get('dashboard', function () {
return view('dashboard.dashboard');
});
Route::post('getcurrency', 'QuoteController#getCurrency'); // make it post instead of get
Route::resource('quotes','QuoteController');
});
});
blade file
<form method="post" action={{ url('getcurrency') }}>
<input type="hidden" name="_token" value={{ csrf_token() }}/>
<div class="form-group">
<label class="control-label col-md-1">Name</label>
<div class="col-md-5">
<select class="form-control select2me selectCurrency" name="user_id" onchange="this.form.submit()">
#foreach($users as $user)
<option value="{{$user->id}}">{{ $user->name }}
#if(!empty($user->companyname))
({{$user->companyname }})
#else
({{$user->email}})
#endif
</option>
#endforeach
</select>
</div>
</div>
</form>
If you use route resource your post will go automatically in store method for more https://laravel.com/docs/5.2/controllers#restful-resource-controllers
If you want to change the method then change the action,like
<form method="post" action='quotes'>
Then need to write a route for this url before resource route
Route::group(['middleware' => ['web']], function () {
Route::group(['middleware' => 'auth'], function () {
Route::get('dashboard', function () {
return view('dashboard.dashboard');
});
Route::get('getcurrency', 'QuoteController#getCurrency'); <!--------This is where i have problem--------->
Route::post('quotes','QuoteController#customMethod');
Route::resource('quotes','QuoteController');
});
});
I'm totally noob in PHP, but my question is, after the validation which has errors for specific inputs, how can I insert a class in the specific input?
Example, if i have this error in the validation: "The email field is required."
How can i insert a specific class in the email input?
Login routes:
Route::group(['prefix' => 'admin'], function () {
Route::get('/', 'Admin\AdminController#index');
Route::get('login', 'Admin\AuthController#getLogin');
Route::post('login', 'Admin\AuthController#postLogin');
Route::get('logout', 'Admin\AuthController#getLogout');
});
AdminController:
class AdminController extends AdminBaseController
{
public function index()
{
if(Auth::user()){
return view('admin/pages/admin/index');
}
return view('admin/pages/login/index');
}
}
AuthController:
class AuthController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
private $redirectTo = '/admin';
public $loginPath = '/admin';
public function __construct()
{
$this->middleware('guest', ['except' => 'getLogout']);
}
public function getLogin()
{
if(Auth::user()){
return redirect('/admin');
}
return view('admin/pages/login/index');
}
public function postLogin(Request $request)
{
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:6',
]);
}
}
My blade form:
<form class="s-form" role="form" method="POST" action="/admin/login">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<div class="s-form-item text">
<input type="text" name="email" value="{{ old('email') }}" placeholder="Email">
</div>
<div class="s-form-item text">
<input type="password" name="password" value="{{ old('password') }}" placeholder="Senha">
</div>
<div class="s-form-item">
#if ($errors->has())
<div class="alert alert-danger">
#foreach ($errors->all() as $error)
{{ $error }}<br>
#endforeach
</div>
#endif
</div>
<div class="s-form-item s-btn-group s-btns-right">
<input class="s-btn" type="submit" value="Entrar">
</div>
</form>
You can pass an argument to the has method to specify the specific key.
For example, for your email input...
<input class="#if($errors->has('email')) some-class #endif" ... >
I left out the rest of the input field for brevity. It basically checks if an error for the email input exists. If so, 'some-class' is outputted. Otherwise, it skips over it.
Edit: To answer the question on how you can customize where to output your error messages, you can use the get or first methods in conjunction with the has method. For example...
#if ($errors->has('email'))
#foreach ($errors->get('email') as $error)
<p>{{ $error }}</p>
#endforeach
#endif
The has method has already been explained. The get method retrieves the validation errors. Because there can be more than one validation error, you must loop through it and output it.
In the next example, I use first. This method just outputs the first error message so there is no need to loop through it.
#if ($errors->has('email'))
<p>{{ $errors->first('email') }}</p>
#endif