Edit profile page using laravel - php

Whenever a user goes to mywebsite.com/profile I want a form to pre populate the values they've entered during the signup/registration flow. I was able to do that with my form here
<h1><b>Your Profile</b></h1>
<form method="POST" action="/profile/update">
<div class="form-group hidden">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="hidden" name="_method" value="PATCH">
</div>
<div class="form-group {{ $errors->has('name') ? ' has-error' : '' }}">
<label for="email" class="control-label"><b>Name:</b></label>
<input type="text" name="name" placeholder="Please enter your email here" class="form-control" value="{{ $user->name }}"/>
<?php if ($errors->has('name')) :?>
<span class="help-block">
<strong>{{$errors->first('name')}}</strong>
</span>
<?php endif;?>
</div>
<div class="form-group {{ $errors->has('email') ? ' has-error' : '' }}">
<label for="email" class="control-label"><b>Email:</b></label>
<input type="text" name="email" placeholder="Please enter your email here" class="form-control" value="{{ $user->email }}"/>
<?php if ($errors->has('email')) :?>
<span class="help-block">
<strong>{{$errors->first('email')}}</strong>
</span>
<?php endif;?>
</div>
<div class="form-group">
<button type="submit" class="btn btn-default"> Submit </button>
</div>
</form>
But now im running into the issue if the user just hits submit button without changing any fields, laravel's built in validations checks and gives me an error message of The name has already been taken. which is true. so im not sure how to handle this issue, but here is my controller below
<?php
namespace App\Http\Controllers;
use Auth;
use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class ProfileController extends Controller
{
/**
* Update user profile & make backend push to DB
*
**/
public function index() {
/**
* fetching the user model
**/
$user = Auth::user();
//var_dump($user);
/**
* Passing the user data to profile view
*/
return view('profile', compact('user'));
}
public function update(Request $request) {
/**
* Validate request/input
**/
$this->validate($request, [
'name' => 'required|max:255|unique:users',
'email' => 'required|email|max:255|unique:users',
]);
/**
* storing the input fields name & email in variable $input
* type array
**/
$input = $request->only('name','email');
/**
* fetching the user model
*/
$user = Auth::user();
/**
* Accessing the update method and passing in $input array of data
**/
$user->update($input);
/**
* after everything is done return them pack to /profile/ uri
**/
return back();
}
}
and here is my routes file.
// only authenticated users
Route::group( ['middleware' => 'auth'], function() {
Route::get('/home', 'HomeController#index');
// practicing using forms for sending data to the DB & populating form fields with DB data
Route::get('profile', 'ProfileController#index');
Route::patch('profile/{id}', 'ProfileController#update');
});

Issue is due to unique validation rule. You can exclude the current user id by specifying unique validation rule. your code will be like this
public function update(Request $request) {
/**
* fetching the user model
*/
$user = Auth::user();
/**
* Validate request/input
**/
$this->validate($request, [
'name' => 'required|max:255|unique:users,name,'.$user->id,
'email' => 'required|email|max:255|unique:users,email,'.$user->id,
]);
/**
* storing the input fields name & email in variable $input
* type array
**/
$input = $request->only('name','email');
/**
* Accessing the update method and passing in $input array of data
**/
$user->update($input);
/**
* after everything is done return them pack to /profile/ uri
**/
return back();
}
here is laravel documentation link for this https://laravel.com/docs/5.1/validation#rule-unique

Related

Laravel 8 - How to suppress validation errors with a back button in Laravel

How to suppress validation errors with a back button in Laravel ??
Details: I have form with two buttons and I made validation how to skip validation when click on (back-button)?
the code in the view page:
<form method="POST" action="{{route("movies.store")}}" class="mt-5 w-50 m-auto">
#csrf
<div class="mb-3">
<label class="form-label">Movie Name</label>
<input type="text" name="movie_name" class="form-control">
#error('movie_name')
<span class="error">{{$message}}</span>
#enderror
</div>
<div class="mb-3">
<label class="form-label">Movie Descrption</label>
<input type="text" name="movie_description" class="form-control">
#error('movie_description')
<span class="error">{{$message}}</span>
#enderror
</div>
<div class="mb-3">
<label class="form-label">Movie Gener</label>
<input type="text" name="movie_gener" class="form-control">
#error('movie_gener')
<span class="error">{{$message}}</span>
#enderror
</div>
<button type="submit" name="action" value="back" class="btn btn-warning me-3">Back</button>
<button type="submit" name="action" value="add" class="btn btn-primary">Add</button>
</form>
the code in the controller file:
public function store(MoviesFormRequest $request)
{
switch ($request->input('action')) {
case 'back':
return redirect()->route("movies.index");
case 'add':
$data = $request->validated();
Movie::create($data);
return redirect()->route("movies.index");
}
}
If you just want to solve the problem by implementing back button instead of using button tag use anchor tag as follows
Back
And remove the switch statement and just do as follows:
public function store(MoviesFormRequest $request)
{
Movie::create($request->all());
return redirect()->route("movies.index");
}
Inside your MoviesFormRequest class do all the validations like :
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class MoviesFormRequest 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 [
'movie_name' => 'required',
'movie_description' => 'required',
'movie_gener' => 'required',
];
}
}
This will work for you just customize the anchor tag to look good. Hope this solve your problem.
The validation happens in your custom request (MoviesFormRequest) before the code in the controller method is executed.
So in order to skip validation given a specific request input, you have to make the it part of the switch block
use Illuminate\Http\Request;
// use the base request here (no validation at this point)
public function store(Request $request)
{
switch ($request->input('action')) {
case 'back':
return redirect()->route("movies.index");
case 'add':
// in our case block we can validate
$this->validate($request, [
'title' => ['required'],
//... your rules here
]);
$data = $this->validated();
Movie::create($data);
return redirect()->route("movies.index");
}
}

Single Validation in Laravel

I am very new to Laravel, and our system uses multiple forms within a single page to insert the single bitcoin wallet into each input field, but as it stands the user is able to use it on all inputs and this is wrong as could i make only one valid? such as "username" "email" etc ..
html:
<form method="POST" action="/wallet3-edit/update">
<div class="form-group hidden">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="hidden" name="_method" value="PATCH">
</div>
<div class="form-group {{ $errors->has('bitzpayer_id3') ? ' has-error' : '' }}">
<label for="bitzpayer_id3" class="control-label"><b>Wallet:</b></label>
<input type="text" name="bitzpayer_id3" placeholder="Please enter your Wallet here" class="form-control" value="{{ $user->bitzpayer_id3 }}"/>
<?php if ($errors->has('bitzpayer_id3')) :?>
<span class="help-block">
<strong>{{$errors->first('bitzpayer_id3')}}</strong>
</span>
<?php endif;?>
</div>
<div class="form-group">
<button type="submit" class="btn btn-warning text-white"> Submit </button>
</div>
</form>
Controller:
<?php
namespace App\Http\Controllers;
use Auth;
use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class Wallet3Controller extends Controller
{
/**
* Update user profile & make backend push to DB
*
**/
public function index() {
/**
* fetching the user model
**/
$user = Auth::user();
//var_dump($user);
/**
* Passing the user data to profile view
*/
return view('/wallet3-edit', compact('user'));
}
public function update(Request $request) {
/**
* fetching the user model
*/
$user = Auth::user();
/**
* Validate request/input
**/
$this->validate($request, [
'bitzpayer_id3' => 'max:255|unique:users,bitzpayer_id3,'.$user->id,
]);
/**
* storing the input fields name & email in variable $input
* type array
**/
$input = $request->only('bitzpayer_id3');
/**
* Accessing the update method and passing in $input array of data
**/
$user->update($input);
/**
* after everything is done return them pack to /profile/ uri
**/
return back();
}
}
Routes:
Route::get('wallet3-edit', 'Wallet3Controller#index');
Route::patch('wallet3-edit/{id}', 'Wallet3Controller#update');
if you want to validate not duplication in a single page:
because The page dosent send any request to server until the form completes,
you can check this within javascript/jquery like this:
$(".inputs").change(function(){
if($("#input1").val()==$("#input2").val()){
$("#input1").addClass("error");
}
});
but if your input are seprated in different pages and save in database you can validate with them with this kind of rules in Laravel controller or Laravel Request Class:
$validationRules = ["wallet" => "required|unique:wallets_table,btc"];
where "wallet" is the name of your input field. "wallets_table" is your database table and "btc" is table column.
but if you are not willing to save the wallet public keys in Database and the requests are from a single user, you can save the "Address"es in a Session Array and check them out when a user submit a request. but this solution works User Scope .
please give me more details if I misunderstood.

Laravel Resource Controller update method not firing

I have a resource controller TruckController generated via php artisan make:controller TruckController --resource.
When I go go to localhost/trucks/1/edit, the edit form shows up successfully.
When I click submit, I am redirected to the resource show page (localhost/trucks/1); however, the truck information is not updated and no errors were thrown.
It seems the update function is not firing at all, which I think means there is something wrong with the action attribute in my form, but I am still unsure. There shouldn't be an issue with the routes because the routes should already be defined because it's a resource controller.
edit.blade.php
<form method="PUT" action="{{ action('TruckController#update', ['id' => $truck->id]) }}" class="validate form-horizontal form-groups-bordered" novalidate="novalidate">
#csrf
<input type="hidden" name="state" data-geo="administrative_area_level_1" value="{{ $truck->state }}">
<input type="hidden" name="city" data-geo="locality" value="{{ $truck->city }}">
<input type="hidden" name="zipcode" data-geo="postal_code" value="{{ $truck->zipcode }}">
[ ... ]
</form>
TruckController#update
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(TruckCreateRequest $request, Truck $truck)
{
$validated = $request->validated();
$truck->name = $request->name;
$truck->description = $request->description;
$truck->save();
}
TruckCreateRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class TruckCreateRequest 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 [
'name' => 'required',
'description' => 'required',
'city' => 'required',
'state' => 'required',
'zipcode' => 'required',
'address' => 'required'
];
}
}
And just in case this may be of more help ...
Web.php
<?php
Auth::routes();
// ajax
Route::post('ajax/notifications/clear', 'DashboardController#mark_notifications_read');
Route::get('/', 'DashboardController#index')->name('dash');
Route::resource('events', 'EventController');
Route::resource('venues', 'VenueController');
Route::resource('trucks', 'TruckController');
Route::resource('admin', 'AdminController');
App/Models/Truck.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Truck extends Model
{
//
}
From the Laravel Documentation:
Since HTML forms can't make PUT, PATCH, or DELETE requests, you will
need to add a hidden _method field to spoof these HTTP verbs.
Try to add a hidden method field to the form:
#method('PUT')
Read more here: https://laravel.com/docs/5.7/blade#method-field
You should try this:
<form method="POST" action="{{ action('TruckController#update', [$truck->id]) }}" class="validate form-horizontal form-groups-bordered" novalidate="novalidate">
#csrf
<input type="hidden" name="state" data-geo="administrative_area_level_1" value="{{ $truck->state }}">
<input type="hidden" name="city" data-geo="locality" value="{{ $truck->city }}">
<input type="hidden" name="zipcode" data-geo="postal_code" value="{{ $truck->zipcode }}">
[ ... ]
</form>

Form array validation Laravel 5.2

I am currently stuck on solving this problem. I am new to Laravel and the MVC framework. I am struggling to create the dynamic form that gives the user the ability to add as many forms as possible. When the user enters the page at first it generates 5 form fields . Here is a look at my code so far.
<div id ={{$id = "from".$i}} >
<div class="form-group col-md-6">
<div class="col-md-6 form-group">
<label for={{$id = "Address".$i}}>Address</label>
<input type="text" name = "address[{{$i}}]" class="form-control" id={{$id = "Address".$i}} placeholder="Street Address"> <!-- problem form array how does this work in laravel -->
</div>
<div class="form-group col-md-6">
<label for={{$id = "city".$i}}>City</label>
<input type="text" value = "{{ old('city') }}" class="form-control" id={{$id = "City".$i}} placeholder="City">
#if ($errors->has('city'))
<span class="help-block">
<strong>{{ $errors->first('city') }}</strong>
</span>
#endif
</div>
How would I go about validating a form in Laravel 5.2 with from array
here's my controller
public function Postdata(Request $request) {
$this->validate($request->all(), [
'address.*' => 'required|string',
'city' => 'required',
]);
}
I am using a for loop to generate the forms dynamically.
here is the error I get
ErrorException in ValidatesRequests.php line 49:
Argument 1 passed to App\Http\Controllers\Controller::validate() must be an instance of Illuminate\Http\Request, array given, called in
C:\wamp\www\Dynamic- 1.0\app\Http\Controllers\propContoller.php on line 34 and defined
Can someone please help or point me in the right direction thank you !
add name="city[{{$i}}]"
Create a specific request with php artisan make:request PostRequest
Change public function Postdata(Request $request) { to public function Postdata(PostRequest $request) {
Remove the validate function call from your controller
Go to /app/Http/Requests/PostRequest.php
Then edit the rules function to something like this ...
.
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
$rules = [];
foreach($this->request->get() as $key => $val)
{
$rules['address.' . $key] = 'required';
$rules['city.' . $key] = 'required';
}
return $rules;
}
Thank You man ! this is the solution I end up with
<div class="form-group col-md-6">
<div class="col-md-6 form-group">
<label for={{$id = "Address".$i}}>Address</label>
<input type="text" name="address[{{$i}}]" class="form-control" id={{$id = "Address".$i}} placeholder="Street Address">
</div>
in post request i did this
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules() {
$rules = [];
foreach($this->request->get('address') as $key => $val) {
$rules['address.'.$key] = 'required';
}
return $rules;
}

Posting content into the database with an image using Laravel

I'm trying to post some stuff into the database using laravel, but It seems not to work...
This is what I get:
The HTML:
{{ Form::open(array('role' => 'form')) }}
<div class="form-body">
<div class="form-group">
<label>Titel</label>
<input type="text" class="form-control" name="title" placeholder="Titel komt hier">
</div>
<div class="form-group">
<label>Textarea</label>
<textarea class="form-control" name="message" rows="5" placeholder="Uw bericht..."></textarea>
</div>
<div class="form-group">
<label for="exampleInputFile1">Nieuws afbeelding</label>
<input type="file" name="img">
</div>
</div>
<div class="form-actions">
<input type="submit" class="btn green" value="Oplsaan" />
</div>
{{ Form::close() }}
#if ($errors->any())
<ul>
{{ implode('', $errors->all('<li class="error">:message</li>')) }}
</ul>
#endif
That displays all well....
Exept when I try to 'post' the news, because that is what I try to do, it just refreses the page. The URL to that page is mydomain.com/admin/news/write
My router looks like this:
Route::resource('admin/news/write', 'AdminController#create');
First it was authenticated in a group:
Route::group(array('before' => 'auth'), function()
{
Route::resource('admin', 'AdminController');
Route::resource('admin/news/write', 'AdminController#create');
});
This all works, but when I change the Route::resource('admin/news/write', 'AdminController#create'); to Route::post('admin/news/write', 'AdminController#create'); I get an error, that I can't see...
Good, now my controller:
public function store()
{
$rules = array(
'title' => 'required',
'message' => 'required',
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->passes())
{
if (Input::only('title', 'message'))
{
return Redirect::to('admin/news/write')->with('message', 'Het nieuws werd gemaakt!');
}
}
else
{
return Redirect::to('admin/news/write')->with('message', "Er ging iets mis: ")->withErrors($validator);
}
}
The problem is, I don't know how I can store an image to
/public/pictures/news
And then store the full file name into the database, if someone could help me out... I need a response quick, beacause I have a deadline... :{
Kindest regards
First you need to tell your form using the laravel helper that this is going to be uploading a file...
Form::open(['method'=>'POST', 'role' => 'form', 'files' => true])
In your controller you want to get the file from the input
$imgFile = Input::file('img');
Now to move the file from the temporary location it's been uploaded, to a more permanent location call the following (where $filename is what you want to call the uploaded file)...
$dir = '../storage/app/upload/';
$imgFile->move($dir.$filename);
The path for the root of the app from here is ../ (one up from public) so..
../storage/app/upload/ would be a great location to use for uploaded files.
You can then just write:
$dir.$filename;
back to the database - job done :)
Edit :: -- Your Controller --
Your controller for parsing this is based on resources...
So your route will be:
Route::group(array('before' => 'auth'), function()
{
Route::resource('admin', 'AdminController');
}
Your controller itself will have a structure such as (remembering this: http://laravel.com/docs/4.2/controllers#restful-resource-controllers):
class AdminController extends BaseController {
public function index(){...}
public function create(){...}
public function
//The store() method is an action handled by the resource controller
//Here we're using it to handle the post action from the current URL
public function store()
{
$imgFile = Input::file('img');
//processing code here....
}
public function show(){...}
public function edit(){...}
public function update(){...}
public function destroy(){...}
}
I fixed the issue.
My controller:
<?php
class AdminNewsController extends \BaseController {
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
return View::make('admin.news.create');
}
/**
* Show the form for creating a new resource.
*
* #return Response
*/
public function create()
{
return View::make('admin.news.create');
}
/**
* Store a newly created resource in storage.
*
* #return Response
*/
public function store()
{
$rules = array(
'title' => 'required',
'message' => 'required',
'publish' => 'required'
);
$validator = Validator::make(Input::all(), $rules);
//process the storage
if ($validator->fails())
{
Session::flash('error_message', 'Fout:' . $validator->errors());
return Redirect::to('admin/news/create')->withErrors($validator);
}else{
//store
$news = new News;
$news->title = Input::get('title');
$news->message = Input::get('message');
$news->img_url = Input::file('img')->getClientOriginalName();
$news->posted_by = Auth::user()->username;
$news->published_at = time();
$news->published = Input::get('publish');
$news->save();
//save the image
$destinationPath = 'public/pictures/news';
if (Input::hasFile('img'))
{
$file = Input::file('img');
$file->move('public/pictures/news', $file->getClientOriginalName());
}
//redirect
Session::flash('success', 'Nieuws succesvol aangemaakt!');
return Redirect::to('admin/news/create');
}
}
/**
* Display the specified resource.
*
* #param int $id
* #return Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* #param int $id
* #return Response
*/
public function update($id)
{
//
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return Response
*/
public function destroy($id)
{
//
}
}
My create.blade.php
<div class="portlet-body form">
{{ Form::open(['method'=>'POST', 'role' => 'form', 'files' => true]) }}
<div class="form-body">
<div class="form-group">
<label>Titel</label>
<input type="text" class="form-control" name="title" placeholder="Titel komt hier">
</div>
<div class="form-group">
<label>Textarea</label>
<textarea class="form-control" name="message" rows="5" placeholder="Uw bericht..."></textarea>
</div>
<div class="form-group">
<label>Nieuws afbeelding</label>
{{ Form::file('img') }}
</div>
<div class="form-group">
<label>Bericht publiceren?</label>
<div class="radio-list">
<label class="radio-inline">
<span>
{{ Form::radio('publish', '1') }}
</span>
<b style="color:green">Publiceren</b>
</label>
<label class="radio-inline">
<span>
{{ Form::radio('publish', '0', true) }}
</span>
<b style="color:red">Niet publiceren</b>
</label>
</div>
</div>
</div>
<div class="form-actions">
<input type="submit" class="btn green" value="Oplsaan" />
</div>
{{ Form::close() }}
</div>
Then It all work!
Thanks to Matt Barber for the help!

Categories