I am trying to create a multi-step form for a user to fill after logging in. I created separate pages with forms that will be a part of the common form.
The data will be saved in the "users" table.
I am new to Laravel and I followed this: https://www.5balloons.info/multi-page-step-form-in-laravel-with-validation/
In my FormController I have these methods:
public function index(Request $request)
{
$request->session()->forget('user');
$user = User::all();
return view('form.index',compact('user',$user));
}
public function updateStep1(Request $request)
{
$user = $request->session()->get('user');
return view('form.update-step1',compact('user', $user));
}
public function postupdateStep1(Request $request)
{
$validatedData = $request->validate([
'first_name' => 'required',
]);
if(empty($request->session()->get('user'))){
$user = User::where('id',auth()->user()->id)->first();
$user->fill($validatedData);
$request->session()->put('user', $user);
}else{
$user = $request->session()->get('user');
$user->fill($validatedData);
$request->session()->put('user', $user);
}
return redirect('/form/update-step2');
}
public function updateStep2(Request $request)
{
$user = $request->session()->get('user');
return view('form.update-step2',compact('user', $user));
}
public function postupdateStep2(Request $request)
{
$validatedData = $request->validate([
'address' => 'required',
]);
if(empty($request->session()->get('user'))){
$user = User::where('id',auth()->user()->id)->first();
$user->fill($validatedData);
$request->session()->put('user', $user);
}else{
$user = $request->session()->get('user');
$user->fill($validatedData);
$request->session()->put('user', $user);
}
return redirect('/form/store');
}
public function store(Request $request)
{
$user = User::where('id',auth()->user()->id)->first();
$user = $request->session()->get('user');
$user->save();
return redirect('/form');
}
And these are the Routes:
Route::get('/form', 'FormController#index');
Route::get('/form/update-step1', 'FormController#updateStep1');
Route::post('/form/update-step1', 'FormController#postupdateStep1');
Route::get('/form/update-step2', 'FormController#updateStep2');
Route::post('/form/update-step2', 'FormController#postupdateStep2');
Route::post('/form/store', 'FormController#store');
This is the first part of the form:
#extends('layouts.app')
#section('content')
<h1>update - Step 1</h1>
<form action="/form/update-step1" method="post">
#csrf
<div class="form-group">
<label for="name">First Name</label>
<input type="text" value="{{ old('first_name', $user->first_name ?? null) }}" class="form-control" name="name">
</div>
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
<button type="submit" class="btn btn-primary">Continue</button>
</form>
#endsection
I get an error when I try to submit, saying that the fields are required. So even if I do enter a name etc., it doesn't work. If I delete the validations, it seems like everything works but no data is added to the database.
Any suggestions?
You should use the input name is first_name because you have used first_name in the validation.
<input type="text" value="{{ old('first_name', $user->first_name ?? null) }}" class="form-control" name="first_name">
OR
If want to change name value in the user table:
FormController
$validatedData = $request->validate([
'name' => 'required',
]);
first part of the form:
<input type="text" value="{{ old('name', $user->name ?? null) }}" class="form-control" name="name">
Related
form
When i submit the form it redirects back to the form itself, can anyone help me?
<form action="/jisajili" method="POST">
#csrf
<div class="card-panel z-depth-5">
<h5 class="center red-text">Jiunge Nasi</h5>
<div class="input-field">
<i class="material-icons prefix">account_circle</i>
<input type="text" name="username" class="validate">
<label>Jina lako</label>
</div>
<div class="input-field">
<i class="material-icons prefix">phone</i>
<input type="number" name="phone" class="validate">
<label>Nambari ya simu</label>
</div>
....
</p>
<input type="submit" name="submit" value="Jiunge" class="btn left col s12 red">
Controller
class registration extends Controller{
public function create(){
return view('jisajili.jiunge');
}
public function store(Request $request){
$reg = new regist;
$reg->jina = $request->input('username');
$reg->simuNumber = $request->input('phone');
$reg->email = $request-> input('email');
$reg -> password = bcrypt($request->input('password'));
$cpassword = $request -> input('cpassword');
$reg->save();
$validated = $request->validate([
'name' => 'required|unique:posts|max:10',
'body' => 'required',
]);
return redirect('home');
}
}
What I would do is first check for the data requirements before you add the object to the database. Also I would add the columns of the models into the Model file to use the Object::create function with an array parameter.
I recomment to use routing in your blade file. I noticed you used action="/route". What you want to do is naming your routes with ->name('route_name') in the route files. To use them in your blade files with the global route function route="{{ route('route_name') }}".
<?php
class PostController extends Controller
{
public function index()
{
return view('post.create');
}
public function store(\Illuminate\Http\Request $request)
{
$validator = Validator::make(
$request->all(),
[
'name' => 'required|unique:posts|max:10',
'body' => 'required'
]
);
// Go back with errors when errors found
if ($validator->fails()) {
redirect()->back()->with($validator);
}
Post::create(
[
'name' => $request->get('name'),
'body' => $request->get('body')
]
);
return redirect()
->to(route('home'))
->with('message', 'The post has been added successfully!');
}
}
What you can do after this is adding custom errors into the controller or add them into your blade file. You can find more about this in the documentation of Laravel.
it redirects you back because of validation error.
change password confirmation name from cpassword into password_confirmation as mentioned in laravel docs
https://laravel.com/docs/7.x/validation#rule-confirmed
update your controller into:
public function store(Request $request){
$validated = $request->validate([
'username' => 'required',
'phone' => 'required',
'email' => 'required',
'password' => 'required|confirmed'
]);
$reg = new regist;
$reg->jina = $request->input('username');
$reg->simuNumber = $request->input('phone');
$reg->email = $request-> input('email');
$reg -> password = bcrypt($request->input('password'));
$reg->save();
return redirect('home');
}
in your blade add the following to display validation errors:
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
I've searched but couldn't find a working solution. I simply cannot update a specific field (status) in users table. I've added two additional fields in Laravel's auth users original table.
Here is the migration code:
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->unsignedBigInteger('role_id');
$table->integer('status')->default(0);
$table->foreign('role_id')->references('id')->on('roles');
});
}
I've also added fillable:
protected $fillable = ['name', 'email', 'password', 'role_id', 'status'];
Now the issue is I cannot update "status" field and the operation doesn't return any issue. I already have tried it with different approaches. Have a look at the code and guide me. TIA.
public function update(Request $request, $id)
{
$validatedData = $request->validate([]);
// APPROACH # 1
$user = User::find($id);
$user->status = $request->status;
$user->save();
// APPROACH # 2
$user = User::find($id);
$user->update([
'status' => $request->status,
]);
// APPROACH # 3
User::findOrFail($id)->update($request->all());
}
Form:
<form action="{{ url('/admin/user') }}/{{ $editRecord[0]->id }}" method="POST" enctype="multipart/form-data">
#method('PUT')
#csrf
<select id="status" name="status" class="form-control">
<option value="1" #if($editRecord[0]->status == 1) selected #endif>Active</option>
<option value="0" #if($editRecord[0]->status == 0) selected #endif>In-Active</option>
</select>
</form>
Finally the route:
Route::put('/admin/user/{id}', 'Admin\PortalController#update');
Then code is working fine may be you forget to redirect back with success message. you should try below -
if($user->save()){
return redirect()->back()->with('message', 'updated successfully');
} else {
return redirect()->back()->with('error', 'something went wrong');
}
Then in blade file -
#if(session()->has('message'))
<div class="alert alert-success">
{{ session()->get('message') }}
</div>
#endif
#if(session()->has('error'))
<div class="alert alert-danger">
{{ session()->get('error') }}
</div>
#endif
I need to make validate the (request_number) input is the Only integer and show a Message if the student writes a string as an example.
the Message if the user write the existing number is (the number of your order exists)
and the message if the user writes the non-integer value is (the input should be the Only Number)
Now I want to make double validation on (request_number).
this is my store in my controller
public function store(Request $request)
{
$excuse = new Student();
$excuse->request_number = $request->input('request_number');
$validatedData = $request->validate([
'request_number' => Rule::unique('students')->where(function ($query)
{
return $query->whereIn('status_id',[2,4,6,5]);
})]);
$excuse->student_id = Auth::guard('web')->user()->id;
$excuse->status_id = 1;
$excuse->college_id = Auth::guard('web')->user()->college_id;
$excuse->save();
return redirect('/students');
}
and this is my form to make a request
<form method="post" action="{{url('/student')}}" enctype="multipart/form-data">
#csrf
<h1> Make order FORM</h1>
<div class="form-group">
<label for="requestnumber"> write the Request Number </label><br>
<input type="text" id="request_number" name="request_number"class="form-control" minlength="5" style="width:50%" required >
</div>
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li> the number of request is exists </li>
#endforeach
</ul>
</div>
#endif
<br>
<button type="submit" class="btn btn-primary">send</button><br>
</form>
Try replacing your code with this
$status = Student ::whereIn('status_id', [2,3,4,5])->pluck
('status_id') ;
$validatedData = $request->validate([
'request_number ' =>
'required|integer ',
Rule::unique('students')->where(function ($query)
use ($status) {
return $query->whereIn('status_id', $status);
})
]) ;
and let me know either it is the thing you want or not
$validatedData = $request->validate([
'request_number ' => [
'required', 'integer', function($attr, $val, $fail) {
if (YourTargetModel::where('id', [1,2,3])->count() > 0) {
return $fail("The request number field should be
unique");
}
}]
]);
You can have many rules for a single field by using an array of rules:
'request_number' => [
'integer',
Rule::unique('students')->where(function ($query) {
return $query->whereIn('status_id', [2, 4, 6, 5]);
}),
]
I want to use input from a form in one view and print results into another view. I get the following error: Undefined variable: users Thanks in advance!
The form (in a view called 'dashboard') that I am using to get email address:
...
<div class="search">
<header><h3>Search Friend</h3></header>
<form action="{{ route('search.friend') }}" method="post">
<div class="form-group">
<input class="form-control" type="text" name="email" id="email" placeholder="Friend's email">
</div>
<button type="submit" class="btn btn-primary">Post</button>
<input type="hidden" value="{{ Session::token() }}" name="_token">
</form>
</div>
...
The route to send data from 'dashboard' to Controller:
Route::post('/searchfriend',[
'uses' => 'FriendController#getSearchFriend',
'as' => 'search.friend',
'middleware' => 'auth'
]);
The controller where I use the email to find user:
class FriendController extends Controller
{
public function getSearchFriend(Request $request)
{
$this->validate($request,[
'email' => 'required | email'
]);
$email = $request['email'];
$users = User::where('email',$email)->get();
return view('userlist',['$users' => $users]);
}
}
The route to send the result to a 'userlist' view:
Route::get('/userlist',[
'uses' => 'FriendController#getSearchFriend',
'as' => 'userlist',
'middleware' => 'auth'
]);
Finally, the 'userlist' view:
#extends('layouts.master')
#section('title')
Users
#endsection
#section('content')
<section class="row new-post">
<div class="col-md-6 col-md-offset-3">
<header><h3>Users</h3></header>
<div class="userlist">
<header><h2>Click to Add Friend</h2></header>
#foreach($users as $user)
Name: {{ $user->username }}
#endforeach
</div>
</div>
</section>
#endsection
Change:
class FriendController extends Controller
{
public function getSearchFriend(Request $request)
{
$this->validate($request,[
'email' => 'required | email'
]);
$email = $request['email'];
$users = User::where('email',$email)->get();
return view('userlist',['$users' => $users]);
}
}
to:
class FriendController extends Controller
{
public function getSearchFriend(Request $request)
{
$this->validate($request,[
'email' => 'required | email'
]);
$email = $request['email'];
$users = User::where('email',$email)->get();
return view('userlist',['users' => $users]);
}
}
You don't need the $ when passing the name of the variable to the view.
#Ryan J Field is correct. Also, you can pass the variable in many different ways. Such as -
return view('userlist')->with('users', $users);
Or,
return view('userlist', compact(users));
I keep on getting this error whenever I try to enter the upload page.
Can anybody help?
I have already done the compact part to make sure that the variable is being passed to the view and also my route should be ok I think.
I tried using dd but all it does is keep on showing me the error
Error: Undefined variable: user (View: C:\xampp\htdocs\Evaluation\resources\views\upload.blade.php)
Here are my codes:
upload.blade.php
<form class="form-horizontal" method="post" action="{{ url('/userUpload')}}" enctype="multipart/form-data">
{{ csrf_field() }}
<input type="hidden" name="user_id" value="{{$user->id}}">
<div class="form-group">
<label for="imageInput" class="control-label col-sm-3">Upload Image</label>
<div class="col-sm-9">
<input type="file" name="file">
</div>
</div>
<div class="form-group">
<div class="col-md-6-offset-2">
<input type="submit" class="btn btn-primary" value="Save">
</div>
</div>
</form>
UploadController:
public function upload(){
return view(‘upload’);
}
public function store(Request $request,$id){
$this->validate($request, [
'file' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
var_dump('has file '.$request->hasFile('file'));
if ($request->hasFile('file')) {
$image = $request->file('file');
$name = $image->getClientOriginalName();
$size = $image->getClientSize();
$id = $request->user_id;
$destinationPath = public_path('/images');
$image->move($destinationPath, $name);
$Image = new Image;
$Image->name = $name;
$Image->size = $size;
// $Image->user_id = $id;
//$Image->save();
$user->find($id);
dd($user);
$user->Images()->save($Image);
}
return redirect('/home');
}
public function test(){
$user = user_information::where('id')->get();
return view('upload', compact('user'));
}
Route: (this are my route)
Route::get('/UploadUser/upload','UploadController#upload’);
Route::post('/UploadUser','UploadController#store');
Route::post('/UploadUser/upload', 'UploadController#test');
Another question: I keep on getting this error when i try to upload a file, so what should I do?
Here is the error:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or
update a child row: a foreign key constraint fails (form.images,
CONSTRAINT images_user_id_foreign FOREIGN KEY (user_id) REFERENCES
usere_information (id)) (SQL: insert into images (name,
size, user_id, updated_at, created_at) values (download.png,
4247, 1, 2017-10-25 08:54:57, 2017-10-25 08:54:57))
Image model:
class Image extends Model
{
protected $fillable = array('name','size','user_id');
public function user_informations() {
return $this->belongsTo('App\user_information', 'user_id', 'id');
}
}
Images table:
Schema::create('images', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('size');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('user_informations');
$table->timestamps();
});
User_information table:
Schema::create('user_informations', function (Blueprint $table) {
$table->increments('id');
$table->engine = 'InnoDB';
$table->binary('signature');
$table->String('Name');
$table->timestamps();
});
User_information model:
class user_information extends Eloquent
{
protected $fillable = array('signature', 'Name');
protected $table = 'user_informations';
protected $primaryKey = 'id';
public function Images() {
return $this->hasOne('App\Image','user_id');
}
}
How to get the image?
Here is the view folder:
#foreach ($data as $object)
<b>Name: </b>{{ $object->Name }}<br><br>
Edit<br>
#foreach ($data3 as $currentUser)
<img src="{{ asset('public/images/' . $currentUser->Image->name ) }}">
#endforeach
#if($data3->count())
#foreach($data3 as $currentUser)
<a href="{!! route('user.upload.image', ['id'=>$currentUser->user_id]) !!}">
<button class="btn btn-primary"><i class ="fa fa-plus"></i>Upload Images</button>
</a>
#endforeach
#else
<a href="{!! route('user.upload.image', ['id'=>$object->id]) !!}">
<button class="btn btn-primary"><i class ="fa fa-plus"></i>Upload Images</button>
#endif
#endforeach
HomeController:
public function getInfo($id) {
$data = user_information::where('id',$id)->get();
$data3=Image::where('user_id',$id)->get();
return view('test',compact('data','data3'));
Because you didn't pass the user to your upload view, try to pass it like this :
public function upload(){
$id = 1 //The wanted user or if the user is authenticated use Auth::id()
$user = User::find($id);
return view('upload')->withUser($user);
}
Or if the user is authenticated use Auth in the view :
<form class="form-horizontal" method="post" action="{{ url('/userUpload')}}" enctype="multipart/form-data">
{{ csrf_field() }}
<input type="hidden" name="user_id" value="{{auth()->id()}}">
<div class="form-group">
<label for="imageInput" class="control-label col-sm-3">Upload Image</label>
<div class="col-sm-9">
<input type="file" name="file">
</div>
</div>
<div class="form-group">
<div class="col-md-6-offset-2">
<input type="submit" class="btn btn-primary" value="Save">
</div>
</div>
</form>
For the second problem it's because in the route you have
Route::post('/UploadUser','UploadController#store');
and the your store method signature is
public function store(Request $request,$id){
The $id parameter that did the problem because it's not defined in the route so simply remove it from the method signatre
public function store(Request $request){
$this->validate($request, [
'file' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
if ($request->hasFile('file')) {
$image = $request->file('file');
$name = $image->getClientOriginalName();
$size = $image->getClientSize();
$id = $request->user_id; // here id is declared no need for the parameter
$destinationPath = public_path('/images');
$image->move($destinationPath, $name);
$Image = new Image;
$Image->name = $name;
$Image->size = $size;
$Image->user_id = $id;
$Image->save();
}
return redirect('/home');
}
For the third case you have to change the routes from :
Route::get('/UploadUser/upload','UploadController#upload’);
to
Route::get('/UploadUser/{user}/upload','UploadController#upload’)->name('user.upload.image');
And in the view add the id in the upload button url maybe like this :
{!! route('user.upload.image', ['user'=>$currentUser->id]) !!}
Then in the upload method :
public function upload(user_information $user){ // route model binding here
// dd($user); //for testing only :)
return view('upload')->withUser($user);
}
In the view change
<input type="hidden" name="user_id" value="{{auth()->id()}}">
To
<input type="hidden" name="user_id" value="{{$user->id()}}">
And you are good to go ;)
#foreach ($data as $currentUser)
<b>Name: </b>{{ $currentUser->Name }}<br><br>
Edit<br>
#if($currentUser->Image)
<img src="{{ asset('public/images/' . $currentUser->Image->name ) }}">
#endif
<a href="{!! route('user.upload.image', ['id'=>$currentUser->id]) !!}">
#endforeach
You have miss to pass id in your where condition,
public function test(){
$user = user_information::where('id',$id)->first();
return view('create1', compact('user'));
}
and you have to pass your user data into this,
public function upload(){
$user = user_information::where('id',$id)->first();
return view(‘upload’,compact('user'));
}
Hope it helps,
On your upload function, you have to pass the user variable because you use the $user in the view. So the controller will be
public function upload() {
$user = Auth::user();
return view('upload', compact('user'));
}
do not forget to change the $user based on your need.
You have to pass an $id variable into your test() method. Then please comment below what's the error next so I can follow you through.
Update
Since you don't want to pass an id. You can use:
public function test(){
$u = Auth::user();
$user = user_information::where('id', $u->id)->get();
return view('upload', compact('user'));
}
OR
Try to use first() instead of get().
More option:
I have noticed, you're using the upload() method here, why not passing the $user there? like so:
public function upload(){
$user = Auth::user();
return view(‘upload’, compact('user'));
}