I have a search form to list properties/ads through certain criteria. I am trying to fetch all properties based on offer or demand, depending on what is clicked in the form. I have three tables
properties (id, price, location)
properties_categories (property_id, category_id)
categories (id, category, priority)
In the row category in the categories table, there are two values, offer, and demand. With the current code when I select offer or demand and click submit I get [] empty array. Any help is appreciated. Here is my code:
Category.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
public $timestamps = false;
public function property()
{
return $this->belongsToMany(Property::class);
}
}
Property.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Property extends Model
{
protected $guarded = ['id'];
public function category()
{
return $this->belongsToMany(Category::class, 'properties_categories')->orderBy('priority', 'asc');
}
}
CategoryController.php
<?php
namespace App\Http\Controllers;
use App\Category;
use App\Http\Controllers\Controller;
use App\Property;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redirect;
class CategoryController extends Controller
{
public function index()
{
return view('categories.search', compact('data'));
}
public function search($propertyBidAsk, $propertyType, $propertyPayment, $city, $price, $quadrature, Request $request, Property $property)
{
$category = $property->category;
if (!empty($request->propertyBidAsk)) {
return $property->category()->where('category', $request->propertyBidAsk)->get();
}
$results = $property;
return view('categories.search', compact('category', 'results'));
}
}
search.blade.php
<div>
#if(isset($results))
<table class="table">
<thead>
<th>Property Bid Ask</th>
</thead>
<tbody>
#foreach ($results as $result)
<tr>
<td>{{ $result->category[0]->category }}</td>
</tr>
#endforeach
</tbody>
</table>
#endif
</div>
<form id="searchForm" method="GET" action="/search">
<div class="col-md-4 mb-6">
<h5>Payment</h4>
<div class="d-block my-3">
<div class="custom-control custom-radio">
<input id="offer" name="propertyBidAsk" value="offer" type="radio" class="custom-control-input">
<label class="custom-control-label" for="offer">Offer</label>
</div>
<div class="custom-control custom-radio">
<input id="demand" name="propertyBidAsk" value="demand" type="radio" class="custom-control-input">
<label class="custom-control-label" for="demand">Demand</label>
</div>
</div>
</div>
<button class="btn btn-primary btn-lg btn-block" type="submit">Search</button>
</form>
web.php
Route::get('/search', 'CategoryController#index');
Route::get('/search/{propertyBidAsk}/{propertyPayment}/{propertyType}/
{city}/{price}/{quadrature}', 'CategoryController#search');
Use different route names and remove route params like the below code,
Route::get('/search-data', 'CategoryController#search');
Also, remove parameters from the search action and use request() in your search function.
Related
This is my web.php file and i have used the correct get and post methods and have specified the path correctly
<?php
use Illuminate\Support\Facades\Route;
namespace App\Http\Controllers\FileController;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome');
});
Route::post('store', [FileController::class,'store']);
Route::view('imgupload','imageUpload');
blade file--imageUplods;where i get like 2 images and store it as a multiple entry in the db
<form method="post" action="store" enctype="multipart/form-data">
#csrf
<div class="input-group realprocode control-group lst increment" >
<input type="file" name="filenames" class="myfrm form-control" id="filenames">
<div class="input-group-btn">
<button class="btn btn-success" type="button"> <i class="fldemo glyphicon glyphicon-plus">
</i>Add</button>
</div>
</div>
<div class="clone hide">
<div class="realprocode control-group lst input-group"
style="margin-top:10px">
<input type="file" name="filenames" class="myfrm form-control"
id="filenames">
<div class="input-group-btn">
<button class="btn btn-danger" type="button"><i class="fldemo
glyphicon glyphicon-remove">
</i> Remove</button>
</div>
</div>
</div>
<button type="submit" class="btn btn-success" style="margin-
top:10px">Submit</button>
</form>
</div>
model: filemodel - filesnames is the only attribute to enter
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class file extends Model
{
use HasFactory;
protected $fillable = [
'filenames'
];
public function setFilenamesAttribute($value)
{
$this->attributes['filenames'] = json_encode($value);
}
}
Controller-FileController- imageUploder is the blade file
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use App\Models\File;
use Illuminate\Support\Facades\Auth;
class FileController extends Controller
{
/**
* Show the application dashboard.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
return view('imageUpload');
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$this->validate($request, [
'filenames' => 'required',
'filenames.*' => 'image'
]);
$files = [];
if($request->hasfile('filenames'))
{
foreach($request->file('filenames') as $file)
{
$name = time().rand(1,100).'.'.$file->extension();
$file->move(public_path('files'), $name);
$files[] = $name;
}
}
$file= new File();
$file->filenames = $files;
$file->save();
return redirect('imageUpload')->with('success', 'Your images has
been successfully added');
}
}
You are mixing up 'use' and 'namespace'. 'namespace' is for defining the namespace of the current class
Change this line
namespace App\Http\Controllers\FileController;
to
use App\Http\Controllers\FileController;
Change what Gert said about the namespace in web.php
Change
class file extends Model
to
class File extends Model
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();
in my code,i want to show category and sub catagory under the Category in the Products table.
Here is my categories table
1.
public function up() { Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->integer('parent_id'); //sub category id
$table->string('name');
$table->rememberToken();
$table->timestamps();
});
}
Here is my products table
2.
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->integer('category_id');
$table->string('product_name');
$table->timestamps();
});
}
Here is my Category Model
3.Category.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Category extends Model { protected $guarded=[];
public function products(){
return $this->hasMany('App\Product');
}
public function parent(){
return $this->belongsTo('App\Category','parent_id','id');
}
}
Here is my Product Model
4.Product.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
public function category(){
return $this->hasone('class::Category');
}
}
Now here is my ProductsController.php
5.ProductsController.php
<?php
namespace App\Http\Controllers;
use App\Category;
use App\Product;
use Session;
use Illuminate\Http\Request;
class ProductsController extends Controller
{
public function product(){
return view('admin.products.product');
}
}
Here is my product.blade.php file
<form class="form-horizontal" method="post" action="{{route('add.product')}}" name="add_product" id="add_product" novalidate="novalidate">
#csrf
<div class="control-group">
<label class="control-label">main Category </label>
<div class="controls">
<select name="category_id" id="category_id" style="width:220px;">
#foreach(App\Category::all() as $cat)
<option value="{{$cat->id}}" >{{ $cat->parent()->name ? $cat->parent()->name . ' -- ' : '' }}{{$cat->name}}</option>
#endforeach
</select>
</div>
</div>
<div class="control-group">
<label class="control-label">Product Name</label>
<div class="controls">
<input type="text" name="product_name" id="product_name">
</div>
</div>
<div class="form-actions">
<input type="submit" value="submit" class="btn btn-success">
</div>
</form>
I want to data like this in my product.blade.php
what data i want
thats why i use this code in product.blade.php
#foreach(App\Category::all() as $cat)
<option value="{{$cat->id}}" >{{ $cat->parent()->name ? $cat->parent()->name . ' -- ' : '' }}{{$cat->name}}</option>
#endforeach
but i facing error like this
ErrorException (E_ERROR)
Undefined property: Illuminate\Database\Eloquent\Relations\BelongsTo::$name (View: F:\laragon\www\flipcart\resources\views\admin\products\product.blade.php)
Previous exceptions
Undefined property: Illuminate\Database\Eloquent\Relations\BelongsTo::$name (0)
There are a number of things you may want to review in this code as there are several odd bits.
The error you are getting is caused by this code:
$cat->parent()->name
You are accessing a query builder instance when you call a relationship as a method rather than a property (i.e. ->parent() rather than ->parent).
Try this instead:
$cat->parent->name
Your ternary statement should then be replaced with something like this:
$cat->parent ? $cat->parent->name . ' -- ' : ''
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
}
I'm facing some issues with a project build with Laravel 5.5.
I would like to save datas from a form in a database and display them in a array. I have code a #foreach loop in the tbody of the array's section:
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Nom</th>
<th>Prix</th>
<th>Categorie</th>
<th colspan="2">Action</th>
</tr>
</thead>
<tbody>
#foreach($products as $product)
<tr>
<td>{{$product->id}}</td>
<td>{{$product->name}}</td>
<td>{{$product->price}}</td>
<td>{{$product->category}}</td>
<td><a href="{{action('ProductController#edit', $product->id)}}"
class="btn btn-warning">Edit</a></td>
<td>
<form action="{{action('ProductController#destroy', $product->id)}}"
method="post">
{{csrf_field()}}
<input name="_method" type="hidden" value="DELETE">
<button class="btn btn-danger" type="submit">Delete</button>
</form>
</td>
</tr>
#endforeach
</tbody>
</table>
Form
<form id ="AddFormProduct" method="post" action="{{url('products')}}">
{{csrf_field()}}
<div class="row">
<div class="col-md-4"></div>
<div class="form-group">
<label for="name">Nom:</label>
<input type="text" class="form-control" name="name">
</div>
</div>
<div class="row">
<div class="col-md-4"></div>
<div class="form-group">
<label for="price">Prix:</label>
<input type="text" class="form-control" name="price">
</div>
</div>
<div class="row">
<div class="col-md-4"></div>
<div class="form-group">
<label for="category">Categorie:</label>
<select name="selectCategory" id="selectCategory" class="form-control">
#foreach($categories as $category)
<option value="{{$category->id}}">{{$category->name}}</option>
#endforeach
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4"></div>
<div class="form-group">
<button type="submit" class="btn btn-success" style="margin-left:38px">Enregistrer</button>
</div>
</div>
</form>
First problem is that I cannot display the view (with the array & the form) because I have this:
ErrorException (E_ERROR)
Undefined variable: products (View: C:\xampp\htdocs\Laratest\resources\views\template.blade.php)
I've tried many solutions, the last one is:
Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Product;
use View;
class ProductController extends Controller
{
public function index()
{
$products = Product::orderBy('id','name')->get();
return view('template', compact('products','categories'));
// $products = Product::all();
// return view('template', ['products' => $products]);
}
public function create()
{
//
}
public function store(Request $request)
{
$product = $this->validate(request(), [
'name' => 'required',
'price' => 'required|numeric',
'category' => 'required'
]);
Product::create($product);
return back()->with('success', 'Le produit a bien été ajouté !');
}
public function edit($id)
{
$product = Product::find($id);
return view('products.edit',compact('product','id'));
}
public function update(Request $request, $id)
{
$product = Product::find($id);
$this->validate(request(), [
'name' => 'required',
'price' => 'required|numeric',
'category' => 'required'
]);
$product->name = $request->get('name');
$product->price = $request->get('price');
$product->category = $request->get('category');
$product->save();
return redirect('products')->with('success','Le produit a bien été
modifié !');
}
public function destroy($id)
{
$product = Product::find($id);
$product->delete();
return redirect('products')->with('success','Le produit a bien été
supprimé !');
}
}
Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Input;
class Product extends Model
{
protected $fillable = [
'name',
'price',
'category'
];
}
Routes
Route::resource('products','ProductController');
Route::get('/monCommerce', 'ProductController#index')->name('products');
The second problem is that I don't know how to get my values from a select>options, it's only works with input fields. = RESOLVED
Please suggest.
For your first question change your route to
Route::get('/monCommerce', 'ProductController#index')->name('products');
Route::resource('products','ProductController');
If that is not the case then :
It may be because you have an empty table or table without any rows this will definitely return a null object. So check for that error. You can either do this on your controller or on blade itself, I recommend doing it on your controller.
If checking it on blade :
try doing the follow:
#if($products == null || $products == "")
No data found
#else
Your foreach loop
#endif
If trying out on controller:
Just use try and catch exception handler.
For your second question try changing
<select name="selectCategory" id="selectCategory" class="form-control">
to
<select name="category" id="selectCategory" class="form-control">
Because you have category field and you have specified category as fillable in your model. If you would like to keep your select name as selectCategory then you will have to change request in your controller.
Just in case if you want to keep selectCategory name in your select form
In your ProductController#store
public function store(Request $request)
{
$request->category=$request->selectCategory;
}