How to upload excel file in Laravel using laravelcollective? - laravel

I have a problem when import data xlsx using package fast excel.
I wanna input excel files include the Id from different model like following below
app/http/clustercontroller :
public function Import($id)
{
$model = Cluster::findOrFail($id);
return view('components.Admin.import', compact('model'));
}
public function StoreImport($id, Request $request)
{
//VALIDASI
$this->validate($request, [
'file' => 'required|mimes:xls,xlsx',
]);
if ($request->hasFile('file')) {
$file = $request->file('file'); //Get File
$collection = (new FastExcel)->import($file, function ($line) use ($id) {
return Soal::create([
'soal' => $line['Soal'],
'image' => $line['Image'],
'A' => $line['A'],
'B' => $line['B'],
'C' => $line['C'],
'D' => $line['D'],
'E' => $line['E'],
'kunci' => $line['Kunci'],
'cluster_id' => $id
]); //Import File
});
}
}
resource/admin/import.blade.php :
{!! Form::model($model, [
'route' => $model->exists ? ['cluster.soal.store', $model->id] : 'cluster.soal.create',
'method' => $model->exists ? 'POST' : 'POST',
'files' => true
]) !!}
<div class="form-group">
<label for="" class="control-label">Cluster</label>
{!! Form::text('cluster', null, ['class' => 'form-control', 'id' => 'cluster']) !!}
</div>
<div class="form-group">
<label for="" class="control-label">File .xlsx</label>
{!! Form::file('files') !!}
</div>
{!! Form::close() !!}
the code above displays the form, but when I click submit there is no response

You don't seem to return a response in your Controller method, so that's one reason I can think of. I assume your models are stored?
Things you could do to improve:
Return a view or, even better, redirection after finishing the import
Surround your code with try/catch blocks

Related

Add date into table which is in relation with product in Laravel 6

I have product and auction table. I want to add auction deadline on a specific table using form. when I submit the form the product_id in auction table is not populated and deadline shows time on which form is submited.
Here what I am trying:
I want that the create form get the deadline and store in auction table with product id so I can access it in show method of product.
create.blade.php
#extends('layouts.app')
#section('content')
<div class="mt-3" style="margin-left: 50px;">
<h2>Add new product</h2>
{!! Form::open(['action' => 'ProductsController#store', 'method' => 'POST', 'enctype' =>
'multipart/form-data', 'class' => 'w-50 py-3']) !!}
<div class="form-group">
{{Form::label('name', 'Product Name')}}
{{Form::text('name', '', ['class' => 'form-control', 'placeholder' => 'Product Name'])}}
</div>
<div class="form-group">
{{Form::label('description', 'Product Description')}}
{{Form::textarea('description', '', ['class' => 'form-control', 'placeholder' => 'Product Description', 'rows' => '4'])}}
</div>
<div class="form-group">
{!! Form::Label('category', 'Category') !!}
<select class="form-control" name="category_id">
#foreach($categories as $category)
<option value="{{$category->id}}">{{$category->name}}</option>
#endforeach
</select>
</div>
<div class="form-group">
{{Form::label('price', 'Product Price')}}
{{Form::number('price', '', ['class' => 'form-control', 'placeholder' => 'Product Price'])}}
</div>
<div class="form-group">
{{Form::label('deadline', 'Auction Deadline')}}
{{Form::date('{{$auction->deadline}}', '', ['class' => 'form-control'])}}
</div>
<div class="form-group">
{{Form::label('image', 'Product Image')}}
{{Form::file('image', ['class' => '', 'placeholder' => 'Product Image'])}}
</div>
{{Form::submit('Upload Product', ['class' => 'btn btn-primary'])}}
{!! Form::close() !!}
</div>
#endsection
Product Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $fillable = [
'name', 'price', 'description', 'image',
];
public function category()
{
return $this->belongsTo('App\Category');
}
public function auction()
{
return $this->hasOne('App\Auction');
}
}
ProductsController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use App\Product;
use App\Category;
use App\Auction;
class ProductsController extends Controller
{
public function index()
{
$categories = Category::all();
$products = Product::with('category')->latest()->paginate(3);
return view('products.index' ,compact('categories', 'products'));
}
public function create()
{
$categories = Category::all(['id', 'name']);
return view('products.create', compact('categories',$categories));
}
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required',
'description' => 'required',
'category_id' => 'required',
'price' => 'required',
'image' => 'image|nullable',
]);
// Create Product
$product = new Product();
$product->name = request('name');
$product->description = request('description');
$product->category_id = request('category_id');
$product->price = request('price');
$product->image = $fileNameToStore;
$product->save();
$auction = new Auction();
$auction->deadline = request('deadline');
$auction->save();
return redirect('/products')->with('success', 'Product Created');
}
public function show($id)
{
$product = Product::find($id);
return view('products.show', compact('product'));
}
}
you are just creating auction, where is the relation? Delete $product->save(); line. After the $auction->save(); add this line:
$product->auction()->associate($auction);
$product->save();
Final Store method
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required',
'description' => 'required',
'category_id' => 'required',
'price' => 'required',
'image' => 'image|nullable',
]);
// Create Product
$product = new Product();
$product->name = request('name');
$product->description = request('description');
$product->category_id = request('category_id');
$product->price = request('price');
$product->image = $fileNameToStore;
$auction = new Auction();
$auction->deadline = request('deadline');
$auction->save();
$product->auction()->associate($auction);
$product->save();
return redirect('/products')->with('success', 'Product Created');
}
Update for Irrelevant Blade problem
This line is wrong:
{{Form::date('{{$auction->deadline}}', '', ['class' => 'form-control'])}}
You are using blade close string tag in blade string tag.
Should be:
{{Form::date('deadline', '', ['class' => 'form-control'])}}
If auction variable has been passing from controller this will work

get the request values in Laravel

I wish to make search query by datepicker and select field.
How could I get the requests values from below view file to controller?
Where could I modify in the code? thanks.
index.blade.php
<div class="form-group col-sm-6">
{!! Form::open(array('class' => 'form', 'method' => 'get', 'url' => url('/pdfs/job_finished_search'))) !!}
{!! Form::input('text', 'datepicker_from', null, ['placeholder' => 'Fra', 'id' => 'datepicker_from']) !!}
{!! Form::input('text', 'datepicker_to', null, ['placeholder' => 'Til', 'id' => 'datepicker_to']) !!}
{!! Form::select('customer_name', $jobs->pluck('customer_name', 'customer_name')->all(), null, ['class' => 'form-control']) !!}
{!! Form::submit('Søke', ['class' => 'btn btn-success btn-sm']) !!}
{!! Form::close() !!}
</div>
Controller.php
public function job_finished_search(Request $request, Job $jobs)
{
$jobs = Job::onlyTrashed()
->whereBetween('created_at', array(
(Carbon::parse($request->input('datepicker_from'))->startOfDay()),
(Carbon::parse($request->input('datepicker_to'))->endOfDay())))
->where('customer_name', 'like', '%'.$request->customer_name.'%')
->orderBy('deleted_at', 'desc')
->paginate(15);
if (empty($jobs)){
Flash::error('Search result not found');
}
return view('pdfs.index', ['jobs' => $jobs]);
}
There are multiple way to get the request data e.g to get datepicker_from value you can use any of the below
$request->datepicker_from
$request->input('datepicker_from')
$request->get('datepicker_from')
choose the one you like the most
refer to https://laravel.com/docs/5.5/requests
To get request values you can use the get method, try:
$customer = $request->get('customer_name','default_value');
To get request values, you can set an object like $input= $request->all(). Then you can make use of the object which is an array to get at specific fields, e.g to access your date picker, you can write $input['datepicker_from']. You need to place $input= $request->all() before you declare the $jobs object in your code.

Laravel & Ajax send HTML form with errors

Here is an action:
public function postMessageAjax(Request $request)
{
$this->validate($request, [
'username' => 'required|string|regex:/^[a-zA-Z\d]+$/',
'email' => 'required|string|email',
'homepage' => 'nullable|string|url',
'text' => 'string',
'captcha' => 'required|captcha',
],
[
'captcha.captcha' => 'The captcha is incorrect',
'username.regex' => 'Use English letters and digits only',
]);
$message = new Message();
$message->username = $request->get('username');
$message->email = $request->get('email');
$message->homepage = $request->get('homepage');
$message->text = strip_tags($request->get('text'));
$message->ip = $request->ip();
$message->browser = get_browser($request->header('User-Agent'))->browser;
$message->save();
return view('Guestbook.postMessage');
}
And here is the view:
{!! BootForm::open(['id' => 'messageForm']) !!}
{!! BootForm::text('username') !!}
{!! BootForm::email('email') !!}
{!! BootForm::text('homepage') !!}
{!! BootForm::textarea('text') !!}
{!! captcha_img('flat') !!}
{!! BootForm::text('captcha') !!}
{!! BootForm::submit('Send') !!}
{!! BootForm::close() !!}
The problem is that Laravel somehow determines that that is an Ajax request and set an JSON of errors (if they're present) to Response instead of retrieving HTML code of form plus errors messages for each input individually. The question is: how do I force it to render the view with errors like if it weren't through Ajax?
UPDATE: this is what I want to get (the form itself and errors if they're present):
For #OuailB:
I've just noticed that when I do a normal POST request, it redirects me to the same page through a GET request so it seems like the error messages actually appear in the GET's body, not POST's so maybe there is no way. I'll think about it, thanks for your help!
You can create validator manually, and if it fails return what you want:
$validator = Validator::make($request->all(), [
'username' => 'required|string|regex:/^[a-zA-Z\d]+$/',
'email' => 'required|string|email',
'homepage' => 'nullable|string|url',
'text' => 'string',
'captcha' => 'required|captcha',
],
[
'captcha.captcha' => 'The captcha is incorrect',
'username.regex' => 'Use English letters and digits only',
]);
if ($validator->fails()) {
return Redirect::back()
->withErrors($validator)
->withInput($request->all());
}
Try this code:
public function postMessageAjax(Request $request)
{
$validator = Validator::make($request->all(), [
'username' => 'required|string|regex:/^[a-zA-Z\d]+$/',
'email' => 'required|string|email',
'homepage' => 'nullable|string|url',
'text' => 'string',
'captcha' => 'required|captcha',
],
[
'captcha.captcha' => 'The captcha is incorrect',
'username.regex' => 'Use English letters and digits only',
]);
if ($validator->fails()) {
return view('Guestbook.postMessage')
->withErrors($validator);
}
// Store your message here
}
Edit :
For displaying the errors, you can add this code into your view :
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif

what is the correct way of form validation in laravel?

I have just created the form and action is PagesController#check and the validation is as follows:
#extends('layout')
#section('content')
<div class = "container">
{!! Form::open(['action' => 'PagesController#check' , 'method' => 'POST']) !!}
<div class = "form-group">
{{ Form::label('country','Country')}}
{{ Form::text('country','', ['class' => 'form-control' , 'placeholder' => ''])}}
</div>
<div class = "form-group">
{{ Form::label('age','Age')}}
{{ Form::number('age','', ['class' => 'form-control' , 'placeholder' => ''])}}
</div>
<div class = "form-group">
{{ Form::label('marks','Marks')}}
{{ Form::number('marks','', ['class' => 'form-control' , 'placeholder' => ''])}}
</div>
<div class = "form-group">
{{ Form::label('description','Description')}}
{{ Form::textarea('description','', ['class' => 'form-control' , 'placeholder' => ''])}}
</div>
{{ Form::submit('Submit' , ['class' => 'btn btn-primary'])}}
{!! Form::close() !!}
</div>
#endsection
And the check() method in the PagesController is like this:
public function check(Request $request){
$this->validate($request, [
'country' => 'required',
'age' => 'required',
'marks' => 'required',
'description' => 'required'
]);
return 123;
}
Why is it then it is throwing the following error:
(2/2) ErrorException
Action App\Http\Controllers\PagesController#check not defined. (View: C:\wamp64\bin\apache\apache2.4.23\htdocs\website\resources\views\profiles.blade.php)
Here is the whole PagesController controller:
class PagesController extends Controller
{
public function home() {
return view('welcome');
}
public function about() {
$title = 'This is the about page';
return view('about')->with('title',$title);
}
public function show() {
$yomads = person::all();
return view('show')->with('yomads',$yomads);
}
public function profiles(){
return view('profiles');
}
public function check(Request $request){
$this->validate($request, [
'country' => 'required',
'age' => 'required',
'marks' => 'required',
'description' => 'required'
]);
return 123;
}
}
The error most likely has to do with the route (or lack of it) in app/Http/routes.php - check that it is properly defined there.
Furthermore, it is good practice to create custom request classes. Have a look at Form Request Validation
These can be generated with artisan:
php artisan make:request Profile
Then use it, as you were using the standard request:
public function check(ProfileRequest $request) {
[...]

Laravel validation with input field as array "title[]" throws always the same error

No matter which validation rule i brake as long as i have an array notation in input name like this
<div class="form-group">
{!! Form::label('titile', '* Eventname: ', ['class' => 'control-label']) !!}
{!! Form::text('title[]', null, ['class' => 'form-control', 'required']) !!}
</div>
i get this error:
I have tried to use simple plain html input like this
<input type="text" name="title[]" />
and even like this
{!! Form::text('title', null, ['name' => 'title[]','class' => 'form-control', 'required']) !!}
But nothing works.
Only if i make the input field without array notation [] the validation works properly...
my validation rule is this
$this->validate($request, [
'title' => 'required|min:2',
]);
I don't know what else to do, if anyone had similar problem please help.
UPDATE:
i have tried it like this now with only one form input:
<div class="form-group">
{!! Form::label('title', '* Eventname: ', ['class' => 'control-label']) !!}
{!! Form::text('title', null, ['name' => 'title[]','class' => 'form-control', 'required', 'placeholder' => 'z.B. Deutscher Filmpreis']) !!}
</div>
-
public function rules()
{
$rules = [
];
foreach($this->get('title') as $key => $val)
{
$rules['title.'.$key] = 'numeric';
}
return $rules;
}
Write your validation in individual request file. This ('title' => 'required|min:2') validation does not work for array input. Try this technique for dynamic field validation.
public function rules()
{
$rules = [
];
foreach($this->request->get('title') as $key => $val)
{
$rules['title.'.$key] = 'required|min:2';
}
return $rules;
}
Very Good example at laravel news site.
https://laravel-news.com/2015/11/laravel-5-2-a-look-at-whats-coming/
OK i finally solved this. In Laravel 5.3 something is changed and you can't put empty array brackets for field name.
You must declare indices inside...for example:
this doesn't work
{!! Form::text('title[]', null, ['class' => 'form-control', 'required']) !!}
but this works
{!! Form::text('title[0]', null, ['class' => 'form-control', 'required']) !!}
UPDATE
So after solving this now i know that if you put empty [ ] brackets this will work if you have multiple input fields with same name...but if you put empty brackets and you have an option to add new fields dynamically like i did...then that single field with empty array brackets will fail because you actually don't have an array...and you must put [0] some indices inside...
and then it works

Resources