After reflecting, I would like to display changes in form page - laravel

I would like to make a form.
After submitting the data,Redirect to the same page and reflect a change.
I thought return redirect should be a good way.
but it seems need to fetching the DB.
because 'ErrorException
Trying to get property 'id' of non-object (View:'error happens.
writing $user = \DB::table('users')->where('id', $request->id)... twice
is redundancy and cheesy.
Is there any good way to implement this.
class CertainController extends Controller
{
public function index(Request $request)
{
$user = \DB::table('users')->where('id', $request->id)->first();
$data = ['user' => $user];
return view('user.detail',$data);
}
public function update(Request $request)
{
\DB::table('users')
->where('id', $request->id)
->update([
$request->name => $request->value
]);
return redirect(route('user.detail', [
'user_id' => $request->id,
]));
}
}
web.php
Route::get('/user_detail', 'CertainController#index')->name('user.detail');
Route::get('/user_detail/update', 'CertainController#update')->name('user.detail.update');
blade
<form method ="GET" action={{ route('user.detail.update')}}>
<div class="form-group row">
<label>name</label>
<div class="col-md-6">
<input type = "hidden" name ="id" value="{{ $user->id }}"/>
<input type = "hidden" name = "column" value="name">
<input id="name" type="text" class="form-control #error('name') is-invalid #enderror" name="name" value="{{ $user->name }}" required autocomplete="name">
#error('')
{{ $message }}
#enderror
<button type = "submit" class ="button">submit</button>
</div>
</div>
</form>

You are looking for id in the index method,
$request->id
^^
But you are sending user_id from update method.
'user_id' => $request->id,
^^^^^
In a simple way, you can just do
return back();
here, back() is a helper function, which redirect back to where it came from.

Related

Undefined variable: posts when passing parameter from controller to view

I'm trying to create a search function in Laravel and its returning me with "undefined variable: posts" when I do foreach on my view.
My code:
Post Model
class Post extends Model {
protected $fillable = [
'creator',
'post_url',
'books',
'likes',
'created_at'
];
public function user() { return $this->belongsTo(User::class); }
}
Homeview:
<form action="{{ url('/search') }}" method="get">
<input type="text" class="search-text form-control form-control-lg" name="q" placeholder="Search" required>
</form>
Controller:
public function search($keyword)
{
$result = Post::where('books', 'LIKE', "'%' . $keyword . '%'")->get();
return view('/search', ['posts' => $result]);
}
Route:
Route::get('/search/{keyword}', 'SearchController#search');
Searchview:
#foreach($posts as $post)
<div class="post">{{ $post->id }}</div>
#endforeach
What am I doing wrong here?
This might help you out.
Homeview.blade.php
<form action="/search" method="POST">
#csrf // include your csrf token
<input type="text" class="search-text form-control form-control-lg" id="q" name="q" placeholder="Search" required>
</form>
Searchview.blade.php
<!-- or did you return a collection? -->
#if( $posts->count() > 1 )
<!-- then loop through the posts -->
#foreach( $posts as $post )
<div class="post"> {{ $post->id }} </div>
#endforeach
#else
#if( !empty($posts) )
<div class="post"> {{ $post->id }} </div>
#endif
#endif
Routes/web.php
Route::post('/search', 'PostsController#show')->name('posts.show');
PostsController
use App\Post;
public function show( Request $request )
{
$result = Post::where("books", "LIKE", "%{$request->input('q')}%")->get();
// Uncomment the following line to see if you are returning any data
// dd($result);
// Did you return any results?
return view('searchview', ['posts' => $result]);
}
The reason it wasn't working,
Route::get('/search/{keyword}', 'SearchController#search');
In your route file you were looking for a {keyword} that was never passed by the form. Your form action is action="{{ url('/search') }}". A get variable will not be picked up by a route and if it was you called the input 'q' anyway.
So then in your controller you were looking for the keyword being passed that is never passed in.
public function search($keyword)
Instead the correct thing to do is pass in the Request object like so
public function search(Request $request)
Then use $request->input('q') to retrieve the passed value through your form.
In your example $keyword would always have been blank.
Corrected code
Homeview:
<form action="{{ url('/search') }}" method="get">
<input type="text" class="search-text form-control form-control-lg" name="q" placeholder="Search" required>
</form>
Controller:
public function search(Request $request)
{
$result = Post::where('books', 'LIKE', "%{$request->input('q')}%")->get();
return view('/search', ['posts' => $result]);
}
Route:
Route::get('/search', 'SearchController#search');
Searchview:
#foreach($posts as $post)
<div class="post">{{ $post->id }}</div>
#endforeach
try:
return view('/search')->with('posts', $result);
Or even better with dinamic vars.
return view('/search')->withPosts($result);

"No message" error laravel - trying to update user account information

I'm receiving the error "MethodNotAllowedHttpException
No message" on submit of my user's form, which is meant to update the user's table. I have two post forms on the same page and two post routes, would that have something to do with it?
I will include all the routes and another form that might be conflicting with it.
web.php
Route::get('profile','userController#profile');
Route::post('profile', 'userController#update_avatar');
Route::post('profile-update', 'userController#update_account'); //this ones not working
userController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
use Auth;
use Image;
class UserController extends Controller
{
//
public function profile()
{
return view('profile', array('user' => Auth::user()) );
}
public function update_avatar(Request $request)
{
if($request->hasFile('avatar')){
$avatar = $request->file('avatar');
$filename = time() . '.' . $avatar->getClientOriginalExtension();
Image::make($avatar)->resize(300,300)->save( public_path('/uploads/avatars/' . $filename) );
$user = Auth::user();
$user->avatar = $filename;
$user->save();
}
return view('profile', array('user' => Auth::user()) );
}
public function update_account(Request $request, $id) //the function with the error
{
User::update([
'id' => Auth::user()->id,
'name' => $request->name,
'email' => $request->email
]);
return redirect('/profile');
}
}
profile.blade.php
<img src="/uploads/avatars/{{ $user->avatar }}" style="width:150px;height:150px;float:left;border-radius:50%;margin-right:25px">
<h2>{{ $user->name }}'s Profile</h2>
<form enctype="multipart/form-data" action="/profile" method="post">
<label>Update Profile Image</label>
<input type="file" name="avatar">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="submit" class=" btn btn-sm btn-light" style="color:#2b2b2b;" value="Update Image">
</form>
<form method="post" action="/profile-update"> <!-- The form with the error -->
{{ method_field('put') }}
{{ csrf_field() }}
<input type="hidden" name="_method" value="PUT" />
<label>Username</label>
<input type="text" name="name" class="form-control" value="{{ $user->name }}">
<label>Email</label>
<input type="email" name="email" class="form-control" value="{{ $user->email }}">
<input type="submit" id="update-account" class="btn btn-success" value="Update">
</form>
try this method:
public function update_account(Request $request, $id)
{
$user = User::find($id)
$user->name = $request->name;
$user->email = $request->email;
$user->update();
return redirect('/profile');
}
You don't have any route which can handle the PUT request for "profile-update". In your form you have defined the following function.
{{ method_field('put') }}
This helper function generate an hidden input field which will be used by Laravel to process the current request only as PUT.
To make this work, you either have to make your make your request POST by removing the above helper function or change your route method to PUT.
Route::put('profile-update', 'userController#update_account');
For those that might need the same answer, to fix this I had to play about with it for quite some time and used bits from the suggested answers to solve the issue completely.
I changed the route method to put in web.php.
Replaced my update_account function with #TonzFale answer but replaced $user = User::find($id)with $user = User::find(Auth::user()->id);.

Validating with all requests

I have this form:
<form role="form" method="POST" action="{{url('/books')}}">
{!! csrf_field() !!}
<div class="col-sm-5">
<label>Book Name:</label> <input type="text" class="form-control" name="name"><br>
<label>Pages:</label> <input class="form-control" type="text" name="pages"><br>
<label>Price in Rs:</label> <input type="text" class="form-control" name="price"><br>
<input type="submit" class="btn btn-default"><br>
</div>
</form>
And i'm trying to validate if all the form fields are set and not null. similar to isset(). but, else statement is not executed even if submitted without entering values in any inputs. Isn't $request->all() supposed to do so.
public function store(Request $request)
{
if($request->all())
{
$book=new Book();
$book->name=$request->name;
$book->pages=$request->pages;
$book->price=$request->price;
if($book->save())
{
return Response::json(true);
}
else
{
return Response::json(false);
}
}
else
{
return "norequest";
}
}
You can use the ValidatesRequests trait of Laravel.
The code in your store might look like this:
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required',
'pages' => 'required',
'price' => 'required'
]);
// the rest of your code goes here....
}
Here, the above code will accomplish what you want. So, no need to use $request->all() to check if all fields are set and not null.
Hope this helps.

Laravel - How to handle errors on PUT form?

I am working with laravel 5.2 and want to validate some data in an edit form. I goal should be to display the errors and keep the wrong data in the input fields.
My issue is that the input is validated by ContentRequest and the FormRequest returns
$this->redirector->to($this->getRedirectUrl())
->withInput($this->except($this->dontFlash))
->withErrors($errors, $this->errorBag);
which is fine so far. Next step the edit action in the controller is called and all parameters are overwritten.
What I have currently done:
ContentController:
public function edit($id)
{
$content = Content::find($id);
return view('contents.edit', ['content' => $content]);
}
public function update(ContentRequest $request, $id)
{
$content = Content::find($id);
foreach (array_keys(array_except($this->fields, ['content'])) as $field) {
$content->$field = $request->get($field);
}
$content->save();
return redirect(URL::route('manage.contents.edit', array('content' => $content->id)))
->withSuccess("Changes saved.");
}
ContentRequest:
class ContentRequest extends Request
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'title' => 'required|min:3',
'body' => 'required|min:3'
];
}
}
How can I fix this? The form looks like this:
<form action="{!! URL::route('manage.contents.update', array('content' => $content->slug)) !!}"
id="site-form" class="form-horizontal" method="POST">
{!! method_field('PUT') !!}
{!! csrf_field() !!}
<div class="form-group {{ $errors->has('title') ? 'has-error' : '' }}">
<label for="title" class="col-sm-2 control-label">Title</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="title" id="title" placeholder="Title"
value="{{ $content->title }}">
#if ($errors->has('title'))
<span class="help-block">
<strong>{{ $errors->first('title') }}</strong>
</span>
#endif
</div>
</div>
</form>
Try something like the following:
<input
type="text"
class="form-control"
name="title"
id="title"
placeholder="Title"
value="{{ old('title', $content->title) }}" />
Note the value attribute. Also check the documentation and find Retrieving Old Data.

How to use custom validation attributes on an array of inputs

I'm using Laravel to build a form that contains an array of inputs and I’m having difficulty in showing the translated attribute name when a validation error occurs. For simplicity sake I will post a simple example of my problem.
Form inside the view:
<form method="POST" action="{{ route('photo.store') }}" accept-charset="UTF-8" role="form">
<input name="_token" type="hidden" value="{{ csrf_token() }}">
<div class="row">
<div class="col-lg-12">
<div class="form-group{{ $errors->has('testfield') ? ' has-error' : '' }}">
<label class="control-label"
for="testfield">{{ trans('validation.attributes.testfield') }}</label>
<input class="form-control" name="testfield" type="text" id="testfield"
value="{{ old('testfield') }}">
#if ($errors->has('testfield'))
<p class="help-block">{{ $errors->first('testfield') }}</p>
#endif
</div>
</div>
<div class="col-lg-12">
<div class="form-group{{ $errors->has('testfieldarray.0') ? ' has-error' : '' }}">
<label class="control-label"
for="testfieldarray-0">{{ trans('validation.attributes.testfieldarray') }}</label>
<input class="form-control" name="testfieldarray[]" type="text" id="testfieldarray-0"
value="{{ old('testfieldarray.0') }}">
#if ($errors->has('testfieldarray.0'))
<p class="help-block">{{ $errors->first('testfieldarray.0') }}</p>
#endif
</div>
</div>
<div class="col-lg-12">
<div class="form-group{{ $errors->has('testfieldarray.1') ? ' has-error' : '' }}">
<label class="control-label"
for="testfieldarray-1">{{ trans('validation.attributes.testfieldarray') }}</label>
<input class="form-control" name="testfieldarray[]" type="text" id="testfieldarray-1"
value="{{ old('testfieldarray.1') }}">
#if ($errors->has('testfieldarray.1'))
<p class="help-block">{{ $errors->first('testfieldarray.1') }}</p>
#endif
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<input class="btn btn-primary" type="submit" value="Gravar">
</div>
</div>
Rules function in the form request:
public function rules() {
$rules = [
'testfield' => array('required'),
];
foreach ($this->request->get('testfieldarray') as $key => $val) {
$rules['testfieldarray.' . $key] = array('required');
}
return $rules;
}
lang/en/validation.php
'attributes' => [
'testfield' => 'Test Field',
'testfieldarray' => 'Test Field Array',
],
The validation is performed correctly, as do the error messages. The only problem in the error messages is the name of the attribute displayed. In both array inputs, the attribute name inserted in the message is 'testfieldarray.0' and 'testfieldarray.1' instead of 'Test Field Array'. I already tried to add on the language file 'testfieldarray.0' => 'Test Field Array', 'testfieldarray.1' => 'Test Field Array', but the messages remain unchanged. Is there a way to pass the attribute names correctly?
Just see the example to add custom rules for integer type value check of array
Open the file
/resources/lang/en/validation.php
Then add the custom message.
// add it before "accepted" message.
'numericarray' => 'The :attribute must be numeric array value.',
Again Open another file to add custom validation rules.
/app/Providers/AppServiceProvider.php
So, add the custom validation code in the boot function.
public function boot()
{
$this->app['validator']->extend('numericarray', function ($attribute, $value, $parameters)
{
foreach ($value as $v) {
if (!is_int($v)) {
return false;
}
}
return true;
});
}
Now you can use the numericarray for integer type value check of array.
$this->validate($request, [
'input_filed_1' => 'required',
'input_filed_2' => 'numericarray'
]);
----------- Best of Luck --------------
1-if you split the validation in file request then add the method attributes and set the value of each key like this :
public function attributes()
{
return [
'name'=>'title',
];
}
2- but if don't split the validation of the request then you just need to make variable attributes and pass the value of items like this :
$rules = [
'account_number' => ['required','digits:10','max:10','unique:bank_details']
];
$messages = [];
$attributes = [
'account_number' => 'Mobile number',
];
$request->validate($rules,$messages,$attributes);
// OR
$validator = Validator::make($request->all(), $rules, $messages, $attributes);
Use custom error messages inside your parent method....
public function <metod>(Request $request) {
$rules = [
'testfield' => 'required'
];
$messages = [];
foreach ($request->input('testfieldarray') as $key => $val) {
$rules['testfieldarray.' . $key] = 'required';
$messages['testfieldarray.' . $key . '.required'] = 'Test field '.$key.' is required';
}
$validator = Validator::make($request->all(), $rules,$messages);
if ($validator->fails()) {
$request->flash();
return redirect()
->back()
->withInput()
->withErrors($validator);
}
}
}

Resources