Yesterday I started with Laravel, currently busy with my first project, a simple news page.
Unfortunately, I've met some problems while validating my post request, I've tried to search on Google for my issue. And I tried to use those fixes, but strange enough I had no result.
The problem is:
When I post data the normal 'form page' will be shown without any errors. I'm aware that I have double error outputs, it's just for the test.
What do I want to reach?
I want that the validation error will be shown
routes.php
<?php
Route::group(['middleware' => ['web']], function() {
Route::get('/', function() {
return redirect()->route('home');
});
Route::get('/home', [
'as' => 'home',
'uses' => 'HomeController#home',
]);
Route::get('/add_article', [
'as' => 'add_article',
'uses' => 'HomeController#add_article',
]);
Route::post('/add_article', [
'as' => 'add_article.newarticle',
'uses' => 'HomeController#post_article',
]);
});
HomeController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\News;
class HomeController extends Controller
{
public function home(News $news)
{
$articles = $news->orderBy('id','desc')->take(3)->get();
return view('home.home')->with('articles', $articles);
}
public function add_article()
{
return view('home.add_article');
}
public function post_article(Request $request)
{
$this->validate($request, [
'title' => 'required|max:64',
'content' => 'required|max:2048',
]);
// $newNews = new News;
// $newNews->title = $request->title;
// $newNews->content = $request->content;
// $newNews->save();
}
}
add_article.blade.php
#extends('templates.default')
#section('content')
<div class="row">
<div class="col-sm-12 col-md-6 col-lg-6 col-xl-6 offset-md-3 offset-lg-3 offset-xl-3">
<p class="lead">New news article</p>
<div class="card">
<div class="card-header">
<h5 class="mb-0"> </h5>
</div>
<div class="card-body">
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
<form method="post" action="{{ route('add_article.newarticle') }}">
<div class="form-group">
<label for="title" style="margin-bottom:0px;">
Title:
</label>
<input class="form-control" type="text" name="title" placeholder="Please enter your title!" id="title">
#if ($errors->has('title'))
{{ $errors->first('title') }}
#endif
</div>
<div class="form-group">
<label for="content" style="margin-bottom:0px;">
Content:
</label>
<textarea class="form-control" rows="3" name="content" placeholder="Please enter your message!" id="content" style="resize:none;"></textarea>
#if ($errors->has('content'))
{{ $errors->first('content') }}
#endif
</div>
<div class="form-group text-right">
<button class="btn btn-primary" type="submit">
Create news
</button>
</div>
{{ csrf_field() }}
</form>
</div>
</div>
</div>
</div>
#endsection
I hope someone can help me to resolve this issue!
use App\Http\Requests;
Remove This from HomeController.php and try.
Your validation is passing but you are not doing anything after so it's not going to show anything unless you tell it to.
Also make sure you use $request->all() instead of $request in the validator as the first one will return the actual input values that were submitted.
use Validator;
public function post_article(Request $request)
{
$validator = Validator::make($request->all(), [
'title' => 'required|max:64',
'content' => 'required|max:2048',
]);
if ($validator->fails()) {
return redirect('home')
->withErrors($validator)
->withInput();
}
// $newNews = new News;
// $newNews->title = $request->title;
// $newNews->content = $request->content;
// $newNews->save();
return redirect()->route('home')->with('message', 'Article created.');
}
}
Then in your view add the following at the top:
#if(Session::has('message'))
<div class="alert alert-success">
×
{{ Session::get('message') }}
</div>
#endif
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
Based on those validation rules you will only see errors when the title is empty or longer than 64 characters, or the content is empty or longer than 2048 characters. Make sure the data you are testing with is long enough to trigger any errors.
For data that passes validation the code currently does not save (commented out), nor does it return a new location or view so it will show a blank page. You should probably save the data and redirect to the index or a show page with a success message.
Related
I am having a little problem here. I am trying to put an image in my User Profile. The image is saved in the database and no errors are shown up, but I never see the default image that I gave to it. It says that it's there but The place for the pic stays empty.
This is what I've got for now:
UserController.php
<?php
namespace app\Http\Controllers;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
// namespace App\Http\Controllers\Controller;
// use App\Http\Requests\Request;
// use Illuminate\Http\Request;
class UserController extends Controller
{
public function profile()
{
$user = Auth::user();
return view('profile',compact('user',$user));
}
public function update_avatar(Request $request){
$request->validate([
'avatar' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
$user = Auth::user();
$avatarName = $user->id.'_avatar'.time().'.'.request()->avatar->getClientOriginalExtension();
$request->avatar->storeAs('avatars',$avatarName);
$user->avatar = $avatarName;
$user->save();
return back()
->with('success','You have successfully upload image.');
}
/** Return view to upload file */
public function uploadFile(){
return view('uploadfile');
}
/** Example of File Upload */
public function uploadFilePost(Request $request){
$request->validate([
'fileToUpload' => 'required|file|max:1024',
]);
$request->fileToUpload->store('logos');
return back()
->with('success','You have successfully upload image.');
}
}
profile.blade.pbp
<hidden='Illuminate\Support\Facades\Auth'>
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row">
#if ($message = Session::get('success'))
<div class="alert alert-success alert-block">
<button type="button" class="close" data-dismiss="alert">×</button>
<strong>{{ $message }}</strong>
</div>
#endif
#if (count($errors) > 0)
<div class="alert alert-danger">
<strong>Whoops!</strong> There were some problems with your input.<br><br>
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
</div>
<div class="row justify-content-center">
<div class="profile-header-container">
<div class="profile-header-img">
<img class="rounded-circle" width="150" height="150" src="/storage/avatars/{{ $user->avatar }}" />
<!-- badge -->
<div class="rank-label-container">
<span class="label label-default rank-label">{{$user->name}}</span>
</div>
</div>
</div>
</div>
<div class="row justify-content-center">
<form action="/profile" method="post" enctype="multipart/form-data">
#csrf
<div class="form-group">
<input type="file" class="form-control-file" name="avatar" id="avatarFile" aria-describedby="fileHelp">
<small id="fileHelp" class="form-text text-muted">Please upload a valid image file. Size of image should not be more than 2MB.</small>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
#endsection
filesystems.php
'default' => env('FILESYSTEM_DRIVER', 'public'),
How can I make the default avatar visible?
Also, do you have any suggestions on how to put a watermark on the photos that will appear each time someone uploads photos?
Thanks in advance!
You can try this. First execute this command
php artisan storage:link
Then
<img class="rounded-circle" width="150" height="150" src="{{url('')}}/storage/avatars/{{ $user->avatar }}"/>
The indexcontroller is shown below
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class IndexController extends Controller
{
public function index()
{
return view('welcome');
}
public function about()
{
return view('about');
}
public function contact()
{
return view('contact');
}
public function thanks(Request $request)
{
$request->validate(['firstname' => ['required', 'alpha_num']]);
return view('thanks');
}
}
contact.blade.php is below
#extends('welcome')
#section('content')
<div>
<h2>Contact Page</h2>
<form method="post" action="{{route("thanks")}}">
#csrf<input type="text" name="firstname"/>
<input type="submit"/>
</form>
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
</div>
#endsection
Thanks.blade.php
#extends('welcome')
#section('content')
<div>
<h2>Thanks</h2>Thank you {{ $firstname }}
</div>
#endsection
welcome.blade.php
<div class="flex-center position-ref full-height">
<div class="content">
<div class="title m-b-md">
app
</div>
<div class="links">
About
contact
</div>
<h1>{{$firstname}}</h1>
<div>
#yield('content')
</div>
</div>
</div>
web.php
<?php
Route::get('/', 'IndexController#index');
Route::get('/about', 'IndexController#about')->name('about');
Route::get('/contact','IndexController#contact')->name('contact');
Route::post('/contact','IndexController#thanks')->name('thanks');
When I click on contact in welcome.blade.php it takes me to contact page where the textbox is pressent . The value entered should appear in thankyou.blade.php.
I need the value entered in the textbox to be shown in thanks.blade.php when I click on submit.
Thanks in Advance
Data needs to be passed to a view explicitly. For hopefully obvious reasons, it isn't globally accessible as a variable.
E.g.
return view('thanks', ['firstname' => 'Your First Name']);
O. I am in need of help with this problem. I have a contact form within a blade.php file, I have a route set up in my web.php file and I have a controller set up which is routed from the web.php file and is to perform validation on the fields and display a flash message on the page when the form is submitted. Right now the form is properly being submitted to my database so it is working but if I submit with a blank form, the validation is not working as it should (laravel) and also the flash message does not show upon successful form submission:
CODE:
Web.php
<?php
Route::get('/', 'HomeController#index')->name('home');
Route::post('/contact/submit','MessagesController#submit');
MessagesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Message;
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', 'Message has been sent');
}
}
contact.blade.php
{{--CONTACT FORM--}}
<section id="contact">
<div class="container-fluid padding">
<div class="row text-center padding">
<div class="col-12">
<h2>Contact PDMA</h2>
</div>
<div class="col-12 padding">
{!! Form::open(['url' => 'contact/submit']) !!}
#csrf
<div class="form-group">
{{Form::label("name", 'Name')}}
{{Form::text('name', '', ['class' => 'form-control', 'placeholder' => 'Enter name'])}}
</div>
<div class="form-group">
{{Form::label("email", 'E-Mail Address')}}
{{Form::text('email', '', ['class' => 'form-control', 'placeholder' => 'Enter email'])}}
</div>
<div class="form-group">
{{Form::label("phonenumber", 'Phone Number')}}
{{Form::text('phonenumber', '', ['class' => 'form-control', 'placeholder' => 'Enter phone number'])}}
</div>
<div class="form-group">
{{Form::label("message", 'Message')}}
{{Form::textarea('message', '', ['class' => 'form-control', 'placeholder' => 'Enter message'])}}
</div>
<div>
{{Form::submit('Submit Form', ['class' => 'btn btn-success'])}}
</div>
{!! Form::close() !!}
</div>
</div>
</div>
</section>
Just use Session:
First Import Session class in your controller
use Session;
Message::create($validatedData);
Session::flash('success', 'Message has been sent');
return redirect('/')
Then Create a blade file in view folder, you can call it whatever you want, e.g: notify.blade.php
#if (Session::has('success'))
<div class="alert alert-success" role="alert" style="bottom:10px; position: fixed; left:2%; z-index:100">
×
<h4 class="alert-heading">Well done!</h4>
<p>{{ Session::get('success') }}</p>
</div>
#endif
#if (Session::has('danger'))
<div class="alert alert-danger" role="alert" style="bottom:10px; position: fixed; left:2%; z-index:100">
×
<h4 class="alert-heading">Error!</h4>
<p>{{ Session::get('danger') }}</p>
</div>
#endif
Finaly, include this file in any view.
include('notify')
As liverson suggested create the blade file for the session
And the other thing you can also is catch the error and change the input style using another blade something like error.blade.php and include it in your form
#if($errors->any())
<div class="alert alert-danger" role="alert">
<ul>
#foreach($errors->all() as $error)
<li>{{$error}}</li>
#endforeach
</ul>
</div>
#endif
For the Form you can add {{$errors->has('name') ? 'is-danger' : ''}} to your div class
For Example
<div class="form-row text-left">
<label for="name" class="col-md-3">Name</label>
<div class="col-md-9">
<input type="text" name="name" class="input {{$errors->has('name') ? 'is-danger' : ''}}" required
value= #if(isset($user))"{{$user->name}}"#else "{{old('name')}}"#endif>
</div>
</div>
https://laracasts.com/series/laravel-from-scratch-2018/episodes/15
Ok I've looked through the site and a few others trying to find an answer to this, but I am struggling. Essentially I am sending from my users index page -> user change primary and from there the user then chooses a house from the select box and then when accepts it sends the ID back so that I can modify and designate the house as being primary.
The code has been changed quite often as tried different solutions, however what happens is that when a user sends the form back to the index page it then submits all house ID's instead of only the specific ID of the house that has been selected.
This is the changeprimary view
#extends('app')
#section('links')
<ul class="nav navbar-nav">
<li>Back</li>
</ul>
#stop
#section('content')
<div class="container-fluid">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="form-box">
<div class="panel panel-default">
<div class="panel-heading" style="padding-left: 30px;">Change your password</div>
<div class="panel-body">
#if (count($errors) > 0)
<div class="alert alert-danger">
<strong>Whoops!</strong> There were some problems with your input.<br><br>
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
<p>
{!! Form::model($houses,['method' => 'POST','route'=>['user.cprimary',$house_id->$houses->id]]) !!}
{!! Form::open(['url' => 'user']) !!}
<div class="form-group">
#if($houses != null)
<div class="form-group">
{!! Form::label('primary', 'Choose a house to make primary') !!}
{{--{!! Form::select('primary', $houses, $houses) !!}--}}
{!! Form::select('primary', $houses) !!}
</div>
{!! Form::close() !!}
<div class="container">
{!! Form::submit('Make House Primary House', ['class' => 'btn btn-primary']) !!}
</div>
#else
<li><a href={{url('/house/create')}}>Add new house</a></li>
</form>
#endif
</div>
</div>
</div>
</div>
</div>
</div>
</div>
This is the user controller for show primary and change priamry
public function showcp()
{
$houses = House::where('user_id', '=', Auth::id())
->lists('h_name');
$house_id = House::where('user_id', '=', Auth::id())
->lists('id');
// foreach($house_ids as $house_id) {
// $house_id = $house_id->id;
// }
// $house = House::find($house_id)->h_name->first();
if (!$houses->isEmpty()) {
return view('users.changeprimary', compact('houses','house_id'));
}
return view('house.nohouse');
}
public function changeprimary($id)
{
//Find and update password linked to User ID.
$house_all = House::all()->where('user_id', Auth::id());
foreach($house_all as $houses)
{
$houses->primary = '0';
$houses->save();
}
$houses->save();
$updateHouse = House::find($id);
$updateHouse->primary = '1';
$updateHouse->save();
return redirect('user')->with('message', 'House '.House::find($id)->h_name.' is primary');
}
And this is the code for the index view
#extends('app')
#section('links')
<ul class="nav navbar-nav">
<li>Back</li>
</ul>
#stop
#section('content')
<div class="container-fluid">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="form-box">
<div class="panel panel-default">
<div class="panel-heading">Profile Options</div>
<div class="panel-body">
#if (session('message'))
<div class="alert alert-info" style="text-align: center; width: 200px; ">
{{ session('message') }}
</div>
#endif
{!! Form::open() !!}
<div class="form-group">
<!-- Modify settings accordingly -->
<div class="form-group">
Change User Settings and Details
</div>
<div class="form-group">
Change Password
</div>
<div class="form-group">
Change Primary House
</div>
</div>
{!! Form::close() !!}
</div>
</div>
</div>
</div>
</div>
</div>
#stop
And this is my routes file
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/
//Home Routes
Route::get('/', 'HomeController#index');
Route::get('home', 'HomeController#index');
//User Routes
Route::post('user/{id}/cprimary',['as' => 'user.cprimary', 'uses' => 'UserController#changeprimary']);
Route::get('user/changeprimary',['as' => 'user.changeprimary', 'uses' => 'UserController#showcp']);
Route::get('user/changepassword', 'UserController#changepassword');
Route::any('user/cpassword',['as' => 'user.cpassword', 'uses' => 'UserController#cpassword']);
Route::resource('user','UserController');
//House Routes
Route::get('createfirsthouse', 'CreateFirstHouseController#index');
Route::get('/house/alternate', 'HouseController#alternate_index');
Route::resource('house', 'HouseController');
//Google Routes
Route::get('googlemap', 'GoogleMapsTest#index');
//Profile Routes
Route::resource('profile', 'ProfileController');
Route::get('profile/resetpassword', 'ProfileController#resetpassword');
//Route to reverse schemas and get migrations.
//Route::get('tc', 'TController#index');
//Any Controller Routes not covered above
Route::controllers([
'auth' => 'Auth\AuthController',
'password' => 'Auth\PasswordController',
]);
Route::get('/dash', 'DashController#index');
Route::get('/', 'DashController#index');
Route::get('/temp', 'TempReset#index');
Route::resource('dash', 'DashController');
Ok the correct answer was changing the controller, not sure why I was adding both options for the form::open, I saw on laracasts and assumed it to be the standard.
public function changeprimary($id)
{
// Get the current users ID
$users= Auth::id();
// Fetch all houses linked to user and loop through collection setting primary to 0
$allhouses=House::where('user_id', $users)->get();
foreach($allhouses as $all) {
$all->primary = '0';
$all->save();
}
// Retrieve the selected input
$houses = Input::get('primary');
// Find house linked to ID
$house = House::find($houses);
$house->primary = '1';
$house->save();
return redirect('user')->with('message', 'House '.$house->h_name.' is primary');
}
That was the correct code I needed to solve this :)
I'm new in Laravel4 world, and I'm trying to convert my site to laravel framework. But at beginning I have a little problem. On index I have two jquery modal: first for singin and second for registration. So, I want to when user try to login and make a mistake to show him an error. Same for registration. But when I have error in singin form, I get register form...My english is bad, so here is code:
routes.php
Route::get('/', function()
{
return View::make("index.index");
}
Route::post('/', array('as'=> 'singin', function()
{
$data = Input::all();
$rules = array(
'username' => 'min:3',
'password' => 'min:6'
);
$validation = Validator::make($data, $rules);
if($validation->passes())
{
return View::make('users.main');
}
Input::flash();
return Redirect::to('/')->withErrors($validation);
}));
Route::post('/', array('as'=> 'register', function()
{
// same as previous function
]
index.blade.php
<div id="signin" class="reveal-modal" #if($errors->all())
style="display:block; visibility:visible;" #endif >
<header class="reveal-modal-header">
Sign in
</header>
<div class="cont">
<div class="indication">
Sign In
</div>
{{ Form::open(array(
'route' => 'singin',
'class' => 'signin')) }}
<p class="clearfix">
{{ Form::label('username', 'Username') }}
{{ Form::text('username')}}
</p>
<p class="clearfix">
{{ Form::label('password', 'Password') }}
{{ Form::password('password')}}
</p>
<p class="without-label clearfix">
{{ Form::submit('') }}
</p>
#if($errors->all())
<div id="logindiverror" style="" class="alert alert-error">
#foreach($errors->all('<li>:message</li>') as $message)
{{ $message }}
#endforeach
</div>
#endif
{{ Form::close() }}
</div>
<a class="close-reveal-modal" id="close1" href="#">×</a>
</div>
<div id="signup" class="reveal-modal" #if($errors->all())
style="display:block; visibility:visible;" #endif >>
<header class="reveal-modal-header">
Sign up
</header>
<div class="cont">
<div class="indication">
Register
</div>
{{ Form::open(array(
'route' => 'register',
'class' => 'signup')) }}
<p class="clearfix">
<em>(<abbr>*</abbr>) All fields are required</em>
</p>
<p class="clearfix">
<label>Username:<abbr>*</abbr></label>
{{ Form::text('username')}}
</p>
<p class="clearfix">
<label>Email:<abbr>*</abbr></label>
{{ Form::text('email') }}
</p>
<p class="clearfix">
<label>Password:<abbr>*</abbr></label>
{{ Form::password('password1'); }}
</p>
<p class="clearfix">
<label>Password (repeat):<abbr>*</abbr></label>
{{ Form::password('password2'); }}
</p>
<p class="checkboxes clearfix">
<span class="niceCheck">{{ Form::checkbox('agree', '0') }}</span>
I agree with LinkyPlanet Terms & Privacy Policy
</p>
<p class="without-label clearfix">
{{ Form::submit('') }}
</p>
#if($errors->all())
<div id="logindiverror" style="" class="alert alert-error">
#foreach($errors->all('<li>:message</li>') as $message)
{{ $message }}
#endforeach
</div>
#endif
{{ Form::close() }}
</div>
<a class="close-reveal-modal" id="close2" href="#">×</a>
</div>
So, problem is when user try to sing in, and he make a mistake in password (pass is shorter than 6 chars), script redirect him to index and open modal for registration and there show an error, not in sing in modal. Where is mistake?
Cheers :)
The problem is that you have 2 "different" routes using the same URI (/) and the same method (POST), but you cannot.
Only the first one will work, by precedence. Something like this could be better:
Route::post('/singin', array('as'=> 'singin', function()
{
}));
Route::post('/register', array('as'=> 'register', function()
{
}));
Or you can keep one of them on / and change the other one:
Route::post('/', array('as'=> 'singin', function()
{
}));
Route::post('/register', array('as'=> 'register', function()
{
}));
EDIT:
You are using the same name for everything ($errors in register and sign in). If you have ONE view for both, you need to have different names. You can use
return Redirect::to('/')->with('registerErrors', $validation->messages());
and
return Redirect::to('/')->with('signInErrors', $validation->messages());
But on tedirects they are bound to your session, so you'll have to get them this way:
#if(Session::has('registerErrors'))
<div id="logindiverror" style="" class="alert alert-error">
#foreach(Session::get('registerErrors')->all('<li>:message</li>') as $message)
{{ $message }}
#endforeach
</div>
#endif