I have this error in a form where i use a foreach in a select option. I can't find where the error is.
Undefined variable: types (View: /var/www/laravel/resources/views/clases/create.blade.php)
Form:
...
<div class="form-group{{ $errors->has('types') ? ' has-error' : '' }}">
<label class="col-md-2 control-label" for="selectbasic">Doy clases de<em>*</em></label>
<div class="col-md-6">
<select id="type" name="types[]" value="" class="selectpicker form-control show-tick" data-live-search="true" multiple="multiple" multiple title="Seleccionar una o varias opciones" data-size="6" data-max-options="8" data-selected-text-format="count > 3">
#foreach($types as $tp)
<option value="{{$tp->id}}" {{in_array($tp->id, old("types") ?: []) ? "selected": ""}}>{{$tp->type}}</option>
#endforeach
</select>
</div>
#if ($errors->has('types'))
<span class="help-block">
<strong>{{ $errors->first('type') }}</strong>
</span>
#endif
</div>
...
ClaseController
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Carbon\Carbon;
use Validator;
use App\Clase;
use App\Province;
use App\Style;
use App\Type;
use App\Instrument;
use Auth;
use Image;
use Illuminate\Validation\Rule;
class ClaseController extends Controller
{
...
public function create()
{
$userid = Auth::user()->id;
$user_clases = \DB::table('clases')
->where('user_id', '=', $userid)
->first();
return view('clases.create',compact('userid'));
}
public function store(Request $request)
{
$validator = Validator::make($request->all(),[
'description' => 'required',
'types' => 'required|required|array|min:1',
'phone' => 'required',
'image' => 'image|mimes:jpeg,bmp,png|max:6144',
'g-recaptcha-response' => 'required|captcha'
]);
$clase = new Clase;
...
$clase->types()->attach($request->types);
$clase->save();
}
model 'Clase':
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Builder;
use App\Traits\DatesTranslator;
use App\SessionHistory;
use Carbon\Carbon;
class Clase extends Model
{
use SoftDeletes, DatesTranslator;
public $dates = ['moderated_at','reported_at','deleted_at'];
protected $fillable = ['content','...','...','types'];
...
public function types(){
return $this->belongsToMany('App\Type');
}
...
}
model 'Type':
namespace App;
use Illuminate\Database\Eloquent\Model;
class Type extends Model
{
public $timestamps = false;
protected $fillabe = ['type'];
public function clases(){
return $this->hasMany('App\Clase');
}
}
Already checked the two models i use in the controller but can't find the error that it seems to be in the foreach ($types as $tp)...
Any help thanks in advance.
Controller
public function create()
{
$userClases = Clase::where('user_id', Auth::user()->id);
return view('clases.create',compact('userClases'));
}
Form:
<div class="col-md-6">
<select id="type" name="types[]" value="" class="selectpicker form-control show-tick" data-live-search="true" multiple="multiple" multiple title="Seleccionar una o varias opciones" data-size="6" data-max-options="8" data-selected-text-format="count > 3">
#foreach($userClases->types as $tp)
<option value="{{$tp->id}}" {{in_array($tp->id, old("types") ?: []) ? "selected": ""}}>{{$tp->type}}</option>
#endforeach
</select>
</div>
Related
Is the relationship working in the bank, but I can't show it in my registration view?
Usuario.php
class Usuario extends Model
{
protected $fillable = [
'company',
'name',
'document',
'phone',
'email'
];
public function empresa()
{
return $this->belongsTo('App\Empresa');
}}
Empresa.php
class Empresa extends Model
{
protected $fillable = [
'name',
'uf',
'cnpj'
];
public function usuarios()
{
return $this->hasMany('App\Usuario');
}}
form.blade.php
#foreach($usuarios as $u)
<option value="{{ $u->company_id->name }}">{{ $u->company_id->name }}</option>
#endforeach
UsuarioController.php
class UsuariosController extends Controller
{
public function new(){
$usuarios = Usuario::get();
return view('usuarios.form', ['usuarios' => $usuarios]);
}
enter image description here
please change your empresa() method in Usuario class.
public function empresa()
{
return $this->belongsTo('App\Empresa', 'company');
}
and blade file will be changes like this.
#foreach($usuarios as $u)
<option value="{{ $u->empresa->name }}">{{ $u->empresa->name }}</option>
#endforeach
form.blade.php
#csrf
<div class="form-group">
<label for="exampleInputEmail1">Empresa:</label>
<select name="company" class="form-control">
#foreach($usuarios as $u)
<option value="{{ $u->empresa->name }}">{{ $u->empresa->name }}</option>
#endforeach
</select>
</div>
<div class="form-group">
<label for="exampleInputEmail1">Nome:</label>
<input type="text" name="name" class="form-control">
</div>
UsuarioController.
class UsuariosController extends Controller
{
public function index(){
$usuarios = Usuario::get();
return view('usuarios.list', ['usuarios' => $usuarios]);
}
public function new(){
$usuarios = Usuario::get();
return view('usuarios.form', ['usuarios' => $usuarios]);
}
public function adicionar( Request $request ){
$usuario = new Usuario;
$usuarios = Usuario::get();
$usuario = $usuario->create( $request->all() );
return Redirect::to('/usuarios', ['usuarios' => $usuarios]);
}
public function editar( $id ){
$usuario = Usuario::findOrFail( $id );
return view('usuarios.form', ['usuario' => $usuario]);
I have many to many relationship between UserProfile model and UserTv model. Here are the tables.
user_profiles
id user_id username
1 1 AuthUser
tv
id name
1 Action
2 Drama
3 Comedy
4 manually added some genre from input from authenticated user
user_tv
id user_id tv_id
1 1 2
1 1 4
For example, these first three ids in tv table (Action, Drama, Comedy) are inserted through seeders and this fourth id is inserted manually through input text from form by that user who is authenticated. And there lies the my problem. I want that those values that are manually added through input in form to only be able to see that user that inserted those values, and all other users can't. But also I want all users to remain to see those first three values that are generated through seeder. Currently everything works so that all users can see everything. Any help is appreciated. Here is my code.
UserProfile.php
<?php
namespace App;
use App\User;
use Illuminate\Support\Facades\App;
use Illuminate\Database\Eloquent\Model;
class UserProfile extends Model
{
protected $fillable = [
'user_id',
'username',
];
public function user()
{
return $this->belongsTo(User::class);
}
public function tvs()
{
return $this->belongsToMany(UserTv::class, 'user_tv', 'user_id', 'tv_id');
}
}
UserTv.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class UserTv extends Model
{
protected $table = 'tv';
protected $fillable = [
'name'
];
public function userProfiles()
{
return $this->belongsToMany(UserProfile::class, 'user_tv', 'tv_id', 'user_id');
}
}
web.php
Route::get('profile/{profile}', 'UserProfileController#showProfile')->name('profile.show');
Route::patch('profile/update-tv-options', 'TvController#updateTvOptions')->name('profile.update.tv.options');
Route::post('profile/insert-tv-options', 'TvController#insertTvOptions')->name('profile.insert.tv.options');
TvController.php
<?php
namespace App\Http\Controllers;
use App\UserTv;
use App\UserProfile;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use App\Http\Requests\InsertTvOptionsRequest;
use App\Http\Requests\UpdateTvOptionsRequest;
class TvController extends Controller
{
public function updateTvOptions(UpdateTvOptionsRequest $request)
{
$user = Auth::user();
$userProfile = UserProfile::where('user_id', Auth::id())->first();
$userProfile->update($request->all());
$data = $request->get('tvsOptions', '[]');
$userProfile->tvs()->sync($data);
return redirect()->route('profile.show', [$user->username]);
}
public function insertTvOptions(InsertTvOptionsRequest $request)
{
$user = Auth::user();
$tv = UserTv::create($request->all());
return redirect()->route('profile.show', [$user->username]);
}
}
UserProfileController.php
<?php
namespace App\Http\Controllers;
use App\User;
use App\UserTv;
use App\UserProfile;
class UserProfileController extends Controller
{
public function showProfile($username, Request $request)
{
$profileId = User::getIdFromUsername($username);
$userForShowProfile = User::with('userProfile')->where('id', $profileId)->firstOrFail();
$tvsOptions = UserTv::get();
$userTvsOptions = UserProfile::findOrFail($profileId)->tvs()->get();
return view('profile.show', compact('userForShowProfile', 'tvsOptions', 'userTvsOptions'));
}
}
show.blade.php
<section data-edit="movies" class="editMovies">
<h3 class="textBold">Film</h3>
<form action="{{ route('profile.update.tv.options') }}" method="POST" class="flex">
#method('PATCH')
#csrf
<div class="form-group flex">
#isset($tvsOptions, $userTvsOptions)
#foreach($tvsOptions as $option)
<div class="interestedIn">
<input type="checkbox" name="tvsOptions[]" value="{{ $option->id }}" {{ $userTvsOptions->contains('id', $option->id)? 'checked': ''}}>
<label for="">{{ $option->name }}</label>
</div>
#endforeach
#endisset
</div>
<div class="form-group">
<label for="" class="textBold">Button FOR CHECKBOX</label>
<input type="submit" class="form-control" name="submit" value="BUTTON">
</div>
</form>
<form action="{{ route('profile.insert.tv.options') }}" method="POST" class="flex">
#csrf
<div class="form-group mt-5">
<input type="text" name="name" placeholder="INSERT NEW MOVIE GENRE">
</div>
<div class="form-group">
<label for="" class="textBold">Button FOR INSERT!!!</label>
<input type="submit" class="form-control" name="submit" value="BUTTON">
</div>
</form>
</section>
And I want to contain first three options for all users and that fourth option for only this user that inserted that.
Something like this?
$defaultTvsOptions = UserTv::whereIn('name', ['Action', 'Drama', 'Comedy'])->get(); // return only action, drama and comedy. you can use ids.
$userTvsOptions = UserProfile::findOrFail($profileId)->tvs;
$tvsOptions = $defaultTvsOptions->merge($userTvsOptions); // merge default and logged user tvs options
To make it more maintainable, you could use configs in your root directory of project.
$defaultTvsOptions = UserTv::whereIn('name', config('config name where return the array'));
Hope it helps you.
Hey As you Have a pivot table You can pull the data Like This:
Userprofile model
public function tv() {
return $this->hasManyThrough(
'Tv class ',
'user_tv class',
'user_id',
'id',
'user_id',
'tv_id'
);
}
UserController
$data = UserProfile::with('tv')
->where(condition)
->get();
I currently have an application that can have a modifier with many options. An example use case is a modifier of Toppings with options of cheese, lettuce, salt, and pepper. A modifier can have 1 --> N options.
I want to have a form that displays the Modifier name and also allows the ability to edit/delete Option records at same time. I want to embed this in my current form for adding/editing modifiers.
Is there a simple way to do this so I can have just one Modifier resource controller that also manages Options?
web.php
Route::resource('modifiers', 'ModifierController')->middleware('auth');
Controller:
namespace App\Http\Controllers;
use App\Modifier;
use Illuminate\Http\Request;
class ModifierController extends Controller
{
public function create()
{
$data = ['action' => route('modifiers.store'),'method' => 'POST', 'modifier' => new Modifier()];
return view('modifiers.form',$data);
}
public function store(Request $request)
{
$modifier = new Modifier($request->all());
$this->do_validate($request);
$modifier->save();
return redirect(route('modifiers.index'));
}
}
views/modifiers/form.blade.php
#extends('layouts.layout-2')
#section('content')
<div class="container">
<div class="row justify-content-center">
#include ('layouts.errors')
<div class="col-md-12">
{!! Form::open(['url' => $action, 'method' => 'post', 'class' => 'form', 'id' => 'form'])!!}
#csrf
#method($method)
<div class="form-group">
<label for="name">{{ __('modifiers.name')}}</label>
<input type="text" class="form-control" id="name" name="name" value = "{{old('name',$modifier->name)}}">
</div>
<button id="btnSubmit" class="btn btn-primary">{{ __('common.submit') }}</button>
{!! Form::close() !!}
</div>
</div>
</div>
#endsection
Models:
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Modifier extends Model
{
use SoftDeletes;
protected $guarded = ['id'];
public function options()
{
return $this->hasMany('App\Option');
}
}
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Option extends Model
{
use SoftDeletes;
protected $guarded = ['id'];
public function modifier()
{
return $this->belongsTo('App\Modifier');
}
}
I think you can use a select element:
<select name="options[]" id="options" class="form-control">
#foreach($options as $option)
<option value="{{ $option->id }}" {{ $modifier->options->contains('id', $option->id) ? 'selected' : '' }}>{{ $option->name }}</option>
#endforeach
</select>
Hope it helps.
Then, within some controller:
public function update(Request $request, $id)
{
$modifier = Modifier::find($id);
$modifier->options()->sync($request->input('options'));
// Do whatever more you want to do
}
for my website I need a form which includes a file upload for PDF files, but I'm new to these and don't really know how to do it.
This is what I got so far, but keep getting:
"Too few arguments to function App\Http\Controllers\FileController::create(), 0 passed and exactly 1 expected"
Controller:
<?php
namespace App\Http\Controllers;
use App\User;
use App\Payment;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class FileController extends Controller
{
public function index(){
$users = User::all();
return view('fileupload.create', compact('users'));
}
protected function create(array $data)
{
$request = app('request');
if($request->hasfile('file')){
$file = $request->file('file');
$filename = $file['filename']->getClientOriginalExtension();
Storage::make($file)->save( public_path('/storage/loonstrookjes/' . $filename) );
dd($filename);
}
return Payment::create([
'file_name' => $filename,
'file_path' => '/storage/loonstrookjes/',
'user_id' => $data['employee'],
]);
return route('fileupload.create');
}
}
Model User:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Kyslik\ColumnSortable\Sortable;
class User extends Authenticatable
{
use Notifiable;
use Sortable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $table = 'users';
protected $fillable = [
'username', 'first_name', 'last_name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
Model Payment:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Payment extends Model
{
protected $table = 'payment_list';
protected $fillable = [
'user_id', 'file_name', 'file_path'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'id', 'file_name', 'file_path'
];
}
View:
#extends('layouts.master')
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Loonstrook uploaden') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('create') }}" enctype="multipart/form-data">
#csrf
<div class="form-group row">
<label for="filename" class="col-md-4 col-form-label text-md-right">{{ __('Bestandsnaam') }}</label>
<div class="col-md-6">
<input id="filename" type="text" class="form-control{{ $errors->has('filename') ? ' is-invalid' : '' }}" name="filename" value="{{ old('filename') }}" required autofocus>
#if ($errors->has('filename'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('filename') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group row">
<label for="file" class="col-md-4 col-form-label text-md-right">{{ __('Bestand') }}</label>
<div class="col-md-6">
<input id="file" type="file" class="form-control" name="file">
</div>
</div>
<div class="form-group row">
<label for="usertype" class="col-md-4 col-form-label text-md-right">{{ __('Werknemer:') }}</label>
<div class="col-md-6">
<select class="form-control" name="type">
#foreach($users as $user)
<option value="{{$user->id}}">{{$user->first_name}} {{$user->last_name}}</option>
#endforeach
</select>
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Uploaden') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
#endsection
These are my routes:
Route::get('/create', 'FileController#index')->name('create');
Route::post('/create', 'FileController#create');
I hope someone can help me find out what's wrong or a better way to do this. Thank you in advance!!
EDIT:
Your answers have helped me quite a bit, but now I'm facing another issue...
The controller now looks like this:
<?php
namespace App\Http\Controllers;
use App\User;
use App\Payment;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpFoundation\File\UploadedFile;
UploadedFile::getMaxFilesize();
class FileController extends Controller
{
public function index(){
$users = User::all();
return view('fileupload.create', compact('users'));
}
protected function validator(array $data)
{
return Validator::make($data, [
'filename' => ['required', 'string', 'max:255'],
'file' => ['required', 'file'],
'user_id' => ['required'],
]);
}
protected function create(Request $request)
{
$request = app('request');
if($request->hasfile('file')){
$file = $request->file('file');
$filename = $request->input('filename');
$file = $filename . '.' . $file->getClientOriginalExtension();
$file_path = storage_path('/loonstrookjes');
Storage::disk('local')->putFile($file_path, new File($request->file), $file);
//$path = $request->file('file')->store( storage_path('/storage/loonstrookjes/'));
//$path = Storage::putFile(storage_path('/loonstrookjes/'), $filename);
//dd($upload);
//return $put;
}
return Payment::create([
'file_name' => $filename,
'file_path' => '/storage/loonstrookjes/',
'user_id' => $request['user'],
]);
return route('fileupload.create');
}
}
But I'm getting a new error, this time it's:
Call to undefined method Illuminate\Support\Facades\File::hashName()
Any ideas??
Your problem is you have a parameter in your method create(array $data), but you are posting the form using only {{ route('create') }}. Here you are calling the method by this route without passing the required parameter as you defined it.
Basically, a form post method can accept the requested values by this
protected function create(Request $request)
Because you already used Request as a trait.
So, by this, you can get the requested field value from your form. And you don't have to use $request = app('request'); since you already have it on the parameter variable $request.
In case you want to know
Variables are passed from frontend (view)
to the backend (route) by using {{ route('update', $the_variable) }}.
By this, you can have $the_variable after the last / of your route.
Hope this helps.
Route:
Route::resource('File','FileController');
Controller changes:
public function store(Request $request)
{
if($request->hasfile('file')){
$file = $request->file('file');
$filename = $file['filename']->getClientOriginalExtension();
Storage::make($file)->save( public_path('/storage/loonstrookjes/' . $filename) );
}
return Payment::create([
'file_name' => $filename,
'file_path' => '/storage/loonstrookjes/',
'user_id' => $request->type
]);
return route('fileupload.create');
}
}
View Changes:
form action="{{ route('File.store') }}"
I'm trying to add validation to my resource controller using the laravel's validation (http://laravel.com/docs/5.1/validation) but I get this error:
ErrorException in ValidatesRequests.php line 30:
Argument 1 passed to App\Http\Controllers\Controller::validate() must be an
instance of Illuminate\Http\Request,
instance of Illuminate\Support\Facades\Request given,
called in
/Users/lextoc/Documents/Sites/partyrecycler/app/
Http/Controllers/MarkerController.php on line 30 and defined
This is the controller:
namespace App\Http\Controllers;
use Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Marker;
class MarkerController extends Controller
{
...
public function create()
{
return view('markers.create');
}
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required|max:255',
'x' => 'required',
'y' => 'required',
]);
$marker=Request::all();
Marker::create($marker);
return redirect('markers');
}
...
}
And the view:
<h1>Create marker</h1>
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
{!! Form::open(array('route' => 'markers.store')) !!}
{!! csrf_field() !!}
<div>
Name
<input type="text" name="name">
</div>
<div>
x
<input type="text" name="x">
</div>
<div>
y
<input type="text" name="y">
</div>
<div>
<button type="submit">Create</button>
</div>
{!! Form::close() !!}
I don't know why it's using the wrong Request class, and why are there two being used in the controller?
The error is due to your include headers:
Try
use Illuminate\Http\Request;
Instead of
use Request;
Example:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Marker;