How do I deal with form in laravel? - laravel

I was dealing with forms in laravel, I have written the code but once i click on the button to submit the form it's just reset the page
Here is my view create.blade.php
#extends('layouts.app')
#section('content')
<div class="container">
<form action="/p" enctype="multipart/form-data" method="post">
#csrf
<div class="row">
<div class="col-8 offset-2">
<div class="row">
<h1>Add New Post</h1>
</div>
<div class="form-group row">
<label for="caption" class="col-md-4 col-form-label">Post Caption</label>
<input id="caption"
type="text"
class="form-control{{ $errors->has('caption') ? ' is-invalid' : '' }}"
name="caption"
value="{{ old('caption') }}"
autocomplete="caption" autofocus>
#if ($errors->has('caption'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('caption') }}</strong>
</span>
#endif
</div>
<div class="row">
<label for="image" class="col-md-4 col-form-label">Post Image</label>
<input type="file" class="form-control-file" id="image" name="image">
#if ($errors->has('image'))
<strong>{{ $errors->first('image') }}</strong>
#endif
</div>
<div class="row pt-4">
<button class="btn btn-primary">Add New Post</button>
</div>
</div>
</div>
</form>
</div>
#endsection
And my PostsController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PostsController extends Controller
{
public function create(){
return view('posts.create');
}
public function store(){
$data = request()->validate([
'caption' => 'required',
'image' => ['required', 'image'],
]);
Post::create($data);
dd(request()->all());
}
}
my routes web.php
<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/p/create', 'PostsController#create');
Route::post('/p', 'PostsController#create');
Route::get('/profile/{user}', 'ProfilesController#index')->name('profile.show');
The validation is not working and every time I click on the button, it resets everything. Kidly Help me sort this out
Post model
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->string('caption');
$table->string('image');
$table->timestamps();
$table->index('user_id');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}

Change this line in your web.php file, from
Route::post('/p', 'PostsController#create');
to
Route::post('/p/store', 'PostsController#store')->name('p.store');
As you can see in the modification above, you were pointing to the wrong Controller method.
Additionally, it is best practice to use named route.
With the above named route, you can now use the route helper without worrying about the url like this in your form:
<form action="{{ route('p.store') }}" enctype="multipart/form-data" method="post">
</form>
UPDATE 1:
I didn't catch this earlier. Your Controller method must have at least the Request object as parameter in the definition for POST requests. Also update your validation logic.
Update your store() method to this
public function store(Request $request){
$request->validate([
'caption' => 'required',
'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg',
]);
Post::create($request->input());
dd($request->all());
}
Observe that you were using the global request helper request() previously. You don't need to do that anymore because the Request object is now passed in as a parameter. Also note that you don't need to pass any actual arguments when you use the route. The argument is automatically passed in by Laravel.
UPDATE 2:
Also, update your Post model with $fillable array
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model {
protected $fillable = ['caption', 'image'];
public function user(){
return $this->belongsTo(User::class);
}
}
The $fillable array indicate fields in the database that can be assigned using an HTTP request (e.g. from an HTML form).
From the Laravel documentation:
you will need to specify either a fillable or guarded attribute on the model, as all Eloquent models protect against mass-assignment by default.

The problem is in your route. Both your get and post route are going to the controller's create method. Post route will be like
Route::post('/p', 'PostsController#store');

Related

BadMethodCallException Call to undefined method App\Models\Categorie::ajoutercategorie()

I code an adding product category system for ecommerce.
i got below error
What should I do to solve this problem?
BadMethodCallException
Call to undefined method App\Models\Categorie::ajoutercategorie()
Did you mean App\Models\Categorie::hasGetMutator() ?
The name of my controller is "CategorieController".This is my store function called sauvercategorie in CategorieController.
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Categorie;
class CategorieController extends Controller
{
//
public function ajoutercategorie(){
return view('admin.ajoutercategorie');
}
public function sauvercategorie(Request $request){
$validatedData = $request->validate([
'category_name' => 'required | max:255',
]);
$categorie = Categorie::ajoutercategorie($validatedData);
return redirect('/ajoutercategorie')->with('status', 'La catégorie'
.$categorie->category_name.'a été ajoutée avec succès');
My entire blade file.
#extends('layouts.appadmin')
#section('title')
Ajouter une catégorie
#endsection
#section('contenu')
<div class="row grid-margin">
<div class="col-lg-12">
<div class="card">
<div class="card-body">
<h4 class="card-title">Ajouter une catégorie</h4>
#if (Session::has('status'))
<div class="alert alert-success">
{{Session::get('status')}}
</div>
#endif
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
<form class="cmxform" id="commentForm" method="post" action="{{ route('categories.sauvercategorie') }}">
#csrf
<fieldset>
<div class="form-group">
<label for="cemail">Nom de la catégorie</label>
<input id="cemail" class="form-control" type="text" name="category_name" >
</div>
<input class="btn btn-primary" type="submit" value="Ajouter">
</fieldset>
</form>
</div>
</div>
</div>
</div>
#endsection
#section('scripts')
{{--<script src="Administrateur/js/form-validation.js"></script>
<script src="Administrateur/js/bt-maxLength.js"></script>--}}
#endsection
the name of model is Categorie. This is my model
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Categorie extends Model
{
use HasFactory;
protected $fillable = ['category_name'];
}
my table name is "categories". This is my table
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCategoriesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('categorie_name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('categories');
}
}
Need helps to solve that, thanks.
Your controller calling
$categorie = Categorie::ajoutercategorie($validatedData);
which is calling ajoutercategorie function on your Model, but you don't have that function on model.
You can change :
public function sauvercategorie(Request $request){
$validatedData = $request->validate([
'category_name' => 'required | max:255',
]);
$categorie = Categorie::ajoutercategorie($validatedData);
return redirect('/ajoutercategorie')->with('status', 'La catégorie'
.$categorie->category_name.'a été ajoutée avec succès');
into :
public function sauvercategorie(Request $request){
$validatedData = $request->validate([
'category_name' => 'required | max:255',
]);
$categorie = Categorie::create($validatedData);
return redirect('/ajoutercategorie')->with('status', 'La catégorie'
.$categorie->category_name.'a été ajoutée avec succès');
Or you can see this documentation https://laravel.com/docs/9.x/eloquent#inserting-and-updating-models for default function CRUD

How do I deal with controller resource in laravel

I am using the resource tool for my controller and my route but the store method appears not to work. Could you highlight what I did wrong. Is the controller name needs to be the same as the model one? I am confuse
FarmController
<?php
namespace App\Http\Controllers;
use App\Animal;
use Auth;
use Illuminate\Http\Request;
class FarmController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function __construct()
{
$this->middleware('auth');
}
public function index()
{
$animal = Animal::all();
return view('farms.index', compact('animal'));
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
$user = Auth::user();
$animal = new Animal();
return view('farms.create', compact('user', 'animal'));
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store()
{
Animal::create($this->validateRequest());
return redirect('farms.show');
}
private function validateRequest()
{
return request()->validate([
'dateOfBirth' => 'required|date',
'placeOfBirth' => 'required',
'gender' => 'required',
'user_id' => 'required',
]);
}
Animal.php (controller)
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Animal extends Model
{
protected $guarded = [];
public function user(){
return $this->belongsTo(User::class);
}}
animals (table)
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateAnimalsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('animals', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id')->index();
$table->date('dateOfBirth');
$table->string('gender');
$table->string('placeOfBirth');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('animals');
}
}
create.blade.php
#extends('layouts.app')
#section('title', 'Add Animal')
#section('content')
<div class="row">
<div class="col-12">
<h1>Farm</h1>
</div>
</div>
<h3>Welcome {{ $user->name }} Please Add an animal</h3>
<div class="row">
<div class="col-12">
<form action="{{ url('farms') }}" method="POST">
<div class="form-group">
<label for="dateOfBirth">Date Of Birth: </label>
<input type="date" name="dateOfBirth" class="form-control" placeholder="dd/mm/yyyy">
</div>
<div class="pb-5">
{{ $errors->first('dateOfBirth') }}
</div>
<div class="form-group">
<label for="placeOfBirth">Place Of Birth</label>
<input type="text" name="placeOfBirth" class="form-control">
</div>
<div class="pb-5">
{{ $errors->first('placeOfBirth') }}
</div>
<div class="form-group">
<label for="gender">Gender: </label>
<select name="gender" class="form-control">
<option value="M">Male</option>
<option value="F">Female</option>
</select>
</div>
<div class="form-group">
<label for="user">User</label>
<select class="form-control" name="user">
<option value="{{ $user->id }}" name="user">{{ $user->name }}</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Add Farm</button>
#csrf
</form>
</div>
</div>
#endsection
web.php (routes)
<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::middleware('admin')->group(function () {
// All your admin routes go here.
Route::resource('/admin', 'AdminController');
});
Route::middleware('farms')->group(function () {
// All your admin routes go here.
Route::resource('/farms', 'FarmController');
});
When I am submitting the form, it seems like it just refreshes the page and do not add anything in my table. I have been stuck on this in two entire days. any help is welcome
In the validateRequest function you have
'user_id' => 'required',
But your form in the view has no field named user_id
The select element is named user
<select class="form-control" name="user">
<option value="{{ $user->id }}" name="user">{{ $user->name }}</option>
</select>
Change one of them so they can match, I guess that the page refresh is just failed validation
You may want to check for any validation error in your view to find out what's wrong as per the docs
For example
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
Hope this helps
Just change your form action then it hit in correct mehtod. Here is the action for your form
{{route('farms.store')}}

CSRF on Yajra Datatable Laravel not working

I have this code in laravel and used YAJRA as my datatable and upon submitting it says that the CSRF token is error, attached here is my code in Controller before rending in View/Blade.
Here is my code:
$return = '<form method="post" action="/procurement/add-product">
'.{{ csrf_token() }}.'
<input type="hidden" name= "product_id" value=".$row->id.">
<input type="text" name="product_qty" class="form-control">
<button type="submit" class="btn btn-primary btn-block">Add Item</button>
</form>';
return $return;
I found an answer via documentation, https://laravel.com/docs/master/csrf
I just put the URI of the said form
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
class VerifyCsrfToken extends BaseVerifier
{
/**
* The URIs that should be excluded from CSRF verification.
*
* #var array
*/
protected $except = [
//
'procurement/*',
];
}
Return the form to another blade like view/products/datatables.blade.php
Example: The controller should looks like:-
public function getproducts()
{
$product = Product::all(); //Product is Model name
return Datatables::of($product)
->addColumn('action', function($product)
{
return view('product.datatables', compact('product'))->render();
})->make(true);
}
And the view should look as below:
Edit
<form action="/product/{{ $product->id }}" method="post" id="deleteForm">
{{ method_field('DELETE') }}
{{ csrf_field() }}
<button class="btn btn-danger btn-sm" type="submit">Delete</button>
</form>
It will work just fine. Because the mustache {{}} can't be read in the controller. We redirect the things to the blade

How to create a user login in Laravel 5.2?

I am using laravel 5.2. I want to create a user login.
I will give my model, view and controller files. I want to create a user login page.
I used below given view, model, controller but I get the error:
Sorry, the page you are looking for could not be found.
NotFoundHttpException in RouteCollection.php line 161:
Please help me to create a user login page in laravel 5.2.
model file
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Database\Eloquent\SoftDeletes;
class UserLogin extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
use Authenticatable, CanResetPassword;
protected $table = 'users';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [ 'username','password'];
}
view file
<!DOCTYPE html>
<html lang="en">
<head>
<meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0' name='viewport' />
<title>#section('title') Cable #show</title>
#section('meta_keywords')
<meta name="keywords" content="MCC Hostel"/>
#show #section('meta_author')
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta http-equiv="cleartype" content="on" />
#show #section('meta_description')
<meta name="description" content="MCC Hostel"/>
#show
{!! Assets::css() !!}
#yield('styles')
</head>
<body id="login-page">
<div class="container">
<div class="content">
<div id="home" class="content has-bg home">
<div class="container home-content">
#include('utils.errors.list')
<div class="logo-img-login text-center"> <big>Cable</big></div>
<form class="form col-sm-6 col-sm-offset-3 col-md-6 col-md-offset-3 col-lg-4 col-lg-offset-4" role="form" method="POST" action="{{ URL::to('/auth/login') }}">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<div class="form-group">
<label class="control-label">Email</label>
<input type="text" class="form-control" name="username" value="{{ old('email') }}">
</div>
<div class="form-group">
<label class="control-label">Password</label>
<input type="password" class="form-control" name="password">
</div>
<div class="form-group">
<div class="">
<div class="checkbox">
<label>
<input type="checkbox" name="remember"> Remember Me
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="">
<button type="submit" class="btn btn-primary" style="margin-right: 15px;">
Login
</button>
<a class="hide" href="{{
URL::to('/password/email') }}">Forgot Your Password?</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{!! Assets::js() !!}
#yield('scripts')
</body>
</html>
controller file
<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class UserLoginController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
protected $redirectPath = 'admin/dashboard';
protected $username = 'username';
protected function validator(array $data) {
return Validator::make($data, [
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6',
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
protected function create(array $data) {
$data = User::create([
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
Mail::send('emails.welcome', ['name' => $data['name']], function ($m) use ($data) {
$m->to($data['email'], $data['name'])->subject('Thank you for registering!')->from('admin#alumni.mescampusschool.edu.in', 'Admin MES school campus');
});
Session::flash('flash_notification', array('level' => 'success', 'message' => 'Your account has been regsitered please check your mail'));
return $data;
}
/**
* Handle a login request to the application.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function postLogin(Request $request) {
$this->validate($request, [
$this->loginUsername() => 'required', 'password' => 'required',
]);
$throttles = $this->isUsingThrottlesLoginsTrait();
if ($throttles && $this->hasTooManyLoginAttempts($request)) {
return $this->sendLockoutResponse($request);
}
$credentials = $this->getCredentials($request);
if (Auth::validate($credentials)) {
$user = Auth::getLastAttempted();
if ($user->confirmed) {
Auth::login($user, $request->has('remember'));
return redirect()->intended($this->redirectPath());
} else {
return redirect($this->loginPath())
->withInput($request->only('email', 'remember'))
->withErrors([
'active' => 'You must confirm your payment first to login '
]);
}
}
if (Auth::attempt($credentials, $request->has('remember'))) {
return $this->handleUserWasAuthenticated($request, $throttles);
}
if ($throttles) {
$this->incrementLoginAttempts($request);
}
return redirect($this->loginPath())
->withInput($request->only($this->loginUsername(), 'remember'))
->withErrors([
$this->loginUsername() => $this->getFailedLoginMessage(),
]);
}
}
You receive a NotFoundHttpException. This means that you probably forgot to define a matching route.
Go into your app/http/routes.php file and define your routes there - e.g. :
Route::get('/login', 'Authcontroller#login'); // if you have this function in your controller
or like
Route::get('/login', function() {
return view('auth.login'); // if you have your login view placed in the auth folder of your view resources
});
The MOST EASY way to get a working login system in laravel is to use the command
php artisan make:auth
But BE AWARE of the following: This might overwrite existing files (if you have an existing Authcontroller for example or an app layout in views/layouts/app.blade.php ).
Usually this should be the first command you run after setting up a new laravel application if you want the default login behavhiour.
Dont forget to call php artisan migrate and ofcrouse define your .env variables correctly to ensure a working database connection.

Laravel - If has errors on validation, insert class in the specifics inputs

I'm totally noob in PHP, but my question is, after the validation which has errors for specific inputs, how can I insert a class in the specific input?
Example, if i have this error in the validation: "The email field is required."
How can i insert a specific class in the email input?
Login routes:
Route::group(['prefix' => 'admin'], function () {
Route::get('/', 'Admin\AdminController#index');
Route::get('login', 'Admin\AuthController#getLogin');
Route::post('login', 'Admin\AuthController#postLogin');
Route::get('logout', 'Admin\AuthController#getLogout');
});
AdminController:
class AdminController extends AdminBaseController
{
public function index()
{
if(Auth::user()){
return view('admin/pages/admin/index');
}
return view('admin/pages/login/index');
}
}
AuthController:
class AuthController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
private $redirectTo = '/admin';
public $loginPath = '/admin';
public function __construct()
{
$this->middleware('guest', ['except' => 'getLogout']);
}
public function getLogin()
{
if(Auth::user()){
return redirect('/admin');
}
return view('admin/pages/login/index');
}
public function postLogin(Request $request)
{
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:6',
]);
}
}
My blade form:
<form class="s-form" role="form" method="POST" action="/admin/login">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<div class="s-form-item text">
<input type="text" name="email" value="{{ old('email') }}" placeholder="Email">
</div>
<div class="s-form-item text">
<input type="password" name="password" value="{{ old('password') }}" placeholder="Senha">
</div>
<div class="s-form-item">
#if ($errors->has())
<div class="alert alert-danger">
#foreach ($errors->all() as $error)
{{ $error }}<br>
#endforeach
</div>
#endif
</div>
<div class="s-form-item s-btn-group s-btns-right">
<input class="s-btn" type="submit" value="Entrar">
</div>
</form>
You can pass an argument to the has method to specify the specific key.
For example, for your email input...
<input class="#if($errors->has('email')) some-class #endif" ... >
I left out the rest of the input field for brevity. It basically checks if an error for the email input exists. If so, 'some-class' is outputted. Otherwise, it skips over it.
Edit: To answer the question on how you can customize where to output your error messages, you can use the get or first methods in conjunction with the has method. For example...
#if ($errors->has('email'))
#foreach ($errors->get('email') as $error)
<p>{{ $error }}</p>
#endforeach
#endif
The has method has already been explained. The get method retrieves the validation errors. Because there can be more than one validation error, you must loop through it and output it.
In the next example, I use first. This method just outputs the first error message so there is no need to loop through it.
#if ($errors->has('email'))
<p>{{ $errors->first('email') }}</p>
#endif

Resources