How to add an array in view and pass it to controller - laravel

Hello i am wondering if its possible to have an array in view blade that is filled with values that user selects and then to be passed to controller. I am asking if its possible to do such a thing and avoid this type of code i already have that works:
foreach ($request->products as $index => $product) {
$values[] = [
'order_id' => $order->id,
'product_id' => $product,
'amount' => $request->amount[$index],
];
So for the foreach i dont need to write $index => $product
This is the request that comes from view:
$request->validate([
'order_number' => 'required',
'client_id' => 'required|exists:clients,id',
'description' => 'required',
'products' => 'required|exists:products,id',
'amount' => 'required',
]);
And this is the view im using:
<div class="row mb-3">
<label for="products" class="col-md-4 col-form-label text-md-end">{{ __('Product') }}</label>
<div class="col-md-6">
<select name="products[]" id="products" type="text" class="form-control #error('products') is-invalid #enderror" required autocomplete="products">
#foreach($products as $product)
<option value="{{$product->id}}">{{$product->name}}</option>
#endforeach
</select>
#error('products')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
</div>
</div>
<div class="row mb-3">
<label for="amount" class="col-md-4 col-form-label text-md-end">{{ __('Amount') }}</label>
<div class="col-md-6">
<input id="amount" type="text" class="form-control #error('amount') is-invalid #enderror" name="amount[]" required autocomplete="amount">
#error('amount')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
</div>
</div>

We can use the input name to create an associative array using the product id as the key in the array.
You can achieve this by subbing in the product id for the array index and labelling the fields that will go into it.
<input type="number" name="products[ {{$product_id}} ][amount]">
<input type="text" name="products[ {{$product_id}} ][otherField]">
This will product a structure like
["products"]=> array(2)
{ [101]=> array(2) {
["amount"]=> string(2) "10" ["otherField"]=> string(7) "LABEL 1" }
[102]=> array(2) {
["amount"]=> string(2) "20" ["otherField"]=> string(7) "LABEL 2" }
}
While you will still have to iterate using foreach($request->products as $productID => $data) the data structure is all relational regarding where the data is stored.

If I understand your question correctly, you want to avoid JQuery? It depends on what environment and language you're using. In ASP .NET Core you can use a hidden input field and pass something through as text.
<input hidden type="text" name="productsString" value="#JsonSerializer.Serialize(products)" />
Then in your controller you can deserialize it (C# example).
var products = JsonSerializer.Deserialize<Object>(productsString);
Maybe that's what you're looking for but it really depends on what you're doing, which I'm not sure about.

Related

Frontend form Laravel Nova

I really like Laravel Nova but it's really complicated for a newbie like me to do something on the frontend that interacts with backend resources.
Can anyone tell me how to make a form insert data into a table from the frontend? Do I need to create a new external model? Can't interact with Nova resources?
Thanks in advance for enlightening me.
My form:
<form wire:submit.prevent="submit">
<div class="form-group">
<input type="text" class="form-control" id="code" placeholder="Introduzca código " name="code">
#error('code') <span class="text-danger">{{ $message }}</span> #enderror
</div><br>
<div class="form-group">
<input type="text" class="form-control" id="ip" placeholder="Introduzca IP " name="ip">
#error('ip') <span class="text-danger">{{ $message }}</span> #enderror
</div><br>
<div class="form-group">
<input type="text" class="form-control" id="access" placeholder="Introduzca access " name="access">
#error('access') <span class="text-danger">{{ $message }}</span> #enderror
</div><br>
<button type="submit" class="btn btn-block btn-primary">Crear Asistencia</button>
</form>
My function submit:
public function submit()
{
$this->validate([
'code' => 'required|min:4',
'ip' => 'required|min:15',
'access' => 'required|min:1',
]);
Attendance::create([
'code' => $this->code,
'ip' => $this->ip,
'access' => $this->access,
]);
session()->flash('message','asistencia creada correctamente');
return redirect(RouteServiceProvider::HOME);
}

Saving some user information to a different table in laravel

I have tried to add to do some modification to Registration Controller. I want to add some users record to a different table but I can't get it right. I'm able to capture all the field using dd($data). But I am unable to save the data to the userRecord Table.
In Registration controller
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
'phoneno' => ['required', 'string', 'min:11']
'areas' => ['required', 'string']
]);
}
protected function create(array $data)
{
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
$user->attachRole('user');
$userRecord = new UserRecords();
$userRecord->phoneno = $data->phoneno;//additional fields
$userRecord->email= $data->email;
$userRecord->areas= $data->areas;//additional fields
$userRecord->save();
}
My model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class userRecords extends Model
{
protected $fillable = [
'name', 'email','phoneno','location',
];
}
My View
#extends('layouts.app')
#section('content')
<div class="container mt-4">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card">
<div class="card-header bg-info text-white">{{ __('Register') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('register') }}">
#csrf
<div class="form-group row">
<label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Name') }}</label>
<div class="col-md-6">
<input id="name" type="text" class="form-control #error('name') is-invalid #enderror" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus>
#error('name')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
</div>
</div>
<div class="form-group row">
<label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Phone Number') }}</label>
<div class="col-md-6">
<input id="phoneno" type="text" class="form-control">
</div>
</div>
<div class="form-group row">
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control #error('email') is-invalid #enderror" name="email" value="{{ old('email') }}" required autocomplete="email">
#error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
</div>
</div>
<div class="form-group row">
<label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Your Location') }}</label>
<div class="col-md-6">
<select name="areas" id="areas" class="form-control">
#foreach($areas as $item)
<option value="{{ $item->area }}">{{ $item->area}}</option>
#endforeach
</select>
</div>
</div>
<div class="form-group row">
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</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">
#error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
</div>
</div>
<div class="form-group row">
<label for="password-confirm" class="col-md-4 col-form-label text-md-right">{{ __('Confirm Password') }}</label>
<div class="col-md-6">
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Register') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
#endsection
Trying to get property 'phoneno' of non-object
$data is an array. But, you get values of $data as object. You should change $data->phoneno into $data['phoneno'], $data->email into $data['email'], $data->areas into $data['areas'].
2.
But not sure whether it will throw another error since I wanted to avoid using Auth tables
I think you can open another topic to clarify this.
A few things you need to set correct
Your model is userRecords so when newing up an instance new userRecords
$data is an array so access properties/elements with array syntax $data['email']
You need to return $user from create method
protected function create(array $data)
{
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
$user->attachRole('user');
$userRecord = new userRecords();
$userRecord->phoneno = $data['phoneno'];//additional fields
$userRecord->email= $data['email'];
$userRecord->areas= $data['areas'];//additional fields
$userRecord->save();
return $user;
}

Laravel: $errors->first() doesn't show error. How to make it work?

I want to show validation errors below each form element. I used {{ $errors->first('control1') }} but, it does not show the validation errors.
No clue about how to get around with this.
Below is my view code snippet.
<div class="form-group row">
<label for="control1" class="col-md-4 col-form-label text-md-left">{{ __('Number of control1') }}</label>
<input type="number" class="form-control col-md-8" id="control1" name="control1" value="{{ old('control1', 2) }}" required minvalue="1" />
#if ($errors->has('control1'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('control1') }}</strong>
</span>
#endif
</div>
in controller action, thebelow validation is written.
$this->validate($request, [
'control1' => 'required|min:1',
]);
You are validating a field named sprints. So change your validator array to match that, from this:
$this->validate($request, [
'sprints' => 'required|min:1',
]);
to this:
$this->validate($request, [
'control1' => 'required|min:1',
]);
And depending on your laravel version you can even simplify it like this:
$request->validate([
'control1' => 'required|min:1',
]);
Then in your view write this:
#error('control1')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror

How to change password?

I want to edit form update only address, email and password. How to change password? The old password is important.
edit.blade.php
<form method="POST" action="{{ route('update') }}">
#csrf
{{ method_field('PATCH') }}
<div class="form-group row">
<label for="email" class="col-md-1 col-form-label text-md-right">{{ __('Email') }}</label>
<div class="col-md-5">
<input id="email" type="text" class="form-control #error('email') is-invalid #enderror" name="email" value="{{ old('email') ? : user()->email }}" required autocomplete="email" autofocus>
#error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
</div>
</div>
<div class="form-group row">
<label for="password" class="col-md-1 col-form-label text-md-right">{{ __('Password') }}</label>
<div class="col-md-5">
<input id="password" type="text" class="form-control #error('password') is-invalid #enderror" name="password" value="{{ old('password') }}" required autocomplete="password" autofocus>
#error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
</div>
</div>
<div class="form-group row">
<label for="address" class="col-md-1 col-form-label text-md-right">{{ __('Address') }}</label>
<div class="col-md-5">
<textarea id="address" type="text" class="form-control #error('address') is-invalid #enderror" name="address" required autocomplete="address" autofocus>{{ old('address') ? : user()->address }}</textarea>
#error('address')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-1">
<button type="submit" class="btn btn-block btn-primary">
{{ __('Register') }}
</button>
</div>
</div>
</form>
Route
Route::post('update', 'Auth\RegisterController#sqlupdate')->name('update');
RegisterController
public function sqlupdate(Request $request)
{
Auth::user()->update([
'address' => $request['address'],
'email' => $request['email'],
]);
$hashedPassword = auth()->user()->password;
if (Hash::check($request->oldpassword, $hashedPassword)){
$user = User::findOrFail(Auth::id());
$user->password = Hash::make($request->password);
}
return redirect()->back();
}
Just read the below code carefully :-
/**
* Admin My profile : Password update.
*
* #param Request $request
* #param $id
* #return \Illuminate\Http\Response
*/
public function updatePassword(Request $request,$id = 0)
{
$validate = Validator::make($request->all(),[
'old_password' => 'required',
'password' => 'required|confirmed|min:8',
'password_confirmation' => 'required|min:8',
]);
$getUserData = Admin::where('id',$id)->first();
if($getUserData === null) {
return redirect()->back()->with([
'status' => 'warning',
'title' => 'Warning!!',
'message' => 'Invalid Admin ID.'
]);
}
$validate->after(function ($validate) use ($request,$getUserData,$id) {
if(!Hash::check($request->get('old_password'),$getUserData->password)){
$validate->errors()->add('old_password', 'Wrong old password');
}
});
if($validate->fails()){
return redirect()->back()->withErrors($validate)->withInput();
}
try{
$getUserData->update([
'password' => Hash::make($request->get('password'))
]);
return redirect()->back()->with([
'status' => 'success',
'title' => 'Success!!',
'message' => 'Admin password updated successfully.'
]);
}catch (Exception $e){
return redirect()->back()->with([
'status' => 'error',
'title' => 'Error!!',
'message' => $e->getMessage()
]);
}
}
With the above method you'll get the idea of how we update password, this is from one of my project i've created three field for that here is the screenshot of view :-
I hope this will help
Further more update here is the small snippet for update method
specially
$getOldPassword = User::where('id',$id)->first();
if($request->get('password') === null){
$password = $getOldPassword->password;
}else{
$password = Hash::make($request->get('password'));
}

Laravel always sets the default value

I am trying to do registration with user profile picture upload.(I am forced to do it this way)
I created the migration like this:
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('nom');
$table->string('prenom');
$table->string('type')->default('visiteur');
$table->boolean('confirme')->default(false);
$table->string('email')->unique();
$table->string('password');
$table->string('photo_url')->default('default_photo_profile.jpg');
$table->rememberToken();
$table->timestamps();
});
the create function :
$request = request();
if ($request->hasFile('photo')) {
$file = $request->file('photo');
$fullname=$data['nom'].'_'.date("Y-m-d",time()).'.'.$file->getClientOriginalExtension();
$path = $request->file('photo')->storeAs('images', $fullname);
}
return User::create([
'nom' => $data['nom'],
'prenom' => $data['prenom'],
'email' => $data['email'],
'photo_url' => $fullname,
'password' => Hash::make($data['password']),
]);
}
and the form for the file field is like this:
<div class="form-group">
<label for="photo_url">Photo profile</label>
<input type="file" name="photo" class="form-control-file" id="photo_url">
</div>
everything is working fine except the photo_url field, it always sets the default value in the migration and not the value I set in the create function.
$fullname is initiated and already declared.
the entire form :
<form method="POST" action="{{ route('register') }}" aria-label="{{ __('Register') }}" enctype="multipart/form-data">
#csrf
<div class="form-group row">
<label for="nom" class="col-md-4 col-form-label text-md-right">Nom</label>
<div class="col-md-6">
<input id="nom" type="text" class="form-control{{ $errors->has('nom') ? ' is-invalid' : '' }}" name="nom" value="{{ old('nom') }}" required autofocus>
#if ($errors->has('nom'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('nom') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group row">
<label for="prenom" class="col-md-4 col-form-label text-md-right">Prénom</label>
<div class="col-md-6">
<input id="prenom" type="text" class="form-control{{ $errors->has('prenom') ? ' is-invalid' : '' }}" name="prenom" value="{{ old('prenom') }}" required autofocus>
#if ($errors->has('prenom'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('prenom') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group row">
<label for="email" class="col-md-4 col-form-label text-md-right">Email</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required>
#if ($errors->has('email'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('email') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group row">
<label for="password" class="col-md-4 col-form-label text-md-right">Mot de pass</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required>
#if ($errors->has('password'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('password') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group row">
<label for="password-confirm" class="col-md-4 col-form-label text-md-right">Mot de pass confirmation</label>
<div class="col-md-6">
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required>
</div>
</div>
<div class="form-group">
<label for="photo_url">Photo profile</label>
<input type="file" name="photo" class="form-control-file" id="photo_url">
</div>
<div class="form-group row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
Envoyer
</button>
</div>
</div>
</form>
What is the problem?
Assuming you have a value for $photo_url, make sure you have 'photo_url' in your $fillables.
When you have $fillables, it only inserts (via User::create) what has in that array, otherwise it doesn't submit for that variable.
Your $fillables should look like this:
$fillables = ['nom','prenom','type','confirme','email','password','photo_url'];
Add 'photo' in $fillable array in User model:
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password', 'photo_url',
];
so according to your code in your model you have to add the photo_url in $fillable array like below.
$fillables = ['nom','prenom','type','confirme','email','password','photo_url'];
okay now there are 3 ways to do it with $fillable is first way and you are doing it right now.
2nd way:
if ($request->hasFile('photo')) {
$file = $request->file('photo');
$fullname=$data['nom'].'_'.date("Y-m-d",time()).'.'.$file->getClientOriginalExtension();
$path = $request->file('photo')->storeAs('images', $fullname);
}
else
{
$fullname = "default_photo_profile.jpg";
}
return User::create([
'nom' => $data['nom'],
'prenom' => $data['prenom'],
'email' => $data['email'],
'photo_url' => $fullname,
'password' => Hash::make($data['password']),
]);
and in your migration change this $table->string('photo_url')->default('default_photo_profile.jpg'); to $table->string('photo_url');
3rd way:
$fullname = "default_photo_profile.jpg";
if ($request->hasFile('photo')) {
$file = $request->file('photo');
$fullname=$data['nom'].'_'.date("Y-m-d",time()).'.'.$file->getClientOriginalExtension();
$path = $request->file('photo')->storeAs('images', $fullname);
return User::create([
'nom' => $data['nom'],
'prenom' => $data['prenom'],
'email' => $data['email'],
'photo_url' => $fullname,
'password' => Hash::make($data['password']),
]);
}
return User::create([
'nom' => $data['nom'],
'prenom' => $data['prenom'],
'email' => $data['email'],
'photo_url' => $fullname,
'password' => Hash::make($data['password']),
]);
}
okay these are the ways to do it. i would prefer first and second way 3rd one is lengthy.
Note: for 2nd and 3rd case you have to change your migration from this $table->string('photo_url')->default('default_photo_profile.jpg'); to $table->string('photo_url');
Hope you get it.

Resources