Insert a Form value from a select in a dynamic url - laravel

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

Related

Load dependent dropdown on Edit Laravel

How to automatically load or retrieve the subcategory/dependent dropdown based on the selected value of parent dropdown in Edit. If I click the edit, the doctor should instantly load. I've been searching for hours for the solutions please help.
Blade
<select name="clinic_id" data-placeholder="Search" data-allow-clear="true"
class="form-control select2bs4" style="width: 100%;" id="load_clinic">
<option selected="selected"></option>
#foreach ($clinic as $id => $item)
<option value="{{ $id }}"
{{ $schedule->clinic_id == $id ? 'selected' : '' }}>
{{ $item }}
</option>
#endforeach
</select>
<select name="doctor_id" data-placeholder="Search" data-allow-clear="true"
class="form-control select2bs4" style="width: 100%;" id="load_doctor">
</select>
Javascript
$(document).ready(function() {
$('#load_clinic').on('change', function(e) {
var clinic_id = e.target.value;
if (clinic_id) {
$.ajax({
url: "{{ route('getDoctor') }}",
type: "POST",
data: {
clinic_id: clinic_id,
_token: "{{ csrf_token() }}"
},
success: function(data) {
if (data) {
$('#load_doctor').empty();
$('#load_doctor').append(
'<option value=""> Select Doctor</option>');
$.each(data, function(key, value) {
$('#load_doctor').append($(
"<option/>", {
value: key,
text: value
}));
});
} else {
$('#load_doctor').empty();
}
}
})
} else {
$('#load_doctor').empty();
}
});
});
Controller
public function edit($id)
{
$schedule = Schedule::findOrFail($id);
$clinic = Clinic::pluck('name', 'id');
$doctor = Doctor::get()->pluck('full_name', 'id');
return view('admin.schedule.edit', compact('schedule', 'doctor', 'clinic'));
}
public function getDoctor(Request $request)
{
$id = $request->clinic_id;
$doctor = Doctor::where('clinic_id', $id)->get()->pluck('full_name', 'id');
return response()->json($doctor);
}
You can get initial select options with PHP before resorting to ajax.
Consider using plural nouns when you are using get() and singular when using i.e. first()
Also, consider using #if(condition) #endif instead of ternary operators in blade
This is solution with PHP, if you want to get doctors with AJAX, in addition to onChange listener, you should also call it when page loads,
Controller
public function edit($id)
{
$schedule = Schedule::findOrFail($id);
$clinic = Clinic::pluck('name', 'id');
$doctor = Doctor::where('clinic_id', $schedule->clinic_id)->get();
return view("admin.schedule.edit", compact('schedule', 'doctor', 'clinic'));
}
Blade
<select name="clinic_id" data-placeholder="Search" data-allow-clear="true"
class="form-control select2bs4" style="width: 100%;" id="load_clinic">
<option selected="selected"></option>
#foreach ($clinic as $id => $item)
<option value="{{ $id }}"
{{ $schedule->clinic_id == $id ? 'selected' : '' }}>
{{ $item }}
</option>
#endforeach
</select>
<select name="doctor_id" data-placeholder="Search" data-allow-clear="true"
class="form-control select2bs4" style="width: 100%;" id="load_doctor">
#foreach($doctor as $item)
<option value="{{$item->id}}">{{$item->full_name}}</option>
#endforeach
</select>

Redering out a view based on dropdown value in Laravel 7

I would like to render a different view for 4 dropdown values in the controller. I'm new to PHP and Laravel and just starting to understand it.
dropdown html:
<div class="col-md-6">
<select name="employees" class="form-control #error('employees') is-invalid #enderror">
<option value="">-- {{ __('choose') }} --</option>
<option value="micro">1 - 5</option>
<option value="small">5 - 50</option>
<option value="medium">50 - 500</option>
<option value="large">500 +</option>
</select>
Controller:
class RegisterControllerStep2 extends Controller
{
public function form()
{
return view('auth.register_step2');
}
public function saveData(Request $request)
{
auth()->user()->update($request->only(['company_name', 'website', 'employees']));
return redirect()->route('home');
}
}
I want to redirect the user to another page other than home based on their selection from the employees dropdown above.
You need something like this
public function saveData(Request $request)
{
auth()->user()->update($request->only(['company_name', 'website', 'employees']));
if($request->employees==='micro'){
return redirect()->route('micro');
}
return redirect()->route('home');
}
Another thought I had on this is you could also do something like
return redirect()->route($request->employees);
As long as you had all your routes set up correctly with matching names to the values in your employees select
For giving a better experience I add this jquery function to justrusty's answer.
By doing this, it is not required for the user to press submit button for changes being applied.
Add a form with an id on the select:
<form action="something" method="post">
#csrf
<select id="employees" name="employees" class="form-control #error('employees') is-invalid #enderror">
<option value="">-- {{ __('choose') }} --</option>
<option value="micro">1 - 5</option>
<option value="small">5 - 50</option>
<option value="medium">50 - 500</option>
<option value="large">500 +</option>
</select>
</form>
Then add below jquery to the end of body section:
$('#employees').change(function() {
this.form.submit();
});
And at last, as justrusty said, redirect to the desired page in the controller:
if($request->employees==='micro'){
return redirect()->route('micro');
}

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.

How to build conditional list of dropdown options in Laravel Voyager

I have a problem with Laravel Voyager v1.2. I need to filter list of related list of options in select dropdown easily by where condition. So let's say I have Post with relation to Category, but I don't want to list all Categories in select dropdown, but just that active ones.
I tried to force Voyager to take my own method to build an relationship in Post model:
public function category_id() {
return $this->belongsTo('Post::class')->where('active',1);
}
Also tried to define scope in BREAD JSON options for the category field:
{
"relationship": {
"key": "id",
"label": "name",
"scopes": [
"active"
]
}
}
Post Model part:
public function scopeActive($query) {
return $query->where('active', 1);
}
This is how my Post class look like (I don't actualy need to filter active categories, but food categories by it's IDs):
public function soup1() {
return $this->belongsTo('App\Meal')->where('meal_category_id',1);
}
public function soup2() {
return $this->belongsTo('App\Meal')->where('meal_category_id',1);
}
public function mealy() {
return $this->belongsTo('App\Meal')->where('meal_category_id',7);
}
public function scopeSoups($query)
{
return $query->where('meal_category_id', 1);
}
public function scopeMealy($query)
{
return $query->where('meal_category_id', 7);
}
I want to receive filtered list of options instead of all model rows.
You can do this easily by overriding the blades in voyager:
Step 1 :
Copy relationship.blade.php
from: /"YourProject"/vendor/tcg/voyager/resources/views/formfields/relationship.blade.php
To: /"YourProject"/resources/views/vendor/voyager/formfields/relationship.blade.php
This way voyager will use this file in your your project views instead of the package file in the vendor.
Read More: Voyager Documentations
Step 2 :
In the line 25 of relationship.blade.php you'll see this block of code:
<select
class="form-control select2-ajax" name="{{ $options->column }}"
data-get-items-route="{{route('voyager.' . $dataType->slug.'.relation')}}"
data-get-items-field="{{$row->field}}"
>
#php
$model = app($options->model);
$query = $model::where($options->key, $dataTypeContent->{$options->column})->get();
#endphp
#if(!$row->required)
<option value="">{{__('voyager::generic.none')}}</option>
#endif
#foreach($query as $relationshipData)
<option value="{{ $relationshipData->{$options->key} }}" #if($dataTypeContent->{$options->column} == $relationshipData->{$options->key}){{ 'selected="selected"' }}#endif>{{ $relationshipData->{$options->label} }}</option>
#endforeach
</select>
Which you should override it with this:
#if($options->table == 'categories')
<div class="ap-form-input">
#php
$model = app($options->model);
$query = $model::where('active', true)->get();
#endphp
<select class="form-control select2" id="language-select" name="{{ $options->column }}">
#if(!$row->required)
<option value="">{{__('voyager::generic.none')}}</option>
#endif
#foreach($query as $relationshipData)
<option value={{ $relationshipData->{$options->key} }} #if($dataTypeContent->{$options->column} == $relationshipData->{$options->key}){{ 'selected="selected"' }}#endif>{{ $relationshipData->{$options->label} }}</option>
#endforeach
</select>
</div>
#else
<div class="ap-form-input">
<select class="form-control select2" name="{{ $options->column }}">
#php
$model = app($options->model);
$query = $model::all();
#endphp
#if(!$row->required)
<option value="">{{__('voyager::generic.none')}}</option>
#endif
#foreach($query as $relationshipData)
<option value={{ $relationshipData->{$options->key} }} #if($dataTypeContent->{$options->column} == $relationshipData->{$options->key}){{ 'selected="selected"' }}#endif>{{ $relationshipData->{$options->label} }}</option>
#endforeach
</select>
</div>
#endif
This way when you're using categories relationship you will only get the active categories.
Click on the link and follow these simple steps, just now I solved my issue.
https://voyager.readme.io/docs/relationships

dynamic select options depend on another select option in laravel

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>

Resources