Laravel | custom collection for select2 optgroup and option - php

Using select 2 I want to do something like this (but this syntax is not quite right):
#foreach($courseCategories as $courseCategory)
<select>
#foreach($courseCategory->courseNames as $courseName)
<optgroup label="{{ $courseCategory }}">
<option value="{{ $courseName }}">
{{ $courseName }}
</option>
</optgroup>
</select>
#endforeach
My Model Structure is quite like this:
In my controller:
public function create()
{
$courses = Course::all();
return View::make('college.create', compact('courses'));
}
I need to map courseCategory => optgroup's label and respective course name => option
How can I create a custom collection to faciliate this? and How can I use the collection (I'm guessing using foreach) to output values in my view file?

There a problem in your foreach :
<select>
#foreach($courseCategories as $courseCategory)
#foreach($courseCategory->courseNames as $courseName)
<optgroup label="{{ $courseCategory }}">
<option value="{{ $courseName }}">
{{ $courseName }}
</option>
</optgroup>
#endforeach
#endforeach
</select>

Related

How to keep values in <select> after submitting a form in laravel 8

I have multiple <select> by city filter
select in blade
<select id="city" multiple name="city[]">
#foreach($cities as $city)
<option value="{{ $city->id }}">{{ $city->name }}</option>
#endforeach
</select>
Query for select
if ($request->has('industry')) {
$businessesQuery->whereIn('industry_id', $request->input('industry'));
}
try this
#if(request('type') != "")
$('#city').find('option[value="' + "{{request('type')}}" + '"]').attr('selected', true);
#endif
little manage according to your code then its should work

Determine selected options based on many-to-many relationship

I have three tables: products, categories and category_product.
In my edit form page I'm displaying the categories and subcategories values in a select box.
The chosen category options are saved in the pivot table category_product. This table has product_id and category_id.
Here's my code.
Product model
public function category() {
return $this->belongsToMany('App\Models\Category');
}
Category model:
public function products()
{
return $this->belongsToMany(Product::class);
}
edit product page view:
<select name="category_id[]" class="form-control" multiple size = 10>
#foreach ($parentCategories as $parentCategory)
<option value="{{ $parentCategory->id }}">{{ $parentCategory->name }}</option>
#if(count($parentCategory->subcategory))
#include('includes.subcats-select',['subcategories' => $parentCategory->subcategory])
#endif
#endforeach
</select>
subcats-select view
#foreach($subcategories as $subcategory)
<option value="{{ $subcategory->id }}">---{{ $subcategory->name }}</option>
#if(count($subcategory->subcategory))
#include('includes.subcats-select',['subcategories' => $subcategory->subcategory])
#endif
</div>
#endforeach
How can I put "selected" attribute to the chosen category options, so when I edit the page to apply the changes properly?
You can get pivot table columns the following way:
Product model
public function category() {
return $this->belongsToMany('App\Models\Category')->withPivot('selected');
}
edit product page View:
<select name="category_id[]" class="form-control" multiple size = 10>
#foreach ($parentCategories as $parentCategory)
<option value="{{ $parentCategory->id }}" selected="{{ $parentCategory->pivot->selected }}">
{{ $parentCategory->name }}
</option>
#if(count($parentCategory->subcategory))
#include('includes.subcats-select',['subcategories' => $parentCategory->subcategory])
#endif
#endforeach
</select>
EDIT: While the above answer might be helpful for others, it doesn't answer the question. So here's my second try after some clarification in the chat.
<select name="category_id[]" class="form-control" multiple size = 10>
#foreach ($parentCategories as $parentCategory)
<option value="{{ $parentCategory->id }}"{{ $product->category->contains($parentCategory->id) ? 'selected' : '' }}>
{{ $parentCategory->name }}
</option>
#if(count($parentCategory->subcategory))
#include('includes.subcats-select',['subcategories' => $parentCategory->subcategory])
#endif
#endforeach
</select>

Laravel 6: Dynamic selectbox/droplist population from the database

As stated in the title, I want to dynamically change the available options of an HTML select box, based on the selection of another HTML select box, using PHP only if possible.
So far, I have managed to pass the data from each table into the view but I do not know how to use the primary and secondary keys in this context and without writing logic into the view file, respecting safety precautions.
What I have:
Controller:
...
use Illuminate\Support\Facades\DB;
...
public function create()
{
$sport_categories = DB::table('sport_categories')->get();
$sports = DB::table('sports')->get();
return view('events.create',
[
'sport_categories' => $sport_categories,
'sports' => $sports
]
);
}
View:
<div id="event-sport-category">
<span>Sport Category:</span>
<select name="sport-category">
<option value="default" selected="selected" disabled hidden>Select Sport Category</option>
#foreach($sport_categories as $sport_category)
<option value="{{ $sport_category->id }}" title="{{ $sport_category->desc }}">{{ $sport_category->name }}</option>
#endforeach
</select>
</div>
and
<div id="event-sport">
<span>Sport:</span>
<select name="sport">
<option value="default" selected="selected" disabled hidden>Select Sport</option>
#foreach($sports as $sport)
<option value="{{ $sport->id }}" title="{{ $sport->desc }}">{{ $sport->name }}</option>
#endforeach
</select>
</div>
The database tables are:
sport_categories (id, name, desc)
and
sports (id, sport_category_id, name, desc)
You'll need to use some sort of Javascript for this to work like you want. As #Clint suggested, since PHP is server-side, you won't be able to change your UI at runtime.
The good news is, you can keep everything you've already done. Depending on your comfort level with Javascript, it could be as easy as doing a show/hide of different html inputs based on what is selected.
Using jQuery, you could do something like this:
<div id="event-sport-category">
<span>Sport Category:</span>
<select name="sport-category" id="sportCategory">
<option value="default" selected="selected" disabled hidden>Select Sport Category</option>
#foreach($sport_categories as $sport_category)
<option value="{{ $sport_category->id }}" title="{{ $sport_category->desc }}">{{ $sport_category->name }}</option>
#endforeach
</select>
</div>
<div id="event-sport-one">
<span>Sport:</span>
<select name="sport" id="sport">
<option value="default" selected="selected" disabled hidden>Select Sport</option>
#foreach($sports as $sport)
<option value="{{ $sport->id }}" title="{{ $sport->desc }}">{{ $sport->name }}</option>
#endforeach
</select>
</div>
<div id="event-sport-two">
<span>Sport:</span>
<select name="sport" id="sportTwo">
<option value="default" selected="selected" disabled hidden>Select Sport</option>
#foreach($sportsTwo as $sportTwo)
<option value="{{ $sportTwo->id }}" title="{{ $sportTwo->desc }}">{{ $sportTwo->name }}</option>
#endforeach
</select>
</div>
jQuery
$(document).ready(function(){
$("#sportCategory").change(function(){
var category = $(this).children("option:selected").val();
console.log('selected category: ', category);
if (category == 'foo') {
// show sports related to foo
// hide & reset everything else
...
$('#event-sport-two').show();
$('#event-sport-one').hide();
}
});
});
CSS
#event-sport-two {
display: none;
}
Doing something like that would render/hide all of your available options when the page loads. You'd use CSS to hide the actual form elements, then using jQuery you could show/hide things as needed. This could get messy if you have a lot of things to manage.
Another option would be to make your form a Vue component. You could then use v-show based on what was chosen.
A final alternative (using either way) would be to listen for the input to change -- then make an ajax request to get your data and show the input based on the server's response.
Vue would give you a bit cleaner code. You could get the data and only show what's needed and not have to worry about all the show/hide business. :)
Hope that helps!

laravel 5.4 form dropdown from database

I want to fetch drop down option value & name from database, to do that my controller code is
$roles = Role::pluck('role','user_id');
return view('users.add_role',compact('roles'));
to fetch this data from drop down list my view file code is
<select name="role" class="form-control" >
#foreach($roles as $role)
<option value="{{ $role->user_id }} "> {{ $role->role }} </option>
#endforeach
</select>
but it says error
Trying to get property of non-object (View: C:\xampp\htdocs\auth2\resources\views\users\add_role.blade.php)
if i just only use
<select name="role" class="form-control" >
#foreach($roles as $role)
<option value="{{ $role }} "> {{ $role }} </option>
#endforeach
</select>
then it shows role column of the table, but it not pass option value to database. so what is the correct way to generate option value & name from database?
Your $roles variable containt an array which is looks like
[0] => 'your_role'
[1] => 'your_role'
Where is 0 and 1 index is user_id. So your user_id is set as an index of your $roles array. Simply do it dd($roles) and check the output. $key as $role will work. Where $key will containt the user_id.
#foreach($roles as $key => $role)
<option value="{{ $key }} "> {{ $role }} </option>
#endforeach
I use laravel collective package to generate dropdown list much more easier,
you can do things like, on your blade template and it will render the list for you
{{ Form::select('role', $role )) }}

Populate dropdown in laravel with more than 2 attributes

So far I know how to populate dropdown using Eloquent (and pluck) is this
public function create()
{
$items = Item::all()->pluck('name', 'id');
return view('admin.item.create', compact('items'));
}
And with this
{!! Form::select('item_id', $items, null, ['class' => 'form-control']) !!}
I can generate this
<select name="items" class="form-control">
<option value="1">Item 1</option>
<option value="2">Item 2</option>
<option value="3">Item 3</option>
</select>
But now I want to create something like this
<select name="items" class="form-control">
<option value="1">Item 1 - Location</option>
<option value="2">Item 2 - Location</option>
<option value="3">Item 3 - Location</option>
</select>
I can only use pluck with 2 attributes. But now I want it to display 3 attributes. How do I do that? I'm using Laravel 5.3 by the way. Thanks for the help.
You have an array like [1=> "something",2=>"else"]. So you task is to either iterate the array and edit the values or select the the locations from the database and the use foreach or array_filter
So something like the following:
$items=[];
foreach(Item::all() as $item){
$items[$item->id] = $item->name . " - " . $item->location->name; // build string to display here
}
Edit:
Your comment said location is at the same table so it would look like...
$items=[];
foreach(Item::all() as $item){
$items[$item->id] = $item->name . " - " . $item->location; // build string to display here
}
Pluck location also
public function create()
{
$items = Item::all()->pluck('name', 'id', 'location');
return view('admin.item.create', compact('items'));
}
Generate like this
<select name="items" class="form-control">
#foreach($items as $item)
<option value="{{ $item->id }}">{{ $item->name }} - {{ $item->location }}</option>
#endforeach
</select>
Best way to create list of array is.
public function create(){
$items = Item::where('id','<>','')->lists('name', 'id');
return view('admin.item.create', compact('items'));}

Categories