Undefined variable? Maybe the query is wrong? - laravel

I am trying to apply filters to my products
This is my database
I'm trying to filter by gender, if it is a kid or not, price range and size
My form:
<form method="GET" action="{{route('products.all')}}">
<div class="filters">
<select class="form-control search" name="gender">
<option value="" selected disabled hidden>Gender...</option>
<option value="M">Man</option>
<option value="W">Woman</option>
</select>
<label>Kids?</label>
<input class="form-control search" type="checkbox" name="kids" value="1">
<div class="filters-all">
Price...
<div class="search">
<input type="text" class="start d-none" name="price-start" />
<input type="text" class="end d-none" name="price-end" />
<input type="text" id="sampleSlider" />
</div>
</div>
<select class="form-control search" name="size">
<option value="" selected disabled hidden>Sizes...</option>
#foreach($sizes as $size)
<option value="{{$size->size}}">{{$size->size}}</option>
#endforeach
</select>
<input type="submit" class="btn btn-secondary"value="Filter"/>
</div>
</form>
My controller with query:
$gender = $request->get('gender');
$child = $request->get('kids');
$size = $request->get('size');
$price_start = $request->input('price-start');
$price_end = $request->input('price-end');
if(!empty($gender) && !empty($size)&& !empty($price_start) && !empty($price_end)){
Product::whereHas('stocks', function ($query) {
$query->where('size', '=', $size);
})
->whereHas('childs', function ($query){
$query->where('child', '=', $child);
})
->where('gender', '=', $gender)
->whereBetween('price', [$price_start, $price_end])
->inRandomOrder()->paginate(12);
}else{
$products = Product::inRandomOrder()->paginate(12);
}
When submitting the form data, it appears correctly in the get:
But when filtering, the link returns "that the variables are not initialized"
I've been thinking for a while but I have the solution. Maybe the query is wrong?

Related

How can I send data from a form into the table in the database?

I have a form that adds a new property listing into the properties table in the db. I keep getting errors that inputs are null and also Laravel isn't grabbing the value inputted into the select HTML tag. I am putting data into the form, but it keeps telling me the fields are null.
Add property form:
<h1 class="admin-header">Add New Listing</h1>
#if($errors->any())
<h4>{{$errors->first()}}</h4>
#endif
<form method="POST" action="{{ route('admin.store_properties') }}" id="add_property_form" enctype="multipart/form-data">
#csrf
<div>
<label for="prop_title">Property Title</label>
<input type="text" id="prop_title" />
</div>
<div>
<label for="prop_desciption">Property Description</label>
<textarea name="prop_desciption" id="prop_desciption"></textarea>
</div>
<div>
<label for="prop_img">Property Image</label>
<input type="file" name="prop_img" id="prop_img" required />
</div>
<div>
<label for="prop_beds">Number of Bedrooms</label>
<input type="number" name="prop_beds" id="prop_beds" steps="1" min="1" />
</div>
<div>
<label for="prop_baths">Number of Bathrooms</label>
<input type="number" name="prop_baths" id="prop_baths" />
</div>
<div>
<label for="prop_ft">Sqaure Feet</label>
<input type="number" name="prop_ft" id="prop_ft" />
</div>
<div>
<label for="props_basement">Finished Basement?</label>
<select name="props_basement" id="props_basement">
<option value="" selected disabled>Select an option</option>
<option value="yes">Yes</option>
<option value="no">No</option>
</select>
</div>
<div>
<label for="prop_tax">Property Tax</label>
<input type="number" name="prop_tax" id="prop_tax" />
</div>
<div>
<label for="props_heat">Heat Type</label>
<select name="props_heat" id="props_heat">
<option value="" selected disabled>Select an option</option>
<option value="gas">Gas</option>
<option value="oil">Oil</option>
<option value="electric">Electric</option>
</select>
</div>
<div>
<label for="props_waterheater">Finished Basement?</label>
<select name="props_waterheater" id="props_waterheater">
<option value="" selected disabled>Select an option</option>
<option value="yes">Yes</option>
<option value="no">No</option>
</select>
</div>
<div>
<label for="prop_year">Year Built</label>
<input type="number" name="prop_year" id="prop_year" />
</div>
<button type="submit">Add New Listing</button>
</form>
Route:
Route::group(['prefix' => 'admin'], function() {
Route::get('/', function() {
return view('admin.dashboard');
})->middleware('auth');
Route::get('/properties', [PropertiesController::class, 'index'])->middleware('auth');
Route::get('/properties/create', [PropertiesController::class, 'create'])->middleware('auth');
Route::post('/properties/store-post', [PropertiesController::class, 'store'])->name('admin.store_properties')->middleware('auth');
});
Controller store() method:
public function store(Request $request)
{
// Create a new Property and store it in the properties DB
$prop = new Property;
$path;
if ($request->hasFile('prop_img')) {
// Get filename with extension
$filenameWithExt = $request->file('prop_img')->getClientOriginalName();
// Get just filename
$filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);
// Get just extension
$extension = $request->file('prop_img')->getClientOriginalExtension();
// Filename to store
$filenameToStore = $filename . '_' . time() . '.' . $extension;
// Upload Image
$path = $request->file('prop_img')->storeAs('public/property_images', $filenameToStore);
} else {
// Filename to store
$filenameToStore = 'noimage.jpg';
}
$prop->property_title = $request->input('prop_title');
$prop->property_description = $request->input('prop_desc');
$prop->property_image = $path;
$prop->bedrooms = $request->input('prop_beds');
$prop->bathrooms = $request->input('prop_baths');
$prop->square_feet = $request->input('prop_ft');
$prop->finished_basement = $request->input('prop_basement');
$prop->prop_tax = $request->input('prop_tax');
$prop->heat_type = $request->input('prop_heat');
$prop->water_heater = $request->input('prop_waterheater');
$prop->year_built = $request->input('prop_year');
$prop->save();
return view('admin.add_property');
}
I can see a typo in your code
In blade file you used tag name 'props_basement' but in controller you are using 'prop_basement'
Try this to fix:
<select name="prop_basement" id="props_basement">
<option value="" selected disabled>Select an option</option>
<option value="yes">Yes</option>
<option value="no">No</option>
</select>

How to update table records, but only form fields that have data in them?

In my controller, I have my create record method, but I want to edit existing records, but only update the fields that are filled out. I try to only fill out one or two fields on the edit property file, but no matter what field I fill out, it returns the same error:
Attempt to assign property "property_title" on null
Update method in my controller:
public function update(Request $request, $id)
{
// Find the record
$prop = Property::find($id);
if ($request->hasFile('prop_img')) {
$file = $request->file('prop_img');
$filenameWithExtension = $file->getClientOriginalName();
$Extension = $file->getClientOriginalExtension();
$filenameOnly = pathinfo($filenameWithExtension, PATHINFO_FILENAME);
$filename = $filenameOnly . time() . '.' . $Extension;
$file->move('property_images', $filename);
$prop->property_image = $filename;
}
$prop->property_title = $request->input('prop_title');
$prop->property_description = $request->input('prop_desc');
$prop->bedrooms = $request->input('prop_beds');
$prop->bathrooms = $request->input('prop_baths');
$prop->square_feet = $request->input('prop_ft');
$prop->finished_basement = $request->input('prop_basement');
$prop->prop_tax = $request->input('prop_tax');
$prop->heat_type = $request->input('prop_heat');
$prop->water_heater = $request->input('prop_waterheater');
$prop->year_built = $request->input('prop_year');
$prop->save();
return view('admin.properties');
}
Routes:
Route::group(['prefix' => 'admin'], function() {
Route::get('/', function() {
return view('admin.dashboard');
})->name('admin')->middleware('auth');
Route::get('/properties', [PropertiesController::class, 'index'])->name('all-properties')->middleware('auth');
Route::get('/properties/create', [PropertiesController::class, 'create'])->middleware('auth');
Route::post('/properties/store-property', [PropertiesController::class, 'store'])->name('admin.store_properties')->middleware('auth');
Route::get('/properties/delete/{id}', [PropertiesController::class, 'destroy'])->middleware('auth');
// Edit property
Route::get('/properties/edit/{id}', [PropertiesController::class, 'edit'])->name('admin.edit')->middleware('auth');
Route::post('/properties/update/{id}', [PropertiesController::class, 'update'])->middleware('auth');
});
Edit properties blade file:
#extends( 'layouts.admin' )
#section( 'content' )
<h1 class="admin-header">Edit Listing</h1>
#if($errors->any())
<h4>{{$errors->first()}}</h4>
#endif
<form method="POST" action="/admin/properties/update/{id}" class="add_edit_property_form" enctype="multipart/form-data">
#csrf
<div>
<label for="prop_title">Property Title</label>
<input type="text" name="prop_title" id="prop_title" />
</div>
<div>
<label for="prop_desciption">Property Description</label>
<textarea name="prop_desc" id="prop_desc"></textarea>
</div>
<div>
<label for="prop_img">Property Image</label>
<input type="file" name="prop_img" id="prop_img" />
</div>
<div>
<label for="prop_beds">Number of Bedrooms</label>
<input type="number" name="prop_beds" id="prop_beds" steps="1" min="1" />
</div>
<div>
<label for="prop_baths">Number of Bathrooms</label>
<input type="number" name="prop_baths" id="prop_baths" />
</div>
<div>
<label for="prop_ft">Sqaure Feet</label>
<input type="number" name="prop_ft" id="prop_ft" />
</div>
<div>
<label for="props_basement">Finished Basement?</label>
<select name="prop_basement" id="prop_basement">
<option value="" selected disabled>Select an option</option>
<option value="yes">Yes</option>
<option value="no">No</option>
</select>
</div>
<div>
<label for="prop_tax">Property Tax</label>
<input type="number" name="prop_tax" id="prop_tax" />
</div>
<div>
<label for="props_heat">Heat Type</label>
<select name="prop_heat" id="prop_heat">
<option value="" selected disabled>Select an option</option>
<option value="gas">Gas</option>
<option value="oil">Oil</option>
<option value="electric">Electric</option>
</select>
</div>
<div>
<label for="props_waterheater">Finished Basement?</label>
<select name="prop_waterheater" id="prop_waterheater">
<option value="" selected disabled>Select an option</option>
<option value="yes">Yes</option>
<option value="no">No</option>
</select>
</div>
<div>
<label for="prop_year">Year Built</label>
<input type="number" name="prop_year" id="prop_year" />
</div>
<button type="submit">Add New Listing</button>
</form>
#endsection
Edit method code:
public function edit($id)
{
return view('admin.edit_property');
}
Results of var_dump
var_dump($id):
string(5) "{$id}"
var_dump($request::all()):
array(8) { ["_token"]=> string(40) "9QOxw20xoy1mEDD6BTWZEJtMpgl3rC16ACejvtcU" ["prop_title"]=> string(4) "Test" ["prop_desc"]=> NULL ["prop_beds"]=> NULL ["prop_baths"]=> NULL ["prop_ft"]=> NULL ["prop_tax"]=> NULL ["prop_year"]=> NULL }
$prop = Property::find($id);
var_dump($prop):
NULL
this error means that this line
$prop = Property::find($id);
returns null, almost because a null value passed to the $id variable
due to the missing $ sign at the action of the edit form, also the variables at the blade should be with double curly braces
So
1- you need to change this line
<form method="POST" action="/admin/properties/update/{id}" class="add_edit_property_form" enctype="multipart/form-data">
to this and it should work with you
<form method="POST" action="/admin/properties/update/{{$id}}" class="add_edit_property_form" enctype="multipart/form-data">
i just added $ sign and in double curly-braces {{$id}}
2- you need to update your edit method, you need to pass the $id parameter to the view
so, you need to update this method
public function edit($id)
{
return view('admin.edit_property');
}
to
public function edit($id)
{
return view('admin.edit_property')->with('id',$id);
}
or to
public function edit($id)
{
return view('admin.edit_property')->with(compact('id'));
}

Append sort route with search results in Laravel

I want to append my search result /search?allsearch= and sort url /search?sort= together but I can't find the solution yet.
Here is my code:
<form class="form-inline my-2 my-lg-0 rounded left-addon-search inner-addon" action="/search" method="GET">
<i class="fas fa-search"></i>
<input type="text" name="allsearch" class="search-field rounded" placeholder="Search" aria-label="Search" aria-describedby="search-addon" />
</form>
<select id="sort" name="sort">
<option value="">Relevance</option>
<option value="product_price_low_high" #if(isset($_GET['sort']) && $_GET['sort']=="product_price_low_high") selected="" #endif>Price: Low to High</option>
<option value="product_price_high_low" #if(isset($_GET['sort']) && $_GET['sort']=="product_price_high_low") selected="" #endif>Price: High to Low</option>
<option value="product_latest" #if(isset($_GET['sort']) && $_GET['sort']=="product_latest") selected="" #endif>Latest Arrivals</option>
</select>
My Controller:
$search = $request->allsearch;
$product = DB::table('brands')
->join('products', 'brands.id', '=', 'products.brandid')
->where('productname','like','%'.$search.'%')
->OrWhere('name','like','%'.$search.'%');
// sorting product
if (isset($_GET['sort']) && !empty($_GET['sort'])) {
if ($_GET['sort'] == "product_price_low_high") {
$product->orderBy('productprice', 'asc');
} elseif ($_GET['sort'] == "product_price_high_low") {
$product->orderBy('productprice', 'desc');
} elseif($_GET['sort'] == "product_latest") {
$product->orderBy('id', 'desc');
}
}
$product = $product->get();
My route:
Route::get('/search','ProductController#search')->name('allsearch', 'sort');
Independently, the /search?allsearch= and the /search?sort= will work. But if I try to search for something, then sort the results, it clears out the search request.
Any idea how to make this works?
you have to set the request value to the form so that you can work with both of them. you can use hidden input for the missing value in each form
the search form
<form class="form-inline my-2 my-lg-0 rounded left-addon-search inner-addon" action="{{ route('search') }}" method="GET">
<i class="fas fa-search"></i>
<input type="text" name="allsearch" value="{{ request()->allsearch }}" class="search-field rounded" placeholder="Search" aria-label="Search" aria-describedby="search-addon" />
<input type="hidden" name="sort" value="{{ request()->sort }}" />
</form>
the sort form
<form class="form-inline my-2 my-lg-0 rounded left-addon-search inner-addon" action="{{ route('search') }}" method="GET">
<select id="sort" name="sort">
<option value="">Relevance</option>
<option value="product_price_low_high" #if (request()->sort == "product_price_low_high") selected #endif>Price: Low to High</option>
<option value="product_price_high_low" #if (request()->sort == "product_price_high_low") selected #endif>Price: High to Low</option>
<option value="product_latest" #if (request()->sort == "product_latest") selected #endif>Latest Arrivals</option>
</select>
<input type="hidden" name="allsearch" value="{{ request()->allsearch }}" />
</form>
why your route has two names?? route shuold have a single unique name
Route::get('search', 'ProductController#search')->name('search');
and in controller
use Illuminate\Http\Request;
public function search(Request $request)
{
$search = $request->allsearch;
$product = DB::table('brands')
->join('products', 'brands.id', '=', 'products.brandid')
->where('productname', 'like', '%'.$search.'%')
->orWhere('name', 'like', '%'.$search.'%');
if ($request->sort == "product_price_low_high") {
$product->orderBy('productprice', 'asc');
} elseif ($request->sort == "product_price_high_low") {
$product->orderBy('productprice', 'desc');
} elseif ($request->sort == "product_latest") {
$product->orderBy('id', 'desc');
}
$product = $product->get();
return response/view
}
you are using laravel, so try to code as the laravel way

How to filter subcategory data from parent category in Laravel8

I want to filter subcategory data according to parent category.
I am getting all my subcategory inside all the categories. I tried many old answers from stackoverflow and youtube but not worked.
I want this filter inside my article post form.
create.article.blade.php
<form action="{{ URL::to('post-article-form') }}" method="post" enctype="multipart/form-data">
#csrf
<div class="form-group">
<label for="exampleInputEmail1">Article Name <b style="color: red">*</b></label>
<input type="text" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter article title" name="articleTitle" required>
</div>
<div class="form-group">
<label for="exampleInputEmail1"> Select Article category </label>
<select class="form-control" name="category" id="category" required>
<option value=""> Select </option>
#foreach($categories as $category)
<option value="{{ $category->id }}"> {{ $category->name }}</option>
#endforeach
</select>
</div>
<div class="form-group">
<label for="exampleInputEmail1"> Select Sub category </label>
<select class="form-control" name="subCategory" id="subCategory" required>
<option value=""> Select </option>
#foreach($subCategories as $subCategory)
<option value="{{ $subCategory->id }}"> {{ $subCategory->name }}</option>
#endforeach
</select>
</div>
I used this below script for filter but not worked.
<script>
$('#category').on('change',function(e){
console.log(e);
var cat_id = e.target.value;
//ajax
$.get('/ajax-subcat?cat_id='+cat_id, function(data){
//subcategory
$('#subCategory').empty();
$('#subCategory').append($("<option></option>").val("").html("--Select Sub Category--"));
$.each(data,function(index, subcatObj){
$('#subCategory').append('<option value="'+subcatObj.id+'">'+subcatObj.name+'</option>');
})
})
});
</script>
My web.php route
//sub category
Route::get('add-sub-category', [SubCategoryController::class, 'create']);
Route::post('post-sub-category-form', [SubCategoryController::class, 'store']);
Route::get('subcategories', [SubCategoryController::class, 'index']);
Route::get("/ajax-subcat", function (Request $request){
$cat_id = $request-> Input::get('cat_id');
$subCategories = SubCategory::where('category_id',$cat_id)->get();
return response()->json($subCategories);
});

Search function, only shows two specific people and not others in database

Using Laravel 5.8 for an assignment on CRUD cricket players and searching them.
My search function only works with one or two specific entries, the first person in my database and one I have created when I add a player.
When I search any other player by first name in the database my results page returns blank.
I have tried different conditional statements and eloquent queries.
Search form
#extends('layout')
#section('content')
<div class="container-fluid">
<div class="row">
<div class="col-md-6">
Search
<form action="/searchresults" method="POST" role="search">
{{ csrf_field() }}
<div class="form-group">
<label for="name">First Name </label>
<input type="text" class="form-control" name="firstName" id="firstName" placeholder="First name">
</div>
<div class="form-group">
<label for="name">Last Name </label>
<input type="text" class="form-control" name="lastName" id="lastname" placeholder="Last name">
</div>
<div class="form-group">
<label for="age">Age </label>
<input type="number" class="form-control" name="age" id="age" placeholder="Age" value="age">
</div>
<div class="form-group">
<label for="role">Role </label>
<select class="form-control" name="role" id="role" value="role">
<option> Top-order Batsman </option>
<option> Bowler</option>
<option>Wicketkeeper batsman </option>
<option> Allrounder</option>
<option> Opening Batsman</option>
<option>Wicket Keeper Batsman</option>
<option>Middle-order Batsman</option>
<option>Batting Allrounder</option>
<option>Bowling Allrounder</option>
</select>
</div>
<div class="form-group">
<label for="batting">Batting </label>
<select class="form-control" name="batting" id="batting" value="batting">
<option>Right-hand Bat</option>
<option>Left-hand Bat</option>
</select>
</div>
<div class="form-group">
<label for="Bowling">Bowling</label>
<select class="form-control" name="bowling" id="bowling" value="bowling">
<option> Right-arm offbreak</option>
<option> left-arm fast-medium</option>
<option>Right-arm fast-medium</option>
<option> Right-arm fast</option>
<option>Right-arm medium</option>
<option> legbreak</option>
</option>Left-arm Orthodox</option>
<option>Right-arm spinoff</option>
<option> Slow left-arm Orthodox</option>
</select>
</div>
<div class="form-group">
<label for="odiRuns"> OdiRuns </label>
<input type="number" class="form-control" name="odiRuns" id="odiRuns" value="odiRuns"
placeholder="OdiRuns">
</div>
<div class="form-group">
<label for="Country">Country</label>
<select class="form-control" name="country" id="country" value="country">
<option selected valued=""> Choose...</option>
<option value="All" required>All</option>
#foreach($allcountries as $country)
<option>{{$country->name}}</option>
#endforeach
</select>
<p>(if you dont know the country please select all)</p>
</div>
<button type="submit" class="btn btn-default">Search
<span class="glyphicon glyphicon-search"></span>
</button>
</span>
</div>
</form>
</div>
</div>
</div>
#endsection
Controller
public function search()
{
$search = request()->all();
$firstName = $search['firstName'];
$lastName = $search['lastName'];
$age = $search['age'];
$role = $search['role'];
$batting = $search['batting'];
$bowling = $search['bowling'];
$odiRuns = $search['odiRuns'];
$country = $search['country'];
$countries = Country::all();
$players = Player::query();
if (!empty($firstName)) {
$players->Where('firstName', 'like', '%' . $firstName . '%');
} elseif (empty($firstName)) {
$players->get();
}
if (!empty($lastName)) {
$players->Where('lastName', 'like', '%' . $lastName . '%');
} elseif (empty($lastName)) {
$players->get();
}
if (empty($age) || $age == 'All') {
$players->get();
} else {
$players->Where('age', $age);
}
if (empty($role) || $role == 'All') {
$players->get();
} else {
$players->Where('role', $role);
}
if (empty($batting) || $batting == 'All') {
$players->get();
} else {
$players->Where('batting', $batting);
}
if (empty($bowling) || $bowling == 'All') {
$players->get();
} else {
$players->Where('bowling', $bowling);
}
if (empty($odiRuns) || $odiRuns == 'All') {
$players->get();
} else {
$players->Where('odiRuns', $odiRuns);
}
if (empty($country) || $country == 'All') {
$players->get();
} else {
$selected = Country::where('name', $country)->get();
$players->where('country', $selected[0]->id);
}
$results = $players->get();
return view('searchresults', compact('results', 'countries'));
}
Results page
#extends('layout')
#section('content')
<table class="table">
<tr scope="row">
<th>First Name</th>
<th>Last Name</th>
<th>Age</th>
<th>Role</th>
<th>Batting</th>
<th>Bowling</th>
<th>odiRuns</th>
<th>Country</th>
<th>Player Image</th>
<th>Flag</th>
</tr>
#foreach ($results as $player )
<tr scope="row">
<td>{{$player->firstName}}</td>
<td>{{$player->lastName}}</td>
<td>{{$player->age}}</td>
<td>{{$player->role}}</td>
<td>{{$player->batting}}</td>
<td>{{$player->bowling}}</td>
<td>{{$player->odiRuns}}</td>
<td>{{$player->country->name}}</td>
<td><img src="{{ asset('images/'.$player->image) }}" class="playerimg" /></td>
<td><img src="{{asset('images/'.$player->country->flag)}}" class="flagimg" /></td>
<td>
<form method="POST" action="{{route('player.destroy',$player->id)}}">
{{csrf_field()}}
{{method_field('DELETE')}}
<button type="submit" name="deletePlayer" class="btn btn-secondary btn-md">Del</button>
</form>
</td>
<td><a class="btn btn-primary btn-md" href="{{route('player.edit',$player->id)}}" name="editPlayer"
role="button">Edit</button></td>
</tr>
#endforeach
</table>
#endsection
I would like to view certain players when searched on different aspects, like first name or last name or age, instead, I get the same two results printed the first in my database and one player I have created

Resources