So I'm very new to laravel and I have a filter in my website blade as follows:
goal: the user chooses a city and price from and price to and then clicks search and villas with what selected must be shown on another view! all values from the database!
I've tried to do this:
the route:
Route::get('/searched/{city_id}/{pricefrom}/{priceto}', [WebsiteController::class, 'search'])->name('search.clicked');
the controller:
public function index() {
$cities = DB::table('cities')
->select('*')->distinct()->get();
$users = Villa::with('City','Seller', 'Payment')->get();
$pricefrom = DB::table('villas')
->select('price')
->where('price', '<=', 50000)->distinct()->get();
$priceto = DB::table('villas')
->select('price')
->where('price', '>', 50000)->distinct()->get();
return view('website', compact('users','cities','pricefrom','priceto'));
}
public function search($city_id, $pricefrom, $priceto) {
$city = City::find($city_id);
$price = Villa::find($price);
$citydata = Villa::with('City','Seller', 'Payment')->where('city_id', $city_id)->get();
$lowdata = Villa::with('City','Seller', 'Payment')->where('price', $pricefrom)->get();
$highdata = Villa::with('City','Seller', 'Payment')->where('price', $priceto)->get();
$info = Villa::with('City','Seller', 'Payment')->get();
return view ('searched',compact('citydata','lowdata','highdata','info'))->with('city', $city )->with('price', $price);
}
the website view blade: here I didn't know how exactly I should pass the parameters for the route so I get an error
#foreach ($users as $villa)
<form action="{{ route('search.clicked', $villa->city_id,$villa->pricefrom,$villa->priceto) }}" method="get">
#csrf
<select name="city" class="form-select">
<option value="" id="searchoption"> City </option>
#foreach ($cities as $city)
<option >{{ $city->name }}</option>
#endforeach
</select>
<div class="col-lg-3 p-2">
<select name="pricefrom" class="form-select">
<option value="" id="searchoption"> Price From </option>
#foreach ($pricefrom as $low)
<option >{{ $low->price}}</option>
#endforeach
</select>
</div>
<div class="col-lg-3 p-2">
<select name="priceto" class="form-select">
<option value="" id="searchoption"> Price To </option>
#foreach ($priceto as $high)
<option >{{ $high->price}}</option>
#endforeach
</select>
</div>
<div class="col-lg-3 p-2">
<button type="button" class="btn btn-outline-success">search</button>
</div>
</form>
#endforeach
also Villa model
class Villa extends Model {
use HasFactory;
protected $fillable=[
"id", "title", "description", "price", "state", "status", "city_id", "seller_id", "payment_id",
"created_at", "updated_at"
];
public function City()
{
return $this -> hasOne(City::class,'id','city_id');
}
public function Seller()
{
return $this -> hasOne(Seller::class,'id','seller_id');
}
public function Payment()
{
return $this -> hasOne(Payment::class,'id','payment_id');
}
}
I think I have many errors I should fix And I want some help with my search bar!
I get this error:
Missing required parameters for [Route: search.clicked] [URI: searched/{city_id}/{pricefrom}/{priceto}] [Missing parameters: pricefrom, priceto].
try:
<form action="{{ route('search.clicked', [$villa->city_id,$villa->pricefrom,$villa->priceto]) }}" method="get">
According to route function second parameter should be string or array. String or Array if you're passing only 1 & array if you are passing 2 or more.
function route($name, $parameters = [], $absolute = true)
BLADE FILE:
#foreach ($users as $villa)
<form action="{{ route('search.clicked', $villa->city_id,$villa->pricefrom,$villa->priceto) }}" method="get">
#csrf
<select name="city" class="form-select">
<option value="" id="searchoption"> City </option>
#foreach ($cities as $city)
<option >{{ $city->name }}</option>
#endforeach
</select>
<div class="col-lg-3 p-2">
<select name="pricefrom" class="form-select">
<option value="" id="searchoption"> Price From </option>
#foreach ($pricefrom as $low)
<option >{{ $low->price}}</option>
#endforeach
</select>
</div>
<div class="col-lg-3 p-2">
<select name="priceto" class="form-select">
<option value="" id="searchoption"> Price To </option>
#foreach ($priceto as $high)
<option >{{ $high->price}}</option>
#endforeach
</select>
</div>
<div class="col-lg-3 p-2">
<button type="button" class="btn btn-outline-success">search</button>
</div>
</form>
#endforeach
to
#foreach ($users as $villa)
<form action="{{ route('search.clicked', ['city_id' => $villa->city_id, 'pricfrom' => $villa->pricefrom, 'priceto' =>$villa->priceto]) }}" method="get">
#csrf
<select name="city" class="form-select">
<option value="" id="searchoption"> City </option>
#foreach ($villa->cities as $city)
<option >{{ $city->name }}</option>
#endforeach
</select>
<div class="col-lg-3 p-2">
<select name="pricefrom" class="form-select">
<option value="" id="searchoption"> Price From </option>
#foreach ($villa->pricefrom as $low)
<option >{{ $low->price}}</option>
#endforeach
</select>
</div>
<div class="col-lg-3 p-2">
<select name="priceto" class="form-select">
<option value="" id="searchoption"> Price To </option>
#foreach ($villa->priceto as $high)
<option >{{ $high->price}}</option>
#endforeach
</select>
</div>
<div class="col-lg-3 p-2">
<button type="button" class="btn btn-outline-success">search</button>
</div>
</form>
#endforeach
You need add to route :
<form action="{{ route('search.clicked',$object->first()->city_id,$model->first()->pricefrom,$model->first()->priceto) }}" method="get">
Related
when add next select, you lose the data of the first select of the municipalities.
Livewire controller SelectUsuario.php
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use Illuminate\Support\Facades\Http;
class SelectUsuario extends Component
{
public $estados;
public $estado;
public $estadoSigla;
public $municipios;
public $selects = [];
public $i = 0;
public function add($i)
{
$i = $i + 1;
$this->i = $i;
array_push($this->selects, $i);
}
public function remove($i)
{
unset($this->selects[$i]);
}
public function mount()
{
$this->estados = Http::get(
url("https://servicodados.ibge.gov.br/api/v1/localidades/estados"),
['orderBy' => 'nome']
)->json();
}
public function updatedEstadoSigla()
{
$this->getMunicipios();
}
public function getMunicipios()
{
if ($this->estadoSigla != '') {
foreach ($this->estadoSigla as $estado) {
$this->municipios = json_decode(
Http::get(
url("https://servicodados.ibge.gov.br/api/v1/localidades/estados/{$estado}/municipios")
)->body(),
true
);
}
}
}
public function render()
{
return view('livewire.select-usuario');
}
}
Livewire component select-usuario.blade.php
<div class="form-group row">
<div class="col-3"><label>Viagem</label></div>
<div class="col-3"><label>Seção</label></div>
<div class="col-4"><label>Funcionário</label></div>
<div class="col-2"><label>Ação</label></div>
<div class="col-3">
<select class="form-control" data-item_id="0">
<option value="R">Responsável</option>
</select>
</div>
<div class="col-3">
<select wire:model="estadoSigla.0" class="form-control" id="estado.0" name="estado.0">
<option value="">selecione estado...</option>
#foreach ($this->estados as $estado)
<option value="{{ $estado['sigla'] }}">{{ $estado['nome'] }}</option>
#endforeach
</select>
</div>
<div class="col-4">
#if ($this->estadoSigla)
<select class="form-control" name="municipio.0" id="municipio.0">
<option value="" selected>selecione município...</option>
#foreach ($this->municipios as $municipio)
<option value="{{ $municipio['id'] }}">{{ $municipio['nome'] }}</option>
#endforeach
</select>
#endif
</div>
<div class="col-2">
<button class="btn btn-info mb-2" wire:click.prevent="add({{ $i }})">adicionar</button>
</div>
{{-- Add Form --}}
#foreach ($selects as $key => $value)
<div class="col-3">
<select name="item_name[]" class="form-control" data-item_id="{{$value}}">
<option value="I">Ida</option>
<option value="V">Volta</option>
<option value="O">Ida e Volta</option>
<option value="R">Responsável</option>
</select>
</div>
<div class="col-3">
<select wire:model="estadoSigla.{{ $value }}" class="form-control" name="estado.{{ $value }}" id="estado.{{ $value }}">
<option value="">selecione estado...</option>
#foreach ($this->estados as $estado)
<option value="{{ $estado['sigla'] }}">{{ $estado['nome'] }}</option>
#endforeach
</select>
</div>
<div class="col-4">
#if ($estadoSigla)
<select class="form-control" name="municipio.{{ $value }}" id="municipio.{{ $value }}">
<option value="" selected>selecione município...</option>
#foreach ($this->municipios as $municipio)
<option value="{{ $municipio['id'] }}">{{ $municipio['nome'] }}</option>
#endforeach
</select>
#endif
</div>
<div class="col-2">
<button class="btn btn-dark mb-2" wire:click.prevent="remove({{ $key }})">remover</button>
</div>
#endforeach
</div>
try adding wire:key directive to the looped select elements while livewire need to keep tracking all the values of them.
<select wire:model="estadoSigla.{{ $value }}" class="form-control" id="estado.{{ $value }}" wire:key="estado-select-{{ $key }}"> // or $value, the unique identifier for its
also, try adding wire:ignore.self to the root div of the select elements
This code from product_listing.blade.php and here the dropdown filter. I need all the item name in ascending orde. Right now the list is in order how I can see it in a database table..
<div class="box-title text-center">
{{ translate('Filter by CarType')}}
</div>
<div class="box-content">
<div class="filter-checkbox">
<select class="form-control" data-placeholder="{{ translate('All CarType')}}" name="cartype" onchange="filter()">
<option value="">Select CarType</option>
#foreach (\App\CarType::all() as $cartype)
<option value="{{ $cartype->id }}" #isset($cartype_id) #if ($cartype_id == $cartype->id) selected #endif #endisset>{{ $cartype->name }}</option>
#endforeach
</select>
</div>
</div>
You can use collection's sortBy() method:
<div class="box-title text-center">
{{ translate('Filter by CarType')}}
</div>
<div class="box-content">
<div class="filter-checkbox">
<select class="form-control" data-placeholder="{{ translate('All CarType')}}" name="cartype" onchange="filter()">
<option value="">Select CarType</option>
#foreach (\App\CarType::all()->sortBy('name') as $cartype)
<option value="{{ $cartype->id }}" #isset($cartype_id) #if ($cartype_id == $cartype->id) selected #endif #endisset>{{ $cartype->name }}</option>
#endforeach
</select>
</div>
</div>
I am creating a real estate project, which will have a search option for different pages with different search filters.
Here is one example of the search view
<form class="form-row basic-select-wrapper" method="POST" action="{{route('filter')}}">
#csrf
{{-- <div class="form-group">
<input type="text" name="prop_name">
</div> --}}
<div class="form-group col-lg col-md-6">
<label>Property type</label>
<select name="type_id" class="form-control basic-select">
<option>Select Type</option>
#foreach ($types as $type)
#if ($type->status == 1)
<option value="{{ $type->id }}">{{ $type->name }}</option>
#endif
#endforeach
</select>
</div>
<div class="form-group col-lg col-md-6">
<label>Property Category</label>
<select name="cat_id" class="form-control basic-select">
<option>Select Category</option>
#foreach ($categories as $category)
<option value="{{ $category->id }}">{{ $category->name }}</option>
#endforeach
</select>
</div>
<div class="form-group col-lg col-md-6">
<label>Location</label>
<select name="loc_id" class="form-control basic-select">
<option>Select Location</option>
#foreach ($locations as $location)
<option value="{{ $location->id }}">{{ $location->loc_name }}</option>
#endforeach
</select>
</div>
<div class="form-group col-lg col-md-6">
<label>Budget</label>
<select name="start_price" class="form-control basic-select">
<option>Select Budget</option>
#foreach($price['price'] as $key => $val)
<option value="{{$key}}">{{$val}}</option>
#endforeach
</select>
</div>
<div class="form-group col-lg col-md-6">
<label>Bedroom(s)</label>
<select name="min_bed" class="form-control basic-select">
<option>Select Bedroom</option>
<option value="0">studio</option>
<option value="1">one bedroom</option>
<option value="2">two bedroom</option>
<option value="3">three bedroom</option>
<option value="4">four bedroom</option>
<option value="5">five bedroom</option>
<option value="6">six bedroom</option>
<option value="7">seven bedroom</option>
</select>
</div>
<div class="advanced-search" id="advanced-search">
<div class="card card-body">
<div class="form-group col-md-12">
<div class="mt-0">
<button class="btn btn-primary align-items-center" type="submit"><i
class="fas fa-search mr-1"></i><span>Search</span></button>
</div>
</div>
</div>
</div>
</form>
Here is my search controller
<?php
namespace App\Http\Controllers\User;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
//use App\Models\Listing;
use App\ListingSearch\ListingSearch;
class SearchController extends Controller
{
public function filter(Request $request)
{
return ListingSearch::apply($request);
}
}
Now, to implement this since there are multiple search filters and I wanted to simplify it. Here is the folder structure
folder structure
Here is the Listitng Search Class
<?php
namespace App\ListingSearch;
use Illuminate\Database\Eloquent\Builder;
use App\Models\Listing;
use Illuminate\Http\Request;
class ListingSearch
{
public static function apply(Request $filters)
{
$query = static::applyDecoratorsFromRequest(
$filters, (new Listing)->newQuery()
);
// Get the results and return them.
return static::getResults($query);
}
private static function applyDecoratorsFromRequest(Request $request, Builder $query)
{
foreach ($request->all() as $filterName => $value) {
$decorator = static::createFilterDecorator($filterName);
if (static::isValidDecorator($decorator)) {
$query = $decorator::apply($query, $value);
}
}
return $query;
}
private static function createFilterDecorator($name)
{
return __NAMESPACE__ . '\\Filters\\' .
str_replace(' ', '',
ucwords(str_replace('_', ' ', $name)));
}
private static function isValidDecorator($decorator)
{
return class_exists($decorator);
}
private static function getResults(Builder $query)
{
return $query->get();
}
}
here is an example of one of the filters CATID for category
<?php
namespace App\ListingSearch\Filters;
use Illuminate\Database\Eloquent\Builder;
class CatId implements Filter
{
public static function apply($builder, $value)
{
return $builder->where('cat_id', $value);
}
}
The problem with this is that I have to enter all the required filters to get a result, otherwise if I only fill one filter I get null results, for example I want only apartments, without entering location or category. How can I achieve this?
search query
Did you try to filter the $value before stacking them in your where?
if (!empty($value)) {
}
empty() will take care of filtering out the empty and null values. So you end up adding to your query filter values that actually exists.
EDIT
foreach ($request->all() as $filterName => $value) {
if (!empty($value)) {
$decorator = static::createFilterDecorator($filterName);
if (static::isValidDecorator($decorator)) {
$query = $decorator::apply($query, $value);
}
}
}
EDIT 2
Your option tag has no value attribute defined and there for is not empty when posted to your controller because the browser defaults to the value inside the tag (Select Type, Select Category ect). You need to provide the value attribute as empty so that the POST does not use the inner text like this:
<option value="">Select Type</option>
[...]
<option value="">Select Category</option>
[...]
<option value="">Select Location</option>
[...]
<option value="">Select Budget</option>
Then if (!empty($value)) {} can do it's thing
Here I'm trying to loop supplier names using a foreach loop but I'm getting following error
<tbody style="font-size:small">
#foreach($material as $material)
<tr class="odd" role="row">
{!! Form::open(['route'=>'materialsupplier.store','class'=>'form-horizontal p-t-20']) !!}
<td>{{ $material->name }}<input type="hidden" value="{{ $material->id }}" name="mat_id"></td>
<td></td>
<td>
<div class="form-group{{ $errors->has('sup_id') ? ' has-error' : '' }}">
<div >
<select class="form-control js-cities" name="sup_id">
<option value="" selected disabled>Select Supplier</option>
#foreach ($supplier as $supplier)
<option value="{{ $supplier->id}}">{{$supplier->company_name}}</option>
#endforeach
</select>
</div>
</div>
</td>
<td>
{{ Form::submit('Save',['class'=>'far fa-trash-alt btn btn-info btn-sm btn-rounded m-b-1 m-l-5']) }}
</td>
{!! Form::close() !!}
</tr>
#endforeach
</tbody>
after that i chaged my code like this
<select class="form-control js-cities" name="sup_id">
<option value="" selected disabled>Select Supplier</option>
#foreach ($supplier as $supplier)
<option value="{{ $supplier}}">{{$supplier}}</option>
#endforeach
</select>
output
controller
public function index()
{
$material = Material::all();
$supplier = Supplier::all();
return view('materialMgmt.material_suppliyer.create')->withMaterial($material)->withSupplier($supplier);
}
How can I avoid getting this error?
I changed the code as following and its worked
<select class="form-control js-cities" name="sup_id">
<option value="" selected disabled>Select Supplier</option>
#foreach ($supplier as $sup)
<option value="{{ $sup->id}}">{{$sup->company_name}}</option>
#endforeach
</select>
Sir FatemehNB, Thank for your suggestion.
I want to update the url with the selected options in the form and send it to session but i keep receiving : (Undefined variable: country).
How can fix this please ? and i am very beginner so excuse my dumb mistakes .
My route :
Route::post('/{country}/{region}/{city}', [
'as' => 'locationFinder',
'uses' => 'User\UserLocationsController#store']);
My controller :
class UserLocationsController extends Controller
{
public function store(Request $request, Country $country, Region $region, City $city)
{
session()->put($country->name, $region->name, $city->name);
return redirect()->route('welcome.index', [$country, $region,
$city]);
}
}
My view :
<form action="{{ route('locationFinder',[$country, $region, $city]) }}" method="POST">
<div class="form-group">
<select class="form-control" name="country_id" id="country_id">
<option value="0" disable="true" selected="true"> Select Country </option>
#foreach ($countries as $key => $value)
<option value="{{$value->id}}">{{ $value->name }}</option>
#endforeach
</select>
</div>
<div class="form-group">
<select class="form-control" name="region_id" id="region_id">
<option value="0" disable="true" selected="true"> Select Region </option>
</select>
</div>
<div class="form-group">
<select class="form-control" name="districts" id="districts">
<option value="0" disable="true" selected="true"> Select City </option>
</select>
</div>
<div class="form-group">
<button class="btn btn-primary">submit</button>
</div>
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
My CountryController :
class CountryController extends Controller
{
public function countries(){
$countries = Country::all();
return view('welcome', compact('countries'));
}
public function regions(){
$countries_id = Input::get('country_id');
$regencies = Region::where('country_id', '=', $countries_id)->get();
return response()->json($regencies);
}
public function cities(){
$regions_id = Input::get('region_id');
$districts = City::where('region_id', '=', $regions_id)->get();
return response()->json($districts);
}
}
in the controller you pass "$country"... but in your view you are using "$countries" in the foreach
controller:
..
return redirect()->route('welcome.index', [$country, $region,
$city]);
..
view:
#foreach ($countries as $key => $value)
<option value="{{$value->id}}">{{ $value->name }}</option>
#endforeach