I've got an tiny little problem. I've got a table in database called 'player_skills'. It contains columns like this (example):
player_id | skill_id | value | count
15 0 10 12
15 1 10 51
...
15 8 10 12
The player_id is actually an id of the player which is column 'id' under 'players' table.
Also there are eight skills. Value is the default value (which is irrelevant in this case). The count is the value (the value of the players skill).
Basically, what I want is to pull data into a Bootstrap tabs (example):
<div class="tabbable tabs-left">
<ul class="nav nav-tabs">
<li class="active">Section 1</li>
<li>Section 2</li>
<li>Section 3</li>
...
</ul>
<div class="tab-content">
<div class="tab-pane active" id="?skill0">
<p>I'm in Section A.</p>
</div>
<div class="tab-pane" id="?skill1">
<p>Howdy, I'm in Section B.</p>
</div>
<div class="tab-pane" id="?skill2">
<p>What up girl, this is Section C.</p>
</div>
</div>
</div>
I want to order it (from the highest to the lowest,( also I have an 'group_id' column in every player, so I don't want it to include a player which has an group_id equals to three) but for every skill). Also I have one skill that's located in the 'players' table (column called 'experience') and I've done it like this:
public function highscores()
{
$players = Player::orderBy('experience','desc')->get();
return View::make('aac.highscores')->with('players', $players);
}
It works just fine, but I need it in tabs to change for every skill.
Your need is really well covered by Laravel. First, you have to declare a many to many relationship between skills and players like this (read more : http://laravel.com/docs/eloquent#many-to-many) :
class Skill extends Eloquent {
public function players() {
return $this->belongsToMany('Player', 'player_skills', 'skill_id', 'player_id')
->withPivot('value', 'count');
}
}
Then you can get all your skills from your database with the players linked with the with method. This method is not obligatory (you can use all instead) but eager loading is a good practice here (read more : http://laravel.com/docs/eloquent#eager-loading) :
class SkillController extends BaseController {
public function index()
{
$skills = Skill::with('players')->get();
return View::make('skill.index', array('skills' => $skills));
}
}
Finally just can iterate over your skills array and over the players arrays inside each skill (read more about blade templating : http://laravel.com/docs/templates#blade-templating) :
<!-- index.blade.php -->
<div class="tabbable tabs-left">
<ul class="nav nav-tabs">
#foreach ($skills as $skill)
<li>{{ $skill->name }}</li>
#endforeach
</ul>
<div class="tab-content">
#foreach ($skills as $skill)
<div class="tab-pane active" id="?{{ $skill->id }}">
#foreach ($skills->players as $player)
<p>{{ $player->name }} : {{ $player->pivot->count }} points !</p>
#endforeach
</div>
#endforeach
</div>
</div>
If you want to order your players by skill count you can use the sortBy function like that (read more : http://laravel.com/docs/eloquent#collections) :
$orderedPlayers = $skill->players->sortBy(function($player) {
return $player->pivot->count;
});
Ask if something is not clear.
Related
im new at Laravel, so i have following problem:
I have db with issue table, that contains 15 names of diseases with it's description. This is my model
class Issue extends Model
{
use HasFactory;
use SoftDeletes;
protected $guarded = false;
public function gender() {
return $this->belongsTo(BodyPart::class);
}
}
And here's controller:
use App\Http\Controllers\Controller;
use App\Models\Issue;
class IndexController extends Controller
{
public function __invoke()
{
$eye_issues = Issue::all();
return view('app.issues.man.eyes.index', compact('eye_issues'));
}
}
And finally below my blade file:
<main>
<section id="schedule" class="section-with-bg">
<ul class="nav nav-tabs" role="tablist" data-aos="fade-up" data-aos-delay="100">
#foreach($eye_issues as $issue)
#if($issue->body_part_id == 2 and $issue->gender_id == 1)
<li class="nav-item">
<a class="nav-link" href="#issue-{{ $issue->id }}" role="tab"
data-bs-toggle="tab">{{ $issue->issue }}</a>
</li>
#endif
#endforeach
</ul>
<div class="tab-content row justify-content-center" data-aos="fade-up" data-aos-delay="200">
#foreach($eye_issues as $issue)
#if($issue->body_part_id == 2 and $issue->gender_id == 1)
<div role="tabpanel" class="col-lg-9 tab-pane fade show active" id="issue-{{ $issue->id }}">
<div class="row schedule-item justify-content-center">
<div class="col-md-10" style=text-align:center>
<h4>{{ $issue->description }}</h4>
Test yourself
</div>
</div>
</div>
#endif
#endforeach
</div>
</div>
</section>
</main>
So problem is, after loading the page, navigation tabs should show all disease names (as it does) and the description section must be empty and show according description of disease that selected from nav-tabs and change description if disease is changed from nav-tabs. But after loading page, in the description section, there are all disease description, even nav-tabs selected to none onload. Only after selecting all diseases from nav-tabs, page works properly.
P.S I use MySQL if case u wanted to know. i tried to use all JS and CSS hide and show functions and other methods from internet, but no one works, and i guess it depends only on laravel it self. if you dont understand what i mean, comment it, i'll leave link for demo video of the issue
I need your help. Lets say I have array with 10 elements and every record to be shown on every iteration and I want to be done with Livewire, let me share with you some code and will tell you what I have tried till now.
public $content;
public $array = ['first', 'second', 'third' ,'fourth'];
foreach ($array as $item) {
sleep(1);
$this->content[] = "Element ${item}";
}
<div class="modal-body">
#if ($content)
<ul class="listree">
#foreach ($content as $element)
<li>
<div class="listree-submenu-heading">
{!! $element['title'] !!}
</div>
<ul class="listree-submenu-items">
#foreach ($element['elements'] as $sub)
<li>
<div class="listree-submenu-heading">
{!! $sub['title'] !!}
</div>
</li>
#endforeach
</ul>
</li>
#endforeach
</ul>
#endif
</div>
My idea is display first record, wait 1 second, display first and second record, wait 1 second, display first, second and third records and so on... How I can do this with livewire. The problem is that $content is filled with the information after all iteration and then the component is refreshed.
I tried on every iteration to send custom event which will call refresh method, but without succes. I will appreaciate any advice, and if you need more information, I will provide it.
Assumming you're also using alpinejs, this can be done pretty easily.
<x-app-layout>
<div class="text-gray-800 ml-10">
<ul class="bg-green-200">
<!-- The main foreach loop. -->
#foreach (range('a', 'z') as $element)
<!-- render al <li> tags with display:none. -->
<!-- Show the 1st after 0s, the 2nd after 1s, the 3rd after 2s, ... -->
<li class="bg-blue-200 m-5"
x-data="{show: false, index: {{ $loop->index }} }"
x-init="setTimeout(() => show = true, index * 1000)">
<div x-show="show">
{{ $element }}
...
</div>
</li>
#endforeach
</ul>
</div>
</x-app-layout>
$loop is a special object you can access within a #foreach block.
I have 2 nested loops in my laravel view
#foreach ($clubs as $club)
<div class="jumbotron text-center">
<h1>{{$club->nom}}</h1>
</div>
<div class="container">
<div class="row">
<div class="col-sm-12">
<h3>Grupos</h3>
#foreach ($grupos as $grupo)
#if ($grupo->club == $club->id)
<p>
<strong>Nombre: </strong> {{$grupo->nom}} <br>
<strong>Tipo: </strong> Grupo de {{$grupo->tipo}} <br>
<strong>Horario disponible: </strong> {{$grupo->dia}}, {{$grupo->horario}} <br>
</p>
#endif
#endforeach
</div>
</div>
</div>
#endforeach
$grupos is an array with all groups from my group table, I iterate through the whole thing and print the info only if the foreign key club is equal to the current club that is iterating at the moment. If there's none, no information will be printed, but I would like to print a message that indicates that nothing was printed during that iteration, is there any way I could do it?
This is an example of my desired output
Club A with id 1 has 5 groups
Club B with id 2 has 0 groups
------ CLUB A -------
Group 1
Group 2
Group 3
Group 4
Group 5
------- CLUB B -------
This club has no groups
You will need some relationships to achieve this. At this point, $grupos is the same for all the clubs. Here is how your minimum table structure should be:
clubs
id (BIGINT 20)
name (VARCHAR 255)
groups
id (BIGINT 20)
name (VARCHAR 255)
club_id (BIGINT 20)
Now you can set up your models:
Club.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Club extends Model
{
protected $table = 'clubs';
public function groups () {
return $this->hasMany(Group::class);
}
}
Group.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Group extends Model
{
protected $table = 'groups';
public function club () {
return $this->belongsTo(Club::class);
}
}
Now, in your controller where you load your view, you can get all your data and pass it through:
ClubController.php
<?php
namespace App\Http\Controllers;
use App\Club;
use Illuminate\Http\Request;
class ClubController extends Controller
{
public function index (Request $request) {
$clubs = Club::with('groups')->get();
return view('clubs', ['clubs' => $clubs]);
}
}
Now, display the clubs in your view:
clubs.blade.php
#foreach($clubs as $club)
<h1>Club: {{ $club->name }}</h1>
#if($club->groups)
<h2>Groups:</h2>
<ul>
#foreach($club->groups as $group)
<li>{{ $group->name }}</li>
#endforeach
</ul>
#else
<h2>This club has no groups.</h2>
#endif
<br>
#endforeach
I hope this helps you and gives you a better understanding on how to use relationships in Laravel :)
I am a little bit new with laravel 5.1 framework. Last couple of days I create my database (insert, update, delete) for dynamic menu I want to create. I connect with default layout in which i put menu. From route code looks like this.
View::composer('layouts.default',function($view){
$menus = Menu::where('parent_id',0)->orderBy('order')->get();
$submenus = Menu::where('parent_id','!=',0)->get();
$view->with(compact('menus','submenus'));
});
In main menu are items with parent_id = 0. Submenu items have parent_id = id, and soo on.
I want to display correct but when I hover main menu items that dont have items, css block appear, becouse i didnt make good if condition. Is there any way to do this?
Code in view look like this.
#foreach($menus as $menu)
<li class="dropdown {!! (Request::is('typography') || Request::is('advancedfeatures') || Request::is('grid') ? 'active' : '') !!}"> {!! $menu->title !!}
<ul class="dropdown-menu" role="menu">
#foreach($submenus as $submenu)
#if($submenu->parent_id === $menu->id)
<li>{!! $submenu->title !!}
#foreach($submenus as $smenu)
#if($smenu->parent_id === $submenu->id)
<ul class="dropdown-submenu" role="menu">
<li>{!! $smenu->title !!}
</li>
</ul>
#endif
#endforeach
</li>
#endif
#endforeach
</ul>
</li>
#endforeach
One more question is how to take only one value from Menu model for example id that can be used to point only one submenu.
Best regards!
You can do it simply by using recursion. I removed html classes for readability.
Note: Set NULL parent_id for root items.
Add this relation to your Menu Model.
function childs()
{
return $this->hasMany('Namespace\Menu','parent_id', 'id');
}
In your controller get the menus who has no parent.
$menus = Menu::whereNull('parent_id')->orderBy('order')->get();
Then display them in your view.
<ul>
#foreach($menus as $menu)
<li>
{!! $menu->title !!}
#include('childItems')//recursion view
</li>
#endforeach
</ul>
And this is what your childItems.blade.php will look like.
<ul>
#foreach($menu->childs as $menu)
<li>
{!! $menu->title !!}
#include('childItems')//call itself for deeper relations.
</li>
#endforeach
</ul>
That's it.
I have an array with 38 records.
After iterating over the first 10 I want it to start on a new column.
This is very simple and an example is below, however, I need to add in HTML which makes it difficult:
#for($i = 0; $i < count($records); $i++)
#if($i % 10 == 0)
//start new column
#endif
<li>{{ $records[$i]['name'] }}</li>
#endfor
What the HTML looks like without looping and what it should look like after looping properly:
<li class="col-sm-3">
<li class="dropdown-header">
Record Set
</li>
<li>Record Name</li>
<li>Record Name</li>
<li>Record Name</li>
</li>
Problem is, after 10 records I need it to break out of col-sm-3 and start a new col-sm-3 without the dropdown-header but with each iteration's record name.
How can this be done? Please ask questions if clarification is needed.
If it's an array then you may use array_chunk:
#foreach(array_chunk($records, 10) as $ten_arrays)
<li class="col-sm-3">
#foreach($ten_arrays as $record)
{{ $record['field_name'] }}
#endforeach
</li>
#endforeach
This will output lis like this:
<li class="col-sm-3">
<!-- Ten Items -->
</li>
<li class="col-sm-3">
<!-- Ten Items -->
</li>