dynamic select options depend on another select option in laravel - ajax

I have two tables as users and departements. My departments table have two columns as id and title and my users table contains users information columns and one exta column as dept_id which is related to department table id.
I want to create a dropdown select option for departement and when a departement is selected the users which have that related department id should be displayed into another dropdown, how can i do that..?
i am fetching all users and departments data in controller and sending it to view.
my controller is....
public function index()
{
$user = DB::table('users')->get();
$dept = DB::table('departments')->get();
return view('userview', compact('user', 'dept'));
}
and my view is....
<select class="form-control" id="department" name="department" >
#foreach($dept as $dept)
<option value="{{ $dept->id }}">{{ $dept->name }}</option>
#endforeach
</select>
<select class="form-control" id="user" name="user" >
<option> </option>
</select>

I would use an Ajax request to fetch the related users and populate the 2nd list. Set up the relation in the User and Department models like:
// Department.php
public function users() {
return $this->hasMany(User::class);
}
// User.php
public function department() {
return $this->belongsTo(Department::class);
}
In your controller:
// DepartmentController.php
public function index() {
return view('userview', [
'departments' => Department::all()
]);
}
public function users(Request $request, $id) {
if ($request->ajax()) {
return response()->json([
'users' => User::where('dept_id', $id)->get()
]);
}
}
Then in your view, setup an event listener for the change event on the first select:
<select class="form-control" id="department" name="department" >
#foreach($departments as $dept)
<option value="{{ $dept->id }}">{{ $dept->name }}</option>
#endforeach
</select>
<select class="form-control" id="user" name="user" ></select>
<script>
$('#department').on('change', e => {
$('#user').empty()
$.ajax({
url: `/departments/${e.value}/users`,
success: data => {
data.users.forEach(user =>
$('#user').append(`<option value="${user.id}">${user.name}</option>`)
)
}
})
})
</script>

Related

Insert a Form value from a select in a dynamic url

While using laravel to create a movie catalog, I am trying to extract the value from an HTML Form and insert it in the URL.
The objective is that, from the main page which is:
http://127.0.0.1:8000/index/
I want it to extract an ID value from the form and insert it in the url:
http://127.0.0.1:8000/index/1
http://127.0.0.1:8000/index/2
http://127.0.0.1:8000/index/3
As each one is a dynamic view that will display each movie information from the database.
The form is already recognizing the ids and is displaying them in the select form in page, but I am not able to have that value used to insert it in the url as shown above.
Please help me, here is my code:
index.blade.php
<form action=" WHAT TO PLACE HERE??? " method="POST">
#csrf
<select name="selector">
<option value="" disabled selected> --- ID --- </option>
#foreach($movies as $movie)
<option value="{{ $movie->id }}">{{ $movie->id }}</option>
#endforeach
</select>
<button>Buscar</button>
</form>
web.php
Route::get('/index', 'App\Http\Controllers\MovieController#index');
Route::get('/index/create','App\Http\Controllers\MovieController#create');
Route::post('/index','App\Http\Controllers\MovieController#store');
Route::get('/index/{id}','App\Http\Controllers\MovieController#show');
Route::delete('/index/{id}','App\Http\Controllers\MovieController#destroy');
MovieController.php
class MovieController extends Controller
{
public function index() {
$movies = Movie::all();
return view('movies.index', ['movies' => $movies,]);
}
public function show($id) {
$movie = Movie::findOrFail($id);
return view('movies.show', ['movie' => $movie]);
}
public function create() {
return view('movies.create');
}
public function store(){
$movie = new Movie();
$movie->title = request('title');
$movie->synopsis = request('synopsis');
$movie->year = request('year');
$movie->cover = request('cover');
$movie->save();
return redirect('/')->with('mssg','La pelĂ­cula a sido registrada');
}
public function destroy($id) {
$movie = Movie::findOrFail($id);
$movie->delete();
return redirect('/index/');
}
}
Replace you form as:
index.blade.php
<form action="" method="POST" id="form_id">
#csrf
<select name="selector" id="selector">
<option value="" disabled selected> --- ID --- </option>
#foreach($movies as $movie)
<option value="{{ $movie->id }}">{{ $movie->id }}</option>
#endforeach
</select>
<button type="submit">Buscar</button>
</form>
Add script after this :
<script>
$('#selector').change(function(){
var selected_value = $(this).val();
$('#form_id').attr('action', 'http://127.0.0.1:8000/'+selected_value);
});
</script>
This will set your action dynamic as per selection with your select tag

How can I store multiple records in hasMany relation Laravel?

I have two models (Post and Tags) and I need to attach multiple tags with Post. Single tag attach is working fine but I'm having trouble with making it multiple.
Model (Post):
public function tags()
{
return $this->hasMany('App\Models\Tag', 'id', 'tag_id');
}
Controller (Post):
public function store()
{
...
$posts->tag_id = $data['tag_id'];
...
}
Blade (Post create form):
<select name="tag_id">
#foreach($tags as $tag)
<option value="{{ $tag->id }}">{{ $tag->title }}</option>
#endforeach
</select>
What should I do to save multiple tags as relation?
-> first, you need to make select use multiple options, like this :
<select name="tagIDs[]" multiple>
#foreach($tags as $tag)
<option value="{{ $tag->id }}">{{ $tag->title }}</option>
#endforeach
</select>
and notice I named the select tagIDs[] so it sends the selected values as array.
-> second, I assume the relationship between Posts and Tags is a ManyToMany. So you have a pivot table post_tag that has column post_id and tag_id.
in your post controller:
public function store()
{
...
if ($post->save()) {
$post->tags()->sync($request->input('tagIDs', []));
}
...
}
what sync does is synchronize the tag IDs you sent in request to the post (can be used in update post too)

get many to many values and which of them are selected in laravel

Contacts:
id
name
Tags:
id
name
ContactTags:
contact_id
tag_id
In Contacts model:
public function tags()
{
return $this->belongsToMany(Tags::class, "contacts_tags", "contact_id", "tag_id");
}
So if I do
$contact = Contacts::findOrFail($id);
dd($contact->tags);
I successfully get the tags associated with the contact. But how can I get all tags and a flag indicating which one of those is associated?
I'm trying to prevent fetching all tags, loop them and with each iteration loop all contact_tags and check if tag_id matches. I want to display a list of checkboxes with all tags and check the ones that are in the relation.
This code can help you, but I'm using the SELECT multiple component. You can easily adapt it to use the CHECKBOX component.
Contacts model:
public function tags()
{
return $this->belongsToMany(Tags::class, "contacts_tags", "contact_id", "tag_id");
}
ContactController.php
public function edit(Contact $contact)
{
$tags = Tag::all();
return view('contacts.edit',compact('contact', 'tags'));
}
edit.blade.php
<div class="row">
<div class="col">
<div class="form-group">
<strong>Tags:</strong>
<select name="tags_id[]" multiple>
#foreach ($tags as $tag)
#if( $contact->tags->contains($tag) )
<option value="{{ $tag->id }}" selected>{{ $tag->name }}</option>
#else
<option value="{{ $tag->id }}">{{ $tag->name }}</option>
#endif
#endforeach
</select>
</div>
</div>
</div>
Update in ContactController.php
public function update(Request $request, Post $contact)
{
$validatedData = $request->validate([
'tags_id' => ['array'],
]);
$contact->update($request->all());
$contact->tags()->sync($validatedData['tags_id']);
return redirect()->route('contact.index')->with('success', 'Contact successfully updated!');
}
The validation is just an example. The $validatedData has no use here, but it can be used to update the contact if you validate the other fields.

Laravel: IF statement drop down list

So i currently have a drop down list where it will output a list of hotels based on its price. I now want to further develop the drop down list so that it can output a list of hotels based on price AND distance. How would i exactly create a drop down list that will output a list of hotels based on 2 or more criteria.
SearchController.php
public function index(Request $request)
{
$distances = DB::table('posts')->select('distance')->distinct()->get()->pluck('distance');
$prices = DB::table('posts')->select('price')->distinct()->get()->pluck('price');
$postsInRange = $request->has('distance')
? Post::where('distance', $request->distance)->get()
: [];
$postsInRange1 = $request->has('price')
? Post::where('price', $request->price)->get()
: [];
return view('Pages.search', [
'distances' => $distances,
'prices' => $prices,
'posts' => $postsInRange,
'posts' => $postsInRange1,
]);
}
public function store(Request $request)
{
// This will return all request data to your screen.
return $request->all();
return view('Pages.search');
}
Search.blade.php
<select name="distance" id="distance" class="form-control input-lg dynamic" data-dependent="state">
<option value="">Distance</option>
#foreach($distances as $distance)
<option value="{{ $distance }}">{{ $distance }}</option>
#endforeach
</select>
<br>
<select name="price" id="price" class="form-control input-lg dynamic" data-dependent="state">
<option value="">Price</option>
#foreach($prices as $price)
<option value="{{ $price}}">{{ $price}}</option>
#endforeach
So to clarify the drop down list works but only outputs one of the choices selected.
I think what you need is query filter
$post = new Post;
if ($request->has('price')) {
$post->where('price', $request->price);
}
if ($request->has('distance')) {
$post->where('distance', $request->distance);
}
return view('Pages.search', [
'distances' => $distances,
'prices' => $prices,
'posts' => $post->get()
]);
I assume that you need one list applying both filters.

Laravel | Save and display two relations

I'm close to finish my CMS but I have one minor problem.
I can create several teams, works perfectly fine.
I can create several games, works also perfectly fine.
Now I want to create matches between those teams, which means I have two pivot tables.
One called game_match and the other called match_team.
game_match consist of game_idand match_id
match_teamconsist of match_id, team1_idand team2_id
My match/create.blade.php has two dropdown fields for each team.
Saving a single relation to the database works fine for me as I've done this a couple of times, but I can't figure out how to save two relations.
This is what I got so far:
Inside match/create.blade.php
<div class="field m-t-20 is-inline-block">
<p class="control">
<label for="home" class="label"><b>{{ trans_choice('messages.home', 1) }}</b></label>
<input type="hidden" name="home" id="home" :value="homeSelected">
<div class="select">
<select v-model="homeSelected">
#foreach($teams as $team)
<option value="{{ $team->id }}">{{ $team->name }}</option>
#endforeach
</select>
</div>
</p>
</div>
<div class="field m-t-20 is-inline-block">
<p class="control">
<label for="opponent" class="label"><b>{{ trans_choice('messages.opponent', 1) }}</b></label>
<input type="hidden" name="opponent" id="opponent" :value="opponentSelected">
<div class="select">
<select v-model="opponentSelected">
#foreach($teams as $team)
<option value="{{ $team->id }}">{{ $team->name }}</option>
#endforeach
</select>
</div>
</p>
</div>
#section('scripts')
<script>
var app = new Vue({
el: '#app',
data: {
homeSelected: "",
opponentSelected: "",
gameSelected: ""
}
});
</script>
#endsection
MatchController.php
public function store(Request $request)
{
$this->validate($request, [
'title' => 'required|max:255',
'matchday' => 'required',
]);
$match = new Match();
$match->title = $request->title;
$match->matchday = $request->matchday;
if ($match->save()) {
$match->games()->sync($request->game);
$match->teams()->sync( [
['team1_id' => $request->home, 'team2_id' => $request->opponent],
]);
Session::flash('success', trans('messages.created', ['item' => $match->title]));
return redirect()->route('matches.show', $match->id);
} else {
Session::flash('error', trans('messages.error'));
return redirect()->route('matches.create')->withInput();
}
}
match.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Match extends Model
{
use SoftDeletes; // <-- Use This Instead Of SoftDeletingTrait
protected $fillable = [
'title'
];
protected $dates = ['deleted_at'];
public function setHomeTeam () {}
public function teams () {
return $this->belongsToMany('App\Team', 'match_team', 'match_id', 'team1_id');
}
public function games () {
return $this->belongsToMany('App\Game', 'game_match');
}
public function getHomeTeam() {
return $this->belongsToMany('App\Team', 'match_team', 'match_id', 'team1_id');
}
public function getOpponentTeam() {
return $this->belongsToMany('App\Team', 'match_team', 'match_id', 'team2_id');
}
}
Can someone help me?
You should better use firstOrCreate(), updateOrCreate or attach() methods.

Resources