Laravel Blade Component onclick function - laravel

Is it possible on blade component to call a function from onclick, and change its variable value?
public $rental = true;
/**
* Create a new component instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Get the view / contents that represent the component.
*
* #return \Illuminate\Contracts\View\View|\Closure|string
*/
public function render()
{
return view('components.product-rental');
}
public function toggleRental(){
$this->rental = !$this->rental;
}
<div class="row">
<div class="col col-md-6">
<div class="form-check form-switch">
<input class="form-check-input" name="rental" type="checkbox" #click="toggleRental()" id="rental" value="1" checked>
<label class="form-check-label" for="rental">Rental</label>
</div>
</div>
</div>
{{$rental}}
Basically, what i want is when i CLICK a button, it will call the "toggleRental()" function from blade component and update the "$rental" variable. Is this possible?

I think you should consider using Livewire instead.
It provides exactly this kind of features.
Otherwise you should implement an API endpoint and use Javascript to do so.
EDIT:
So you can use something like this:
<div class="row">
<div class="col col-md-6">
<div class="form-check form-switch">
<input class="form-check-input" name="rental" type="checkbox" data-rental="{{ $rental }}" onclick="toggleRental" id="rental" value="1" checked>
<label class="form-check-label" for="rental">Rental</label>
</div>
</div>
</div>
{{$rental}}
<script>
document.addEventListener('DOMContentLoaded', (event) => {
var rentalCheckBox = document.querySelector('#rental');
rentalCheckBox.value = rentalCheckBox.getAttribute('data-rental');
function toggleRental(){
rentalCheckBox.value = !rentalCheckBox.value;
}
});
</script>

Related

Laravel 8 Form Request Validation Redirect to Index page instead same page and show error

On localhost all is good, but when I deploy the application to the server not working. If form request validation fails instead of bringing me back to the same page and showing an error, it redirects me to the index page.
config.blade.php
<form method="POST" action="{{ route('config.update', $config->id) }}">
#csrf
#method('PUT')
<div class="form-group row">
<div class="col">
<label class="col-form-label">Name</label>
<input id="name" type="text" class="form-control" name="name" value="{{ $config->name }}" required>
</div>
</div>
<div class="form-group row mt-3">
<div class="col">
<label class="col-form-label text-md-right">Address</label>
<input id="address" type="text" class="form-control" name="address" value="{{ $config->address }}">
</div>
</div>
<div class="form-group row mt-3">
<div class="col">
<label class="col-form-label text-md-right">Phone</label>
<input id="phone" type="tel" class="form-control" name="phone" value="{{ $config->phone }}" required>
</div>
</div>
<div class="form-group row mt-3">
<div class="col">
<label class="col-form-label text-md-right">E-mail</label>
<input id="email" type="email" class="form-control" name="email" value="{{ $config->email }}" required>
</div>
</div>
<div class="form-group row mt-4 mb-0">
<div class="col-md-12">
<button type="submit" class="btn btn-primary button-full-width">Save changes</button>
</div>
</div>
</form>
web.php
Route::resource('/admin/config', 'Admin\ConfigController');
ConfigController
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Services\ConfigServices;
use App\Http\Requests\ConfigRequest;
use App\Models\Config;
class ConfigController extends Controller
{
protected $configServices;
public function __construct(ConfigServices $configServices) {
$this->middleware('auth');
$this->configServices = $configServices;
}
...
public function update(ConfigRequest $request, $id)
{
$config = $this->configServices->updateConfigById($request, $id);
return redirect()->back();
}
...
}
ConfigRequest - here is the problem
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ConfigRequest 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|string|max:255',
'address' => 'nullable|string|max:255',
'phone' => 'required|regex:/^([0-9\s\-\+\(\)]*)$/|min:9|max:15',
'email' => 'required|email:rfc',
];
}
}
Form Request return to index page instead same page. On localhost working everything, but when I deploy the app to server a problem arises.
When data on form request validated correct return me back on the same page and show success, but when form request failing redirect mine for some reason to the index page.
A problem arises in Laravel 8, this code worked well in previous Laravel versions.
Can someone help me, please?
In your custom request you need:
/**
* The URI that users should be redirected to if validation fails.
*
* #var string
*/
protected $redirect = '/dashboard';
or
/**
* The route that users should be redirected to if validation fails.
*
* #var string
*/
protected $redirectRoute = 'dashboard';
You can find more in the docs.
In the docs for older versions of Laravel these properties don't exist.
Do you have error parts in your blade?
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#if ($message = Session::get('unique'))
asdsad
#endif
#endforeach
</ul>
</div>
#endif

Axios returning HTML in response instead of data

I want to ask for help regarding Axios' response to my POST request in the login route via Laravel. It returns HTML of the homepage in data when it authenticated the user (or it finds the user in the database). Please see the response screenshot below:
May I just ask for the solution to my problem? Here are the necessary codes and the versions that I am using:
Tools
VueJS: v3.0.5
Axios: 0.19
Laravel: 5.8
Codes
Login.vue (script)
import axios from 'axios'
export default {
data() {
return {
csrfToken: '',
loginObj: {
username: '',
password: '',
remember: false,
},
message: '',
}
},
created() {
this.csrfToken = document.querySelector('meta[name="csrf-token"]').content;
},
methods: {
signIn() {
console.log(this.loginObj)
axios.post('login', this.loginObj).then(res => {
console.log(res)
})
.catch(error => {
console.log(error.response)
})
}
}
}
Login.vue (template)
<div class="card shadow-lg border-0 rounded-lg mt-5">
<div class="card-header bg-orange"><h3 class="text-center my-4">Hello!</h3></div>
<div class="card-body p-0">
<div class="row">
<div class="col-lg-6 d-none d-lg-block">
<div class="login-image-wrap text-center">
<img src="/img/ahrs_logo_trans.png" class="login-img" alt="AKB Logo">
</div>
</div>
<div class="col-lg-6">
<div class="p-5">
<div class="text-center">
<h1 class="h4 text-gray-900 mb-4">Sign In</h1>
</div>
<form name="loginForm" #submit.prevent="signIn">
<input type="hidden" name="_token" :value="csrfToken">
<div class="form-group">
<label class="small mb-1" for="inputUsername">Username</label>
<input class="form-control py-4" v-model="loginObj.username" id="inputUsername" type="text" placeholder="Enter username" required autofocus>
</div>
<div class="form-group">
<label class="small mb-1" for="inputPassword">Password</label>
<input class="form-control py-4" v-model="loginObj.password" id="inputPassword" type="password" placeholder="Enter password" required>
</div>
<div class="form-group">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="remember" id="remember" v-model="loginObj.remember">
<label class="form-check-label text-small" for="remember">
Remember Me
</label>
</div>
</div>
<div class="form-group d-flex align-items-center justify-content-between mt-4 mb-0">
<a class="small" href="password.html">Forgot Password?</a>
</div>
<hr />
<div>
<button type="submit" class="btn bg-yellow btn-block font-weight-bold">LOGIN</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
LoginController.php
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
// override in the AuthenticatesUsers function username()
public function username()
{
return 'username';
}
Thank you for your help.
You will probably need to tell Laravel that you want to return the User as JSON if it's an ajax request.
You can do this by adding the following to your LoginController:
protected function authenticated(Request $request, $user)
{
if ($request->ajax()) {
return $user;
}
}
You may also need to set the X-Requested-With header that is usually set in the default bootstrap.js file that comes with Laravel so that Laravel knows it's an ajax request:
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
Obviously, if this line is already there and you're still including the bootstrap file in your bundle you can ignore this.

How to display other data when you select the supplier name in select tag in laravel

I'd like to select a name and output it properties in form automatically, how do I display its properties automatically?
<select id="suppliers_name" name="suppliers_name" class="form-control" data-plugin="select2">
#foreach ($supplier as $suppliers)
<option value="{{$suppliers->name}}">{{$suppliers->supplier_name}}</option>
#endforeach
</select>
</div>
</div>
<div class="form-group row">
<label for="Supplier/s Address" class="col-sm-2 col-form-label">Suppler/s Address:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="sup_address" name="sup_address" placeholder="Supplier's Address" value="{{$suppliers->supplier_address}}" >
</div>
</div>
<div class="form-group row">
<label for="Contact Person" class="col-sm-2 col-form-label">Contact Person:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="con_person" name="con_person" placeholder="Contact Person Name" value="{{$suppliers->contact_person_name}}" disabled>
</div>
</div>
I can select the suppliers name but I can't display its properties.
here's the controller:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Po;
use App\Supplier;
class PoController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$po = Po::All()->name();
return view('/po.manage-po', compact('po'));
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
$supplier = Supplier::All();
return view('/po.add-po', compact('supplier'));
}

New “Metier” is created when editing a “Metier”

When I try to edit a "Metier", a new "Metier" is created and the old one stays the same. I want to crush the old "Metier" and create a new one just by editing. Here is my code in relation with the edit function.
Controller
public function edit($id)
{
$metier=Metier::find($id);
return view('metier.edit',['libelle_metier'=>$metier]);
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$metier=Metier::find($id);
return view('metier.edit',['libelle_metier'=>$metier]);
}
View
<div class="form-group">
<label for="">libelle Metier </label>
<input type="text" name ="libelle_metier" class="form-control"value ="
{{$libelle_metier->libelle_metier}}" >
</div>
<div class="form-group">
<input type="submit" value = "enregistrer" class="form-control btn btn-
primary">
</div>
route
Route::get('/metier', 'MetierController#index');
Route::get('/metier/create', 'MetierController#create');
Route::post('/metier', 'MetierController#store');
Route::get('/metier/{id}/show', 'MetierController#edit');
Route::get('/metier/{id}/edit', 'MetierController#edit');
Route::upd('/metier/{id}/update', 'MetierController#update');
Route::delete('/metier/{id}', 'MetierController#destroy')
MetierController.php
public function edit($id)
{
$metier=Metier::find($id);
return view('metier.edit',['libelle_metier'=>$metier]);
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$metier = Metier::find($id);
$metier->libelle_metier = $request->libelle_metier;
$metier->save();
return back();
}
edit.blade.php
#extends('Layouts/app')
#extends('Layouts.master')
#section('content')
<div class="container">
<div class="row">
<div class="col-md-10">
<h1>Modifier Metier </h1>
<form action=" {{url ('metier') }}" method="post">
{{csrf_field()}}
<div class="form-group">
<label for="">libelle Metier </label>
<input type="text" name ="libelle_metier" class="form-
control"value ="
{{$libelle_metier->libelle_metier}}" >
</div>
<div class="form-group">
<input type="submit" value = "enregistrer" class="form-control
btn btn-
primary">
</div>
</form>
</div>
</div>
#endsection
That's because you don't even try to update the DB record. Do something like this instead:
public function update(Request $request, $id)
{
Metier::where('id', $id)->update($request->all());
return back();
}
Or without using the mass assignment:
public function update(Request $request, $id)
{
$metier = Metier::find($id);
$metier->libelle_metier = $request->libelle_metier;
$metier->save();
return back();
}
Update
Thanks for sharing the whole form. You're also using POST method instead of PUT. Change the form URL and add this field to the form:
<form action="{{ url('metier/' . $libelle_metier->id . '/update') }}" method="post">
{{ method_field('PUT') }}
Then the update() method will be executed instead of store().
And change the route to put:
Route::put('/metier/{id}/update', 'MetierController#update');
Also, it's a good idea to use Route::resource instead of manually creating the same routes. It will allow you to avoid this kind of errors.
https://laravel.com/docs/5.6/helpers#method-method-field
add {{ method_field('PATCH') }} to your form and change action to named route and pass metier id to it.
#extends('Layouts/app')
#extends('Layouts.master')
#section('content')
<div class="container">
<div class="row">
<div class="col-md-10">
<h1>Modifier Metier </h1>
<form action="{{ route('metier.update', $libelle_metier->id) }}" method="post">
{{csrf_field()}}
{{ method_field('PATCH') }}
<div class="form-group">
<label for="">libelle Metier </label>
<input type="text" name ="libelle_metier" class="form-
control"value ="
{{$libelle_metier->libelle_metier}}" >
</div>
<div class="form-group">
<input type="submit" value = "enregistrer" class="form-control
btn btn-
primary">
</div>
</form>
</div>
</div>
#endsection
Route file
Route::patch('/metier/{id}/update', 'MetierController#update')->name('metier.update');
Hint: delete all these
Route::get('/metier', 'MetierController#index');
Route::get('/metier/create', 'MetierController#create');
Route::post('/metier', 'MetierController#store');
Route::get('/metier/{id}/show', 'MetierController#edit');
Route::get('/metier/{id}/edit', 'MetierController#edit');
Route::upd('/metier/{id}/update', 'MetierController#update');
Route::delete('/metier/{id}', 'MetierController#destroy')
and either add just it all as a single resource, so that all REST urls will be added in one shot.
this is how should be if its REST specification. read it
REST Resource Naming Guide and here
Route::resource('metier', 'MetierController');
or add it this way instead of resource
Route::get('/metier', 'MetierController#index')->name('metier.index');
Route::get('/metier/create', 'MetierController#create')->name('metier.create');
Route::post('/metier', 'MetierController#store')->name('metier.store');
Route::get('/metier/{id}', 'MetierController#show')->name('metier.show');
Route::get('/metier/{id}/edit', 'MetierController#edit')->name('metier.edit');
Route::patch('/metier/{id}', 'MetierController#update')->name('metier.update');
Route::delete('/metier/{id}', 'MetierController#destroy')->name('metier.destroy');
Learn about Resource Controllers
Controller
public function edit($id)
{
$metier=Metier::find($id);
return view('metier.edit',['libelle_metier'=>$metier]);
}
public function update(Request $request, $id)
{
// do some request validation
$metier=Metier::find($id);
$metier->update($request->all());
return redirect()->route('metier.show', $metier->id);
}
if you are having mass assignment error.
add protected $guarded = []; to the Metier model

Issues with Laravel Mailables

I'm trying to create a contact form in Laravel using Laravel 5.3, but I get this nasty error here:
ErrorException in helpers.php line 519:
htmlspecialchars() expects parameter 1 to be string, object given (View: /Applications/XAMPP/xamppfiles/htdocs/meps/resources/views/emails/contactemail.blade.php)
Here are the files that I was using:
The contact form
<div class="contact-form">
<form class="margin-clear" role="form" action="{{ url('/sendmail') }}" method="POST">
{{ csrf_field() }}
<div class="form-group has-feedback">
<label for="name">Name*</label>
<input type="text" class="form-control" id="name" name="name" placeholder="">
<i class="fa fa-user form-control-feedback"></i>
</div>
<div class="form-group has-feedback">
<label for="email">Email*</label>
<input type="email" class="form-control" id="email" name="email" placeholder="">
<i class="fa fa-envelope form-control-feedback"></i>
</div>
<div class="form-group has-feedback">
<label for="subject">Subject*</label>
<input type="text" class="form-control" id="subject" name="subject" placeholder="">
<i class="fa fa-navicon form-control-feedback"></i>
</div>
<div class="form-group has-feedback">
<label for="message">Message*</label>
<textarea class="form-control" rows="6" id="message" name="message" placeholder=""></textarea>
<i class="fa fa-pencil form-control-feedback"></i>
</div>
<input type="submit" value="Submit" class="btn btn-primary">
</form>
</div>
The Controller function
public function sendmail(Request $request, Mailer $mail) {
$mail->to('kaley36_aw#yahoo.com')->send(new ContactEmail($request->name, $request->email, $request->subject, $request->message));
$request->session()->flash('mail-sent', 'Your email has been sent.');
return redirect('/contact');
}
The Mailable class
class ContactEmail extends Mailable
{
use Queueable, SerializesModels;
public $name;
public $email;
public $subject;
public $message;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($name, $email, $subject, $message)
{
$this->name = $name;
$this->email = $email;
$this->subject = $subject;
$this->message = $message;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->from($this->email)->view('emails.contactemail');
}
}
And here is the route
Route::post('sendmail', 'EmailController#sendmail');
You probably looking at the wrong view. The error points to
/views/emails/contactemail.blade.php
But this view has a <form> unless you are sending back to your users a form via e-mail, this looks a lot more like your contact form view and not your e-mail view. Something like:
/views/contact.blade.php (or whatever you have in there as a form)
As for the error, you must have a {{ $variable or functionCall() }} which is not receiving a string, but an object.
I figured it out. The issue was with the variable $message, Laravel wrapped it in an actual object called Message. All I had to do was change the variable name to $theMessage and it worked find.

Resources