I am making a todo list with validation using laravel 5.4.
When I click on the submit button, only the required validation is working but not the unique.
What am I doing wrong and how do I fix it so as to get it working as desired?
Below is my form (located at home.blade.php):
<div class="panel-body">
<form class="form form-control" action="/todo" method="post">
{{csrf_field()}}
<fieldset class="form-group">
<textarea class="form-control" name="textbox" id="textArea"></textarea>
<button type="submit" class="btn btn-primary">Submit</button>
</fieldset>
</form>
{{-- for dispaying the error --}}
#if (count($errors) >0)
{{-- expr --}}
#foreach ($errors->all() as $error)
<h3 class="text-danger">{{$error}}</h3>
#endforeach
#endif
</div>
Here, the content of my Todo controller (in my todocontroller.php file):
use Illuminate\Http\Request;
use App\todo;
public function store(Request $request)
{
$todo = new todo;
$todo->body = $request->textbox;
$this->validate($request,[
"body" => "required|unique:todos"
]);
$todo->save();
return redirect('/todo');
}
You should simply use the name of the field; you don't need to stress yourself.
Take a look at the snippet below:
<?php
namespace App\Http\Controllers;
use App\Todo;// following Laravel's standards, your model name should be Todo; not todo
use Illuminate\Http\Request;
class NameOfYourTodoController extends Controller
{
public function store(Request $request)
{
$todo = new Todo();
// use the name of the field directly (here, textbox)
$this->validate($request, [
'textbox' => 'required|unique:todos'
]);
// other code logics here.
}
}
Related
At the moment I am working with Laravel. I am trying to insert data into a database. It is not user data, but product data. Costumers have to be able to insert a title, description and price of a product into the database.
I have looked at the laravel website, however, I was unable to find anything. There are some people with the same question as mine on StackOverflow. However, the answers that were given to them do not work for me.
My controller:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ProductsController extends Controller
{
public function insertform(){
return view('home');
}
public function insert(Request $request){
$productname = $request->input('title');
$description = $request->input('description');
$price = $request->input('price');
$data=array('title'=>$productname,"description"=>$description,"price"=>$price);
DB::table('products')->insert($data);
echo "Record inserted successfully.<br/>";
echo 'Click Here to go back.';
}
}
My view:
#section('content')
<h1>Add your new items here:</h1>
<form method="get">
<div class="title">
<div class="title">
<span class="input-group-text" id="title">Title</span>
</div>
<input type="text" name="title" class="form-control" aria-label="title" aria-describedby="inputGroup-sizing-default">
</div>
<br>
<br>
<div class="description">
<div class="description">
<span class="input-group-text" id="description">Description</span>
</div>
<input type="text" name="description" class="form-control" aria-label="description" aria-describedby="inputGroup-sizing-default">
</div>
<br>
<br>
<div class="price">
<div class="price">
<span class="input-group-text" id="price">Price</span>
</div>
<input type="text" name="price" class="form-control" aria-label="price" aria-describedby="inputGroup-sizing-default">
</div>
<br>
<br>
<div class="form-group">
<label for="exampleFormControlFile1">Insert Image</label>
<input type="file" class="form-control-file" id="exampleFormControlFile1">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
#endsection
My web.php:
<?php
Route::get('/', function () {
return view('welcome');
});
Route::get('insert','ProductsController#insertform');
Route::post('create','ProductsController#insert');
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
My database structure:
The home and welcome, along with some code in the web.php, has been made by authentication.
Hopefuly you guys can help me out. I want to make sure that the product data is inserted into the database.
Don't use DB class. Instead create a model called Product and use model function to create or update data into table.
php artisan make:model Product
$product= Product::create([
'name' => $request->name, # declared as fillable on Product model
'description' => $request->description,
...
]);
Convert the route of /insert into POST and add csrf field in your form
#csrf
OR
<input type="hidden" name="_token" value="{{csrf_token()}}">
On your controller validation of input in insert function.
Also take a look at these -
https://laravel.com/docs/5.8/eloquent#defining-models
Laravel Validation Rules
or https://laravel.com/docs/5.8/validation#quick-writing-the-validation-logic
In your web.php, Add route names
Route::get('insert','ProductsController#insertform')->name('product.create');
Route::post('create','ProductsController#insert')->name('product.store');
In your view, change method to post and add action attribute and csrf field.
<form action="{{ route('product.store') }}" method="post">
#csrf
In Controller
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use DB;
class ProductsController extends Controller
{
public function insertform(){
return view('home');
}
public function insert(Request $request){
$productname = $request->input('title');
$description = $request->input('description');
$price = $request->input('price');
$data = array(
"title" => $productname,
"description" => $description,
"price" => $price
);
DB::table('products')->insert($data);
echo "Record inserted successfully.<br/>";
echo 'Click Here to go back.';
}
}
Alternate you can directly add action without route name
<form action="/create" method="post">
#csrf
In laravel 5.6 i can show you how to insert the data and display the data to the index page
so first of all i can code my route
in here we can use 2 routes
first is index page route
second is store and in store controller you can display your stored data.
Route::get('/FAQ_page', 'SettingController#FAQ_page')->name('FAQ_page');
Route::get('/FAQ_page/create', 'SettingController#FAQ_page_create')->name('FAQ_page.create');
Route::post('/FAQ_page/store', 'SettingController#FAQ_pagestore');
now make a database and connect to your module
this is your module
namespace App;
use Illuminate\Database\Eloquent\Model;
class FAQpage extends Model
{
protected $table = 'p66_FAQ_page';
public $timestamps = false;
protected $primaryKey = 'fid';
}
now make your controller like this
public function FAQ_page()
{
$data = FAQpage::get();
return view('SuperAdmin.settings.FAQ_page', compact('data'));
}
public function FAQ_page_create()
{
return view('SuperAdmin.settings.FAQ_page_create');
}
public function FAQ_pagestore(Request $request)
{
request()->validate([
'FAQ_question'=> 'required',
'FAQ_answer'=> 'required',
'Sort_order'=> 'required|max:4',
'FAQ_departments'=> 'required',
]);
$data = new FAQpage();
$data->FAQ_question = $request->get('FAQ_question');
$data->FAQ_answer = $request->get('FAQ_answer');
$data->Sort_order = $request->get('Sort_order');
$data->FAQ_departments = $request->get('FAQ_departments');
$data->Created_date = Carbon::now();
$data->save();
return redirect('/SuperAdmin/FAQ_page');
}
thank you
I'm learning Laravel and I got stuck trying to get data from a form.
I already am able to get data back with GET, but with POST I've been having a ton of trouble. Here's what I'm working with:
Form:
<form id="forms" method="POST" action="sugestoes" novalidate>
{{ csrf_field() }}
<div class="form-row">
<div class="form-group col-md-12">
<label for="obs">Observações:</label>
<textarea type="text" class="form-control" name="obs" placeholder="Observações" required></textarea>
</div>
</div>
<hr>
<button type="submit" class="btn btn-primary">Enviar</button>
</form>
#php
if (isset($_POST["obs"])) {
echo "IN";
}
#endphp
Controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function store(Request $request)
{
$name = $request->input('obs');
return redirect('sugestoes');
//
}
}
Route:
Route::post('sugestoes', 'PostController#store');
The intended behaviour that I'm trying to reach is for the post to be submitted, and then returning to the same page with an empty form. Later on I'll be sending the input data into a database, but for now I just want to get the post to work.
I guess I'm missing something really basic, but I've been following guides and looking online, I've done some progress but I'm really stuck here.
(some more info, this is Laravel 5.4, and I'm using XAMPP)
First, you need to call the model, use App/Your_model_name; then you have to save the data.
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Suggest; //Suggest model, let's hope you have suggest table
class PostController extends Controller
{
public function store(Request $request)
{
$suggest = new Suggest; //model
$suggest->name = $request->obs; //name is DB name, obs is request name
$suggest->save(); //save the post to DB
return redirect()->back()->with('success', 'Saved successfully'); //return back with message
}
}
Then if you want to flash the message on the HTML page
#if(session('success'))
<div class="alert alert-warning alert-dismissible" id="error-alert">
<strong style="color: white;">{{session('success')}}</strong>
</div>
#endif
<form id="forms" method="POST" action="{{ route('sugestoes') }}" novalidate>
{{ csrf_field() }}
<div class="form-row">
<div class="form-group col-md-12">
<label for="obs">Observações:</label>
<textarea type="text" class="form-control" name="obs" placeholder="Observações" required></textarea>
</div>
</div>
<button type="submit" class="btn btn-primary">Enviar</button>
</form>
Remove the #php tag below the form, then in router.php
Route::post('/sugestoes', 'PostController#store')->name('sugestoes');
Then in Controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function store(Request $request)
{
$name = $request->input('obs');
return redirect('/sugestoes'); // you should have GET in Route.php
//
}
}
Add the following code in your action attribute on the form. It will capture the post URL. When you submit the form it will send the form data to the URL end-point.
action="{{ url('sugestoes')}}"
Then die and dump in your controller store function
public function store(Request $request)
{
dd($request->all());
}
I'm a newbie to voyager, is there a way I can upload users via CSV in voyager. I imagine I would have to make a custom template for this, anyone that can point me on the right direction on this, I would highly appreciate it.
I know this is an old question, but since this is the first thing I encounter when I research the same thing, I wanted to add an answer so that those who come here can benefit.
This solution is for Laravel 8.9.0 and Voyager 1.4
This has a selection before uploading CSV, it is not necessary but good to have, so you don't have to adjust CSV before uploading.
I did use another resource to do it, which was in Laravel 5.5 you can see the original codes from Laravel-5.5 CSV Import
I'll also add a fork which updated with Laravel 9.0 after I finished my own project.
Anyhow, I use Laravel-Excel 3.1.24 to read CSV. The resource was using an older version.
Let's Start the Coding
Before you connect it with Voyager, first you should know that you need to write your view and controller to do the job.
Also, we'll need our model. For your User Model, make sure that you added all the fields you need. Create migration with the same needs.
Like if your User Model has this;
protected $fillable = [
'name',
'email',
'password',
];
Make sure your migration;
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
After you set your model and migration, you'll need one other model to store your CSV. This will be helpful for you while doing the selection with CSV and database fields.
It will have only three fields; 'csv_filename', 'csv_header', 'csv_data' .
After setting our models, we'll need to add config/app.php to our selections.
'db_fields' => [
'name',
'email',
'password',
]
That fields we will get from CSV, you can remove the password if you don't have password in your CSV file.
Before getting into our Controller, we should add Laravel-Excel. From the documentation, all you need to do is run this command on the terminal.
composer require "maatwebsite/excel:3.1.24"
This will add Laravel-Excel to our project. Our controller will need "import" which is a class to helps us import files, comes with Laravel-Excel. For this;
php artisan make:import CsvImport --model=User
You can use it for a quick start like Laravel-Excel documentation recommended. Now we can get into our Controller. We'll create controller vie Laravel commands. We're gonna need bunch of things;
use App\Imports\CsvImport; //This is needed for Laravel-Excel.
use Illuminate\Http\Request;
use App\Models\User; //Our user model.
use App\Models\CsvData; //Our model for csv.
use App\Http\Requests\CsvImportRequest; //I'll share this in a sec.
use Maatwebsite\Excel\Facades\Excel; //This is from Laravel-Excel
use Illuminate\Support\Str; //This is for basic password creation
class ImportController extends Controller
{
The functions we need are;
public function form()
{
return view('import.form');
}
This function is pretty simple. It will return our view. The second one is when we parse our CSV and saving in it add CSV_Data. But first, we need a request as Laravel wanted.
php artisan make:request CSVImportRequest
I'll share mine;
class CsvImportRequest extends FormRequest
{
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'csv_file' => 'required|file'
];
}
Now we can go back to our Controller;
public function parseImport(CsvImportRequest $request)
{
//we getting with the request the file. So you need to create request with
//Laravel. And you should add this to your Controller as use App\Http\Requests\CsvImportRequest;
$path = $request->file('csv_file')->getRealPath();
if ($request->has('header')) {
//this is coming from Laravel-Excel package. Make sure you added to your
//controller; use Maatwebsite\Excel\Facades\Excel;
$data = Excel::toArray(new CsvImport, request()->file('csv_file'))[0];
} else {
$data = array_map('str_getcsv', file($path));
}
if (count($data) > 0) {
//checking if the header option selected
if ($request->has('header')) {
$csv_header_fields = [];
foreach ($data[0] as $key => $value) {
$csv_header_fields[] = $key;
}
}
$csv_data = array_slice($data, 0, 2);
//creating csvdata for our database
$csv_data_file = CsvData::create([
'csv_filename' => $request->file('csv_file')->getClientOriginalName(),
'csv_header' => $request->has('header'),
'csv_data' => json_encode($data)
]);
} else {
return redirect()->back();
}
//this is the view when we go after we submit our form.We're sending our data so we can select to match with db_fields.
return view('import.fields', compact('csv_header_fields', 'csv_data', 'csv_data_file'));
}
And, now the import function.
public function processImport(Request $request)
{//we are getting data from request to match the fields.
$data = CsvData::find($request->csv_data_file_id);
$csv_data = json_decode($data->csv_data, true);
$request->fields = array_flip($request->fields);
foreach ($csv_data as $row) {
$contact = new User();
foreach (config('app.db_fields') as $index => $field) {
//using config app.db_fields while matching with request fields
if ($data->csv_header) {
if ($field == "null") {
continue;
} else if ($field == "password") {
//this is checkin if password option is set. If not, it is creating a password. You can eliminate this according to your needs.
if (isset($request->fields['password'])) {
$pw = $row[$request->fields['password']];
} else {
$pw = Str::random(10);
}
} else
$contact->$field = $row[$request->fields[$field]];
} else
//same with the if but without headers. You can create a function to avoid writing
//codes twice.
{
if ($field == "null") {
continue;
} else if ($field == "password") {
if (isset($request->fields['password'])) {
$pw = $row[$request->fields['password']];
} else {
$pw = Str::random(10);
}
} else
$contact->$field = $row[$request->fields[$index]];
}
}
$user = User::where(['email' => $contact->email])->first();
//checking for duplicate
if (empty($user)) {
$contact->password = bcrypt($pw);
$contact->save();
} else {
$duplicated[] = $contact->email;
//if you want you can keep the duplicated ones to check which ones are duplicated
}
}
//you can redirect wherever you want. I didn't need an success view so I returned
//voyagers original users view to see my data.
return redirect(route('voyager.users.index'));
}
Now, we can create our routes. Since we're using Voyager do not forget to add voyager., so we can use it with the voyager admin panel.
use App\Http\Controllers\ImportController;
Route::group(['prefix' => 'admin','as' => 'voyager.', 'middleware' => 'admin.user'],
function()
{
Route::get('import',[ImportController::class, 'form'])->name("import.form");
Route::post('import/parse', [ImportController::class, 'parseImport'])-
>name("import.parse");
Route::post('import/process', [ImportController::class, 'processImport'])-
>name("import.process");
});
Also, we'll need a view while importing and selecting. I created my views in the views/import.
For your form blade, you want to use it with voyager so you should
#extends('voyager::master')
use this to have the same theme. After that, you need to add your html with a section.
#section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">CSV Import</div>
<div class="panel-body">
<form class="form-horizontal" method="POST" action="{{ route('voyager.import.parse') }}" enctype="multipart/form-data">
{{ csrf_field() }}
<div class="form-group{{ $errors->has('csv_file') ? ' has-error' : '' }}">
<label for="csv_file" class="col-md-4 control-label">CSV file to import</label>
<div class="col-md-6">
<input id="csv_file" type="file" class="form-control" name="csv_file" required>
#if ($errors->has('csv_file'))
<span class="help-block">
<strong>{{ $errors->first('csv_file') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<div class="checkbox">
<label>
<input type="checkbox" name="header" checked> File contains header row?
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-8 col-md-offset-4">
<button type="submit" class="btn btn-primary">
Parse CSV
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
#endsection
As you can see, we use "voyager." to add our route. This will also help us to Voyager settings. Our second view is where we choose our db_fields.
#extends('voyager::master')
#section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">CSV Import</div>
<div class="panel-body">
<form class="form-horizontal" method="POST" action="{{ route('voyager.import.process') }}">
{{ csrf_field() }}
<input type="hidden" name="csv_data_file_id" value="{{ $csv_data_file->id }}" />
<table class="table">
#if (isset($csv_header_fields))
<tr>
#foreach ($csv_header_fields as $csv_header_field)
<th>{{ $csv_header_field }}</th>
#endforeach
</tr>
#endif
#foreach ($csv_data as $row)
<tr>
#foreach ($row as $key => $value)
<td>{{ $value }}</td>
#endforeach
</tr>
#endforeach
<tr>
#foreach ($csv_data[0] as $key => $value)
<td>
<select name="fields[{{ $key }}]">
<option value="null">Do Not Save</option>
#foreach (config('app.db_fields') as $db_field)
<option value="{{ (\Request::has('header')) ? $db_field : $loop->index }}"
#if ($key === $db_field) selected #endif>{{ $db_field }}</option>
#endforeach
</select>
</td>
#endforeach
</tr>
</table>
<button type="submit" class="btn btn-primary">
Import Data
</button>
</form>
</div>
</div>
</div>
</div>
</div>
#endsection
This is it! Now we have our import set. We just need to configure with Voyager.
VOYAGER SETTINGS
First, we need a menu-item to reach our import view. After you get into Voyager panel, you need to go to the menu builder to create a menu item. All you have to do is make the url of the item as /admin/import with that when you clicked that item, you'll go to our import form view. For the other options, you can change them however you want.
You may also need to change from your user BREAD Model as App\Models\User, so it can receive all the fields we created.
laravel-8.9.0 voyager-1.4 laravel-excel-3.1.24
I am new to Laravel and other PHP frameworks.
Try simple form and validating, like examples in https://laravel.com/docs/5.1/validation
routes.php
Route::get('/post/', 'PostController#create');
Route::post('/post/store', 'PostController#store');
create.blade.php
<html>
<head>
<title>Post form</title>
</head>
<body>
<h1>Create Post</h1>
<form action="/post/store" method="POST">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<div class="form-group">
<label for="title">Title</label>
<input type="text" id="title" name='title'>
</div>
<button type="submit" class="btn btn-default">Save</button>
</form>
</body>
PostController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use View;
use Validator;
class PostController extends Controller
{
/**
* Show the form to create a new blog post.
*
* #return Response
*/
public function create()
{
return view('post.create');
}
/**
* Store a new blog post.
*
* #param Request $request
* #return Response
*/
public function store(Request $request)
{
// Validate and store the blog post...
$validator = Validator::make($request->all(), [
'title' => 'required|min:5'
]);
if ($validator->fails()) {
dd($validator->errors);
//return redirect('post')
//->withErrors($validator)
//->withInput();
}
}
}
When I post not valid data:
ErrorException in PostController.php line 37: Undefined property: Illuminate\Validation\Validator::$errors
Validator object nor have errors.
If enabled in controller
return redirect('post')->withErrors($validator)
->withInput();
and enabled in form
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
Have error
ErrorException in c5df03aa6445eda15ddf9d4b3d08e7882dfe13e1.php line 1: Undefined variable: errors (View: /www/alexey-laravel-1/resources/views/post/create.blade.php)
This error in default get request to form and after redirect from validator.
For $errors to be available in the view, the related routes must be within the web middleware:
Route::group(['middleware' => ['web']], function () {
Route::get('/post/', 'PostController#create');
Route::post('/post/store', 'PostController#store');
});
I just downloaded and started a new project with the latest Laravel 4.2. When trying to submit a form I get the following error : BadMethodCallException Method [store] does not exist
Here are my files : controller - admin/AdminController
<?php
namespace admin;
use Illuminate\Support\Facades\View;
use App\Services\Validators\ArticleValidator;
use Input, Notification, Redirect, Sentry, Str;
class AdminController extends \BaseController {
public function index() {
if (Input::has('Login')) {
$rules = array(
'email' => 'required',
'password' => 'required|min:3',
'email' => 'required|email|unique:users'
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
return Redirect::to('admin\AdminController')->withErrors($validator);
} else {
// redirect
Session::flash('message', 'Successfully created user!');
return Redirect::to('admin\AdminController');
}
}
$data['title'] = ADMIN;
return View::make('admin.index', $data);
}
}
View page - admin/index.blade.php
<div class="container">
{{ Form::open(array('url' => ADMIN,'id' => 'login')) }}
<div id="icdev-login-wrap">
<div class="raw align-center logoadmin">{{ HTML::image('images/logo.png') }}</div>
<div id="icdev-login">
<h3>Welcome, Please Login</h3>
<div class="mar2_bttm input-group-lg"><input type="text" class="form-control loginput" placeholder="Email" name="email"></div>
<div class="mar2_bttm input-group-lg"><input type="password" class="form-control loginput" placeholder="Password" name="password"></div>
<div ><input type="submit" class="btn btn-default btn-lg btn-block cus-log-in" value="Login" /></div>
<div class="row align-center forgotfix">
<input type="hidden" name="Login" value="1">
</div>
</div>
<div>
</div>
</div>
{{ Form::close() }}
</div>
The error message tells you what the problem is: the method called store() doesn’t exist. Add it to your controller:
<?php
namespace admin;
use Illuminate\Support\Facades\View;
use App\Services\Validators\ArticleValidator;
use Input, Notification, Redirect, Sentry, Str;
class AdminController extends \BaseController {
public function index()
{
// leave code as is
}
public function store()
{
// this is your NEW store method
// put logic here to save the record to the database
}
}
A couple of points:
Use camel-casing for name spaces (i.e. namespace admin should be namespace Admin)
Read the Laravel documentation on resource controllers: http://laravel.com/docs/controllers#resource-controllers
You can also automatically generate resource controllers with an Artisan command. Run $ php artisan make:controller ItemController, replacing ItemController with the name of the controller, i.e. ArticleController or UserController.