How to put input textarea in an array? (Laravel 5.3) - php

My view blade is like this :
#foreach($reviews as $key => $review)
...
<div class="form-group">
{!! Form::open(['route' => 'message.review.update', 'method' => 'post', 'id' => 'reviewform']) !!}
<label for="review" class="sr-only">Review</label>
{!! Form::textarea('review', null, ['class' => 'form-control', 'id' => 'review', 'rows'=>3,'required'=>'required']) !!}
#if ($errors->has('review'))
<span class="help-block">
<strong>{{ $errors->first('review') }}</strong>
</span>
#endif
{!! Form::hidden('id', $review->_id) !!}
{!! Form::hidden('store', $review->store_id) !!}
{!! Form::close() !!}
</div>
...
#endforeach
My routes is like this :
Route::group(['prefix' => 'message','as'=>'message.'],function(){
Route::post('review/update', ['as'=>'review.update','uses'=>'ReviewController#update']);
});
My controller to update is like this :
public function update(CreateReviewRequest $request)
{
$param = $request->only('id', 'review', 'store');
...
}
Before update, it will call CreateReviewRequest to validation
My CreateReviewRequest is like this :
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CreateReviewRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'review'=>'required|max:300'
];
}
}
When, only one data, I input comment and submit, it works
But, when more than one data, it does not works
There exist error like this :
An invalid form control with name='review' is not focusable.
How can I solve it?

You made some mistakes here... In HTML IDs MUST be unique. You can't put "review" as id for all your textareas... My comment was about to use an array as name like this name=review[], and in the ID add dynamically the $key at the end of the id to make them unique.
This will give you something like this :
<textarea name="review[]" class="form-control" id="review0" rows="3" required></textarea>
<textarea name="review[]" class="form-control" id="review1" rows="3" required></textarea>
<textarea name="review[]" class="form-control" id="review2" rows="3" required></textarea>
EDIT
I've just founded this stackoverflow topic. Could you try to add novalidate attribute in the <form>?
<form name="myform" novalidate>
Something like this in your case :
{!! Form::open(['route' => 'message.review.update', 'method' => 'post', 'id' => 'reviewform', 'novalidate']) !!}

VIEW
{!! Form::textarea('review[]', null, ['class' => 'form-control', 'id' => 'review', 'rows'=>3,'required'=>'required']) !!}
or
<textarea name="review[]" class="form-control" id="review" rows="3" required></textarea>
You must insert name field like array empty, when you will submit the form you can get all values in your controller calling:
CONTROLLER
public function update(Request $request)
{
// Validate the form
$this->validate($request, [
'review' => 'required',
]);
// get inputs
$review_input = $request->get('review');
dd($review_input); // see if it work
}

Related

Get old or user variable value on form after custom request validation error, view with two different forms

EDIT:
Your solutions are working for text inputs and textareas, but checkboxes are not working correctly for me.
This was my original checkbox:
{{ Form::checkbox('active', true, (isset($user->active)) ? old($user->active) : true, ['class' => 'custom-control-input', 'id' => 'active']) }}
I've tried a lot of possible solutions like adding old('active', isset($user) ? $user->active: true) instead, but when an error occurs I lose the values from this input. On the controller I was checking this, but if I change the input to the 'new solution' active is always false on my db:
if(!array_key_exists('active', $validated)){
$validated = array_add($validated, 'active', '0');
}
ORIGINAL QUESTION (PARTIALLY RESOLVED):
I have one blade view call edit with two forms, but each one is calling his own method/route. One form is for edit/store the user and the other is a form in a modal to change the user password. When I change the password and no validation error happens, the other form still has all of his values that is getting from old() or $user variable via index method. But if for example the passwords do not match, a validation error occurs, and the values from the edit/store user form disappear.
Forms are pretty simple (remember, they are on the same view, and the one that is giving me problems is the edit/create one), and each one call a different method from UserController
Form 1 for edit users (simplified)
#if($user->exists)
{{ Form::model($user, ['route' => ['users.update', $user], 'class' => 'needs-validation', 'novalidate'=>'']) }}
#method('PATCH')
#else
{{ Form::model($user, ['route' => ['users.store'], 'class' => 'needs-validation', 'novalidate'=>'']) }}
#method('POST')
#endif
#csrf
<div class="form-group">
<div class="row">
<div class="col-sm-4">
{{ Form::label('cif', __('users.cif'), ['class' => 'form-label']) }}
{{ Form::text('cif', (isset($user->cif)) ? old($user->cif) : '', ['class' => 'form-control', 'required','maxlength'=>'12', 'minlength'=>'9']) }}
{{ Form::hidden('validate','', ['class' => 'form-control', 'required', 'id'=>'validate']) }}
</div>
<div class="col-sm-6">
{{ Form::label('name', __('users.name'), ['class' => 'form-label']) }}
{{ Form::text('name', (isset($user->name)) ? old($user->name) : '', ['class' => 'form-control','required','maxlength'=>'255']) }}
</div>
<div class="col-sm-2">
{{ Form::label('initials', __('users.initials'), ['class' => 'form-label']) }}
{{ Form::text('initials', (isset($user->initials)) ? old($user->initials) : '', ['class' => 'form-control', 'required','maxlength'=>'5']) }}
</div>
</div>
<div class="col-sm-6">
{{ Form::label('province', __('users.province'), ['class' => 'form-label']) }}
{{ Form::text('province', (isset($user->city)) ? $user->city->province->name : '', ['class' => 'form-control', 'disabled'=>'']) }}
</div>
{!! Form::close() !!}
Form 2: Update password
<form id="change-password" action="{{route('users.change.password', $user)}}" method="POST">
#csrf
<div class="modal-body">
<div class="card-body">
<div class="panel-tag">
<p>Las contraseñas debe de coincidir y tener más de 8 carácteres</p>
</div>
<div class="form-group row">
<label for="password" class="col-md-4 col-form-label text-md-right">Contraseña</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control #error('password') is-invalid #enderror" name="password" required autocomplete="new-password" minlength="8">
#error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
</div>
</div>
<div class="form-group row">
<label for="password-confirmation" class="col-md-4 col-form-label text-md-right">Confirmar contraseña</label>
<div class="col-md-6">
<input id="password-confirmation" type="password" class="form-control #error('password') is-invalid #enderror" name="password_confirmation" required autocomplete="new-password" minlength="8">
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button id="change" type="submit" form="change-password" class="btn btn-primary">Confirmar</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Cancelar</button>
</div>
</form>
UserController I'm going to paste two methods, one for store/user, the other for change the password. Update method is very similar.
public function store(StoreUserRequest $request)
{
if( $request['validate'] == 1 ){
$validated = $request->validated();
$validated['password'] = Hash::make($validated['password']);
$id = DB::table('users')->insertGetId($validated);
return redirect()->route('users.edit',['user'=>$id])->with('status', 'created');
} else {
return redirect()->back()->withInput()->with('status', 'error_dni');
}
}
public function changePassword(PasswordUserRequest $request, User $user)
{ // HERE IS WHERE I THINK IS THE PROBLEM, IF VALIDATION FAILS (FOR EXAMPLE PASSWORD CONFIRM) VALUES FROM THE OTHER FORM DISAPPEAR AND IT DOESNT GET INTO THIS METHOD
$pass = Hash::make($request->password);
$user->password = $pass;
$action = $user->save();
if ($action) {
return redirect()->back()->with('status', 'change_password_ok');
}
return redirect()->back()->with('status', 'error_change_password');
}
PasswordUserRequest This is the request to validate the password form
public function rules()
{
return [
'password' => 'required|string|confirmed';
];
}
The route would be something like:
users/{user}/edit
I've spent all day trying to fix this and still didn't found a solution. My english is not very good so please tell me if I'm not explaining something correctly and I will edit the question.
Thanks and hope that I can find a solution.
old values are from input name
<input type="text" name="input" value="{{old('input')}}"
example
<div class="col-sm-4">
{{ Form::label('cif', __('users.cif'), ['class' => 'form-label']) }}
{{ Form::text('cif', old('cif', $user->cif ?? ''), ['class' => 'form-control', 'required','maxlength'=>'12', 'minlength'=>'9']) }}
{{ Form::hidden('validate','', ['class' => 'form-control', 'required', 'id'=>'validate']) }}
</div>
//$user->cif ?? '' <- left or right hand-side operand, return right-hand if left is null or undefined
//old('input', $user->cif ?? '') <- if old input available, use old input, if not, $user will be displayed
form::checkbox:
First argument : name
Second argument : value
Third argument : checked or not checked (true or false)
Fourth argument : additional attributes
note that value is attribute(value) and checked is attribute(checked)
then
{{ Form::checkbox('active', true, (isset($user->active)) ? $user->active : true, ['class' => 'custom-control-input', 'id' => 'active']) }}
//2nd parameter (true) will always set checkbox value to 1(true)
//(isset($user->active)) ? $user->active : true <- will set default to true (checked) if $user is null or undefined
//maybe try
{{ Form::checkbox('active', $user->active ?? false, $user->active ?? false) }}
//if $user != null, put $user->active else put false
//if $user != null, set checked value based on $user->active else put false
in html looks like this
<input type="checkbox" value="1" checked="checked">
then you need to add inline event onchange="$(this).is(':checked') ? $(this).val(1) : $(this).val(0);" in the 4th parameter of form::checkbox to change the default on runtime
If I understood all correctly, you should do this way:
old('name', isset($user) ? $user->name : ''),
Here you trying to get old name input, and if it doesn't exist, in second parameter od old function you are getting default value, which is user's name in case of user exists
There is documentation, which can help you to understand much more.

Update article laravel

Controller article
public function update(Request $request, Article $article){
$article->update($request->except('slug', 'image_path'));
if ($request->hasFile('image_path')) {
$image = $request->file('image_path');
$new_name = rand() . '.' . $image->getClientOriginalExtension();
$image->move(public_path('images'), $new_name);
$article->image_path = $new_name;
$article->save();
}
$article->categories()->detach();
if ($request->has('categories')) {
$article->categories()->attach($request->input('categories'));
}
$user=auth()->user();
return redirect()->back()->with('message', 'Raksts atjaunots!');
}
public function edit(Article $article){
$user=auth()->user();
return view('edit',[
'article' => $article,
'categories' => Category::with('children')->where('parent_id',0)->get(),
'delimiter' => ''
]);
}
edit blade
<form class="form-horizontal" action="{{route('update', $article)}}" method="post" enctype="multipart/form-data" style="display: flex;justify-content: center;flex-direction: column;">
<input type="hidden" name="_method" value="put">
{{ csrf_field() }}
{{-- Form include --}}
<img src="{{URL::to('/images').'/'.$article->image_path}}" alt="">
#include('partials.form')
<input type="hidden" name="modified_by" value="{{Auth::id()}}">
</form>
link to the form
<tbody>
#foreach ($articles_suggest_user as $article)
<a class="btn btn-default" href="{{route('edit', $article)}}"><i class="fa fa-edit"></i></a>
<?php } ?>
#endforeach
</tbody>
web.php
Route::get('/home/edit/{id}','Controller_Article_parents#edit', function () {
return view('/home/edit');
})->name('edit');
Route::get('/home/update/','Controller_Article_parents#update', function () {
return view('/home');
})->name('update');
When i clicked the link, i move to for example this url http://127.0.0.1:8000/home/edit/190
But my form is empty... input empty. How I can do when I open form it's display me input information ?
When click my link its display me form, but form is empty.
form example
<div class="rtq">
<label for="parent_id">Cat</label>
<span class="required">*</span>
<select
id="parent_id"
class="form-control"
name="categories[]"
multiple=""
required
>
#include('admin.categories.partials.categories',
['categories' => $categories,
'current' => $article,
'delimiter' => $delimiter])
</select>
</div>
<div class="rtq">
<label for="">Descript</label>
<textarea
name="description_short"
class="form-control"
id="description_short"
>
{{ $article->description_short ?? "" }}
</textarea>
</div>
It my form . Mini example
If you want to redirect with form input, you can use the withInput() function
return back()->withInput();
https://laravel.com/docs/7.x/redirects#creating-redirects
Now, this function is designed to be used with form validation and may not be what you want.
What I have done in the past when combining create & edit views into a single template is something like this:
{!! Form::text('name', isset($model) ? $model->name : null, [
'class' => 'form-control',
'placeholder' => 'Please fill out this field &hellips;',
'required' => true
]) !!}
This uses the Laravel Collective HTML library. However the principle is the same if you are using raw hmtl like so:
<input type="text" value="{{ isset($model) ? $model->name : null }}">
Round 2 Electric Boogaloo
You aren't returning a variable called $article to your edit.blade.php.
Round 3 Apple Tree
Originally, you appeared to be calling both a controller action AND also a callback function. Stick to the controller action only like so:
Route::get('/home/edit/{id}','Controller_Article_parents#edit')->name('edit');
Then within your edit() function on the Controller you will want to do this:
public function edit ($id) {
return view('/home/edit', [
'article' => Article::find($id)
]);
}

Saving data into database using a form with multiple pages and one to many relationship laravel

I have 2 form blade.php to get data and save into database. But I am doing a one to many relationship where there is one bear and many fish
But I don't know how to do it properly, previously I used this:
$bear = Bear::create(['Name' => $request->input('name_of_bear')]);
$bear->fishes()->create(['type_of_fish' => $fishType);
But it is only for 1 page, but what if I have 2 page, what do I need to do? Do I use associate, flash, session or something else to save the data into the database?
If possible can I also have some example for reference. Thank you
page1.blade.php:
{!! Form::open(['url' => 'page1/submit']) !!}
<div class="form-group">
{{Form::label('Name', 'Name of Bear ')}}
{{Form::text('Name', '', ['class' => 'form-control'])}}
</div>
<div class="form-group">
{{Form::label('bear_type', 'Type of Bear ')}}
{{Form::text('bear_type', '', ['class' => 'form-control'])}}
</div>
<div class="form-group">
{{Form::submit('Next', ['class' => 'btn btn-primary'])}}
</div>
{!! Form::close() !!}
Controller for page1:
public function submit(Request $request)
{
$data = array();
$data['Name'] = $request->Name;
$data['bear_type'] = $request->bear_type;
$BearDetails = bear::create($data);
return redirect('http://test.dev/page2');
}
page2.blade.php
{!! Form::open(['url' => 'page2/submit']) !!}
<div class="form-group">
{{ Form::label('type_of_fish','Type of fish bear eat')}}
<input type="checkbox" id="inlineCheckbox1" name="type_of_fish[]" value="Salmon"> Salmon
<input type="checkbox" id="inlineCheckbox2" name="type_of_fish[]" value="Sardine"> Sardine
</div>
{{ Form::label('fish_location','Where is the fish located near at?')}}
<input type="checkbox" id="inlineCheckbox1" name="fish_location[]" value="Canyon"> Canyon
<input type="checkbox" id="inlineCheckbox2" name="fish_location[]" value="Rainforest"> Rainforest
</div>
{!! Form::close() !!}
</div>
<div class="form-group">
{{Form::submit('Submit', ['class' => 'btn btn-primary'])}}
</div>
Controller for page2:
$test = array();
$test['fish_location'] = $request->fish_location;
$test['type_of_fish'] = $request->type_of_fish;
$bear = bear::create($data);
$fish = fish::create($test);
$fish->user_particular()->associate($bear);
$fish->save();
return ('thank you');
}
bear model:
class bear extends Eloquent
{
protected $primaryKey = 'id';
public function fishs() {
return $this->hasMany('App\fish,'bear_id');
}
}
fish model:
class fish extends Eloquent
{
protected $fillable = array('name', 'bear_id');
// DEFINE RELATIONSHIPS
public function bears() {
return $this->belongsTo('App\bear);
}
}

Laravel form validation doesn't seem to work

I'm making my first form in Laravel and the generation of the form is all working. It's just that the store function seems to blindly return the user to my contact page irrelevant of the result of the form validation.
So if the email address posted isn't an email but a random string I still get returned to the /contact page with the thank you message being sent to the view.
My controller looks like this:
namespace App\Http\Controllers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\View;
use Illuminate\Support\Facades\DB;
use App\Http\Requests\ContactFormRequest;
class ContactController extends Controller {
public function create(){
return view('contact');
}
public function store(ContactFormRequest $request) {
return \Redirect::route('contact')
->with('message', 'Thanks for contacting us!');
}
}
And the form handler like this:
namespace App\Http\Requests;
use Illuminate\Http\Request;
class ContactFormRequest extends Request {
public function authorize() {
return true; // don't need to be registered to run form so true
}
public function rules() {
return [
'email' => 'required|email',
];
}
}
This is controlled by the following routes
if (config('app.tan_site_page_contact')===true){
Route::get('/contact', ['as' => 'contact', 'uses' => 'ContactController#create']);
Route::post('/contact', ['as' => 'contact_store', 'uses' => 'ContactController#store']);
});
And the form like this:
<ul>
#foreach($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
#if(Session::has('message'))
<div class="alert alert-info">
{{Session::get('message')}}
</div>
#endif
{!! Form::open(array('route' => 'contact_store', 'id' => 'contactCallMeForm')) !!}
{!! Form::label('Your E-mail Address') !!}
{!! Form::text('email', null, array('required', 'class'=>'form-control', 'placeholder'=>'Your e-mail address')) !!}
{!! Form::submit('Contact Us!', array('class'=>'btn btn-primary')) !!}
{!! Form::close() !!}
The form html seems fine,with a token and valid url
<form method="POST" action="http://localhost/contact" accept-charset="UTF-8" id="contactCallMeForm" novalidate="">
<input name="_token" type="hidden" value="VNHchLZhfsXadVZXCZWHGdAuJ4zgmO6cDJIGhR59">
<label for="Your E-mail Address">Your E-mail Address</label>
<input required="required" class="form-control" placeholder="Your e-mail address" name="email" type="text">
<input class="btn btn-primary" type="submit" value="Contact Us!">
</form>
The problem here is your ContactFormRequest class.
You extends it from invalid Request class. You extend it from \Illuminate\Http\Request class but you should extend it from \Illuminate\Foundation\Http\FormRequest (or \App\Http\Requests\Request class)

Laravel 5.2 : Getting form fields in controller method

I have the following form :
{!! Form::open(['action' => 'PublicController#showProfile','method' => 'post', 'class' => 'form-horizontal']) !!}
{!! Form::token(); !!}
<input type="text" class="form-control" name="from">
<span class="input-group-addon"> to </span>
<input type="text" class="form-control" name="to">
<button type="submit" class="btn blue">Query</button>
{!! Form::close() !!}
In my controller I am getting the form fields like this :
public function showProfile(Request $request)
{
$to = $request->get("to");
$from = $request->get("from");
$giftReceived = App\GiftSent::whereBetween('created_at', [$from, $to])->get();
dd($from);
return view('user.profile',compact('giftReceived'));
}
In the above code dd($from) comes null
Am i missing something ?
First of all, as stated in your comments, you are using Route::get and submitting the form as POST which is obviously wrong. So, you should probably get MethodNotAllowedException
So, kindly change the line to
{!! Form::open(['action' => 'PublicController#showProfile','method' => 'GET', 'class' => 'form-horizontal']) !!}
In any case, instead of using Laravel's Request Class, prefer using the helper function request()
So, basically, it should be like
public function showProfile() {
$from = request()->get('from');
$to = request()->get('to');
dd($from, $to);
}
Everything should work fine now :)
If your post data is sending to controller, you can access the values like:
// Get all request data via method POST.
$requestData = Request::instance()->request->all();
dd($requestData['from']);
dd($requestData['to']);

Categories