Laravel: Add to favourites button is duplicating because of foreach loop - php

For a project, I've created a method where people can add products they want to buy to a wishlist. All items in the catalog are stored and each article has a hearticon that is clickable. Once it's clicked, it's added to my database.
However, when an article is added to favourites, the icon turns red but the original transparant icon is still there. So articles whom are added to favourites all have a filled and a transparant icon, which is not how it should be done.
Here is my code:
My View:
<div class="flex flex-col justify-evenly items-center lg:flex-row flex-wrap justify-between gap-y-20 gap-x-2 lg:p-20 lg:w-12/12">
#foreach ($articles as $article)
<div class="w-8/12 lg:w-3/12 flex flex-col justify-between xl:h-100">
<form action="{{route('wishlist.store', $article->id)}}" id="wish_form" method="post">
{{csrf_field()}}
<input name="user_id" type="hidden" value="{{Auth::user()->id}}" />
<input name="article_id" type="hidden" value="{{$article->id}}" />
<button type="submit" class=""><img src="{{ 'icons/0heart.png' }}" alt="" width="25" onclick="this.form.submit()" id="emptyHeart"></button>
#foreach ($wishlists as $wishlist)
#if ($wishlist->article_id === $article->id )
<button type="submit"><img src="{{ 'icons/1heart.png' }}" alt="" width="25" onclick="this.form.submit()" id="checked"></button>
#endif
#endforeach
</form>
<div class="h-2/3 xl:h-1/3 flex justify-center items-center">
{{-- <img src="{{$article->image}}" alt="" class="h-40"> --}}
</div>
<div class="h-20 mt-2">
<h4 class="text-md text-center flex"><strong>{{ $article->title }}</strong></h4>
</div>
<div class="flex flex-row flex-wrap justify-between items-center mt-4">
<p class="p-2">{{$article->prijs}}</p>
<p>Beschikbaar via {{$article->website->title}}</p>
</div>
</div>
#endforeach
</div>
My controller:
class FilterController extends Controller
{
public function catalogus(Request $r)
{
$articles = Article::all();
$categories = Category::all();
$websites = Website::all();
$wishlists = Wishlist::all()->where('user_id',auth()->user()->id);
$list = Wishlist::all()->where('article_id', $articles->id);
dd($list);
return view('catalogus', compact('articles', 'categories', 'websites', 'wishlists', 'list'));
}
}
My model:
class Wishlist extends Model
{
protected $table = "wishlists";
protected $fillable = [
'user_id',
'article_id',
'confirmed',
'available'
];
protected $casts = [
];
public function user()
{
return $this->belongsTo(User::class);
}
public function article()
{
return $this->belongsTo(Article::class);
}

You can use contains() collection method
<form action="{{route('wishlist.store', $article->id)}}" id="wish_form" method="post">
{{csrf_field()}}
<input name="user_id" type="hidden" value="{{Auth::user()->id}}"/>
<input name="article_id" type="hidden" value="{{$article->id}}"/>
#if ($wishlists->contains('article_id', $article->id))
<button type="submit">
<img src="{{ 'icons/1heart.png' }}" alt="" width="25"
onclick="this.form.submit()" id="checked">
</button>
#else
<button type="submit" class="">
<img src="{{ 'icons/0heart.png' }}" alt="" width="25"
onclick="this.form.submit()" id="emptyHeart" />
</button>
#endif
</form>

Related

Livewire retrieve Data from a relation manyToMany

in my blog project using livewire, i have a relationship manyToMany between tables posts & tags using a pivot table call post_tag
when i want to edit a post , in the modal i get all the data from posts table using -> wire:model.defer="post.body" ( we're using the Post model)
for the tags, i'm using a foreach to cycling through all the tags but how to get the tags associates to the post ?
Models
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $guarded = ['id', 'created_at', 'updated_at'];
public function user()
{
return $this->belongsTo(User::class);
}
public function category()
{
return $this->belongsTo(Category::class);
}
public function tags()
{
return $this->belongsToMany(Tag::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Tag extends Model
{
use HasFactory;
protected $guarded = ['id', 'created_at', 'updated_at'];
public function posts()
{
return $this->belongsToMany(Post::class);
}
}
Migration post_tag table
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('post_tag', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('post_id');
$table->unsignedBigInteger('tag_id');
$table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
$table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('post_tag');
}
};
class
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\Post;
use App\Models\Category;
use App\Models\Tag;
use Livewire\WithPagination;
use Livewire\WithFileUploads;
class EditHideForm extends Component
{
use WithPagination;
use WithFileUploads;
public $open = false;
public $post, $image, $identificador;
public $taggs;
protected $rules = [
'post.name' => 'required|max:100',
'post.slug' => 'required',
'post.body' => 'required',
'post.status' => 'required',
'post.user_id' => 'required',
'post.category_id' => 'required',
'post.image' => 'required',
'tagss' => 'required'
];
public function mount(Post $post)
{
$this->post = $post;
$this->tagss = $post->tags->toArray();
$this->identificador = rand();
}
public function save()
{
$this->validate();
$this->post->save();
/* codigo para borrar la foto Aqui */
$this->post->tags()->sync($this->tagss);
$this->reset(['open']);
$this->emitTo('show-post', 'render');
}
public function render()
{
$categories = Category::all();
$tags = Tag::all();
return view('livewire.edit-hide-form', compact('categories', 'tags'));
}
}
View
<div class="mb-2">
#auth
#if (auth()->user()->id === $post->user->id)
<x-jet-button wire:click="$set('open', true)">
Editar
</x-jet-button>
<x-jet-danger-button>
Eliminar
</x-jet-danger-button>
#endif
#endauth
</div>
<x-jet-dialog-modal wire:model="open" id="commentModal">
<x-slot name="title">
<h1 class="text-2xl mb-4">Edita tu post</h1>
</x-slot>
<x-slot name="content">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="container bg-white border-b border-gray-200 shadow-lg mx-auto justify-center px-4 py-2 ">
<section id="contact-us">
<div wire:loading wire:target='image'
class="bg-red-100 border border-red-400 text-xl font-normal max-w-full flex-initial">
<div class="py-2">
<p class="ml-2">Cargando la imagen</p>
<div class="text-sm font-base">
<p class="ml-2">Espero unos instantes mientras termine el proceso...</p>
</div>
</div>
</div>
#if ($image)
<img class="mb-4" src="{{ $image->temporaryUrl() }}" alt="">
#else
<img src="{{ Storage::url($post->image) }}" alt="">
#endif
<input class="hidden" wire:model="id_user" type="text" id="id" name="user_id" value={{
Auth::user()->id }}" />
<div>
<x-jet-label for="name" value="{{ __('Título') }}" />
<x-jet-input id="slug-source" class="block mt-1 mb-2 w-full" wire:model.defer="post.name"
type="text" name="name" required autofocus autocomplete="name" />
<x-jet-input-error for="name" />
<x-jet-label for="slug" value="{{ __('Slug') }}" />
<x-jet-input id="slug-target" class="block mt-1 w-full" wire:model.defer="post.slug"
type="text" name="slug" :value="old('slug')" required autofocus autocomplete="slug" />
<x-jet-input-error for="slug" />
</div>
<!-- body -->
<div>
<x-jet-label for="body" class="mt-4 text-base" value="{{ __('Contenido del post') }}" />
<textarea wire:model.defer="post.body" id="editor" rows="8" name="body"></textarea>
</div>
<x-jet-input-error for="body" />
<div class="mt-2 center justify-center mx-auto">
<!-- Image -->
<x-jet-label for="url" value="{{ __('Imagen') }}" />
<input type="file" id="image" name="image" class="mb-2" wire:model.defer="post.image" />
<x-jet-input-error for="image" />
</div>
<div>
<!-- Drop Down-->
<x-jet-label for="categories" value="{{ __('Categoría') }}" />
<select name="category_id" class="block font-medium text-sm text-gray-700" id="categories"
wire:model.defer="post.category_id">
<option selected disabled>opciones </option>
#foreach($categories as $category)
<option value="{{ $category->id }}">{{ $category->name }}</option>
#endforeach
</select>
</div>
<br>
<div>
<x-jet-label for="tags" value="{{ __('Etiquetas') }}" />
#foreach ($tags as $tag)
<label for="tagss"
class="relative flex-inline items-center isolate p-2 mr-4 mb-2 rounded-2xl">
<input wire:model.defer="tagss" value={{ $tag->id }} type="checkbox" class="relative
peer z-20 text-blue-600 rounded-md focus:ring-0" />
<span class="ml-1 relative z-20">{{ $tag->name }}</span>
</label>
#endforeach
</div>
<br>
<x-jet-label for="status" value="{{ __('Status') }}" />
<div class="flex">
<div class="inline-block rounded-lg">
Borrador <input type="radio" value=1 wire:model.defer="post.status" id="borrador" />
</div>
<div class="inline-block rounded-lg ml-4">
Publicado <input type="radio" value=2 wire:model.defer="post.status" name="publicado"
id="publicado" />
</div>
</div>
</section>
</div>
</div>
</x-slot>
<x-slot name='footer'>
<x-jet-secondary-button wire:click="$set('open', false)">
Cancelar
</x-jet-secondary-button>
<x-jet-danger-button wire:click="save">
Actualizar
</x-jet-danger-button>
</x-slot>
</x-jet-dialog-modal>
#push('js')
<script src="https://cdn.ckeditor.com/ckeditor5/34.0.0/classic/ckeditor.js"></script>
<script>
ClassicEditor
.create( document.querySelector( '#editor' ) )
.then(function(editor){
editor.model.document.on('change:data', () => {
#this.set('body', editor.getData());
})
})
.catch( error => {
console.error( error );
} );
</script>
#endpush
</div>
I would appreciate any help or advice, thanks
Charles, I wrote a POC (Proof of concept) for this problem and just found that it's related to a typo, haha.
You have the public property taggs and then you're assigning $this->tagss, that's why livewire wasn't rendering the checkboxes correctly.
I would recommend you to switch to a more verbose property like tagsSelected instead of taggs (or tagss).

Missing required parameters for [Route]

I have this issue:
Illuminate\Routing\Exceptions\UrlGenerationException
Missing required parameter for [Route: admin.percent.edit] [URI: {locale}/admin/percent/edit/{id}] [Missing parameter: id]. (View: C:\Users\kawed\OneDrive\Desktop\flooss\resources\views\admin\includes\top.blade.php)
index page code:
#extends('admin.layouts.app')
#section('headSection')
<!-- form Uploads -->
<link href="{{ asset('back/assets/plugins/datatable/dataTables.bootstrap4.min.css') }}" rel="stylesheet" type="text/css" />
#endsection
#section('content')
<div class="page-header mt-0 shadow p-3">
<ol class="breadcrumb mb-sm-0">
<li class="breadcrumb-item">
{{ __('val.home') }}
</li>
<li class="breadcrumb-item active" aria-current="page">
{{ __('val.dashboard_percent') }}
</li>
</ol>
<a href="/{{ app()->getLocale() }}/admin/percent/create">
<button type="button" class="btn btn-success btn-pill mt-1 mb-1">{{ __('val.create_percent') }}</button>
</a>
</div>
<div class="row">
<div class="col-md-12">
<div class="card shadow">
<div class="card-header">
<h2 class="mb-0">Data Table</h2>
</div>
<div class="card-body">
<div class="table-responsive">
<table id="example" class="table table-striped table-bordered w-100 text-nowrap">
<thead>
<tr>
<th class="wd-15p">id</th>
<th class="wd-15p">{{ __('session.percent') }}</th>
<th class="wd-20p">{{ __('session.edit') }}</th>
<th class="wd-15p">{{ __('session.delete') }}</th>
</tr>
</thead>
<tbody>
#foreach($percents as $item)
<tr>
<td>
{{ $item->id }}
</td>
<td>
{{ $item->pname }}
</td>
<td>
{{ __('session.edit') }}
</td>
<td>
{{ __('session.delete') }}
</td>
</tr>
#endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
#endsection
#section('footerSection')
<!-- file uploads js -->
<script src="{{ asset('back/assets/plugins/datatable/jquery.dataTables.min.js') }}"></script>
<script src="{{ asset('back/assets/plugins/datatable/dataTables.bootstrap4.min.js') }}"></script>
<script>
$(function(e) {
$('#example').DataTable();
var table = $('#example1').DataTable();
$('button').click(function() {
var data = table.$('input, select').serialize();
alert(
"The following data would have been submitted to the server: \n\n" +
data.substr(0, 120) + '...'
);
return false;
});
$('#example2').DataTable({
"scrollY": "200px",
"scrollCollapse": true,
"paging": false
});
});
</script>
#endsection
Edited page code:
#extends('admin.layouts.app')
#section('headSection')
<!-- form Uploads -->
<link href="{{ asset('back/assets/plugins/fileuploads/css/dropify.css') }}" rel="stylesheet" type="text/css" />
#endsection
#section('content')
<div class="page-header mt-0 shadow p-3">
<ol class="breadcrumb mb-sm-0">
<li class="breadcrumb-item">
{{ __('val.home') }}
</li>
<li class="breadcrumb-item active" aria-current="page">
{{ __('val.dashboard_percent') }}
</li>
</ol>
</div>
<div class="row">
<div class="col-md-12">
<form action="{{ route('admin.percent.edit', ['id' => $category->id, 'locale' => app()->getLocale()]) }}" method ="post" enctype="multipart/form-data">
{{ csrf_field() }}
<div class="card shadow">
<div class="card-header">
<h2 class="mb-0">{{ __('val.edit_percent') }}</h2>
#include('admin.includes.messages')
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<input type="text" class="form-control" name="categoryarabicname" value="{{ $category->categoryarabicname }}">
</div>
<div class="form-group">
<input type="text" class="form-control" name="categoryengname" value="{{ $category->categoryengname }}">
</div>
<div class="form-group">
<textarea class="form-control"name="categoryarabicdesc" id="exampleFormControlTextarea1" rows="3">{{ $category->categoryarabicdesc }}</textarea>
</div>
<div class="form-group">
<textarea class="form-control"name="categoryengdesc" id="exampleFormControlTextarea1" rows="3">{{ $category->categoryengdesc }}</textarea>
</div>
</div>
<div class="col-md-6">
<div class="card shadow">
<div class="card-header">
<h2 class="mb-0">Upload Image</h2>
</div>
<div class="card-body">
<input type="file" name="catimage" class="dropify" data-height="300" />
</div>
<input type="hidden" name="image2" class="form-control" id="exampleInputEmail1">
</div>
<div class="card shadow overflow-hidden">
<img alt="Image placeholder" width=250px height=250px class="big" src="/uploads/{{ $category->categoryimage }}">
</div>
</div>
<div class="col-lg-9"></div>
<div class="col-lg-3">
<button type="submit" class="btn btn-success btn-square mt-1 mb-1">Update</button>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
#endsection
#section('footerSection')
<!-- file uploads js -->
<script src="{{ asset('back/assets/plugins/fileuploads/js/dropify.min.js') }}"></script>
<script>
$('.dropify').dropify({
messages: {
'default': 'Drag and drop a file here or click',
'replace': 'Drag and drop or click to replace',
'remove': 'Remove',
'error': 'Ooops, something wrong appended.'
},
error: {
'fileSize': 'The file size is too big (2M max).'
}
});
</script>
#endsection
Controller code:
namespace App\Http\Controllers;
use App\Http\Requests\PercentEditRequest;
use App\Http\Requests\PercentRequest;
use App\Models\Percent;
use Illuminate\Http\Request;
class PercentController extends Controller
{
public function index()
{
$percents = Percent::orderBy('created_at', 'desc')->get();
return view('admin.percent.index', compact('percents'));
}
public function create()
{
return view('admin.percent.create');
}
public function store(PercentRequest $request)
{
$validated = $request->validated();
$category = new Percent();
$category->pname = strip_tags($request->pname);
$category->save();
return redirect()->route('admin.percent', ['locale' => app()->getLocale()])
->with('success', trans('session.success'));
}
public function edit(Request $request, $id) {
$id = $request->id;
$locale = $request->locale;
$category = Percent::find($id);
return view('admin/percent/edit', compact('category'));
}
public function update(PercentEditRequest $request, $id) {
$validated = $request->validated();
$category = Percent::find($id);
$category->categoryengname = strip_tags($request->categoryengname);
$category->categoryarabicname = strip_tags($request->categoryarabicname);
$category->categoryengdesc = strip_tags($request->categoryengdesc);
$category->categoryarabicdesc = strip_tags($request->categoryarabicdesc);
if (!empty($request->hasFile('catimage'))) {
$imagePath = $request->file('catimage');
$imageName = time() . '.' . $imagePath->getClientOriginalExtension();
$imagePath->move('uploads', $imageName);
$category->categoryimage= $imageName;
}
$category->save();
return redirect('/admin/percent')->with('success', 'percent Updated Successfuly');
}
public function destroy($id)
{
$category = Percent::find($id);
$category->delete();
return redirect('/admin/percent')->with('success','percent Deleted Successfuly');
}
}
you have 2 parameters in url as define (locale & id)
but in your function have only one id so add locale parameter
public function edit(Request $request, $locale, $id) {
or remove parameter from url and use it from request

Php search filter. Array returns NULL

This is Search Controller
if ($request->has('query')) {
$search = $request->get('query');
$search = addslashes(str_replace('"', '', json_encode($search)));
$solution = Service::all();
$solutions = array();
foreach ($solution as $id => $val) {
if (strpos(mb_strtolower($val['title']), mb_strtolower($search))) {
$solutions[] = $solution[$id];
}
}
}
When I run the dd command, 10 pieces of data appear.
For example when I search for 'customer' the array returns null even though this data is exist.
This is search.blade.php
<div class="header-search-form default-search">
<form action="{{ route('search') }}" method="GET" class="search-form-top">
<input class="search-field" type="text" name="query" id="query" value="{{ request()->input('query') }}" placeholder="{{ trans('general.search') }}">
<button class="search-submit">
<i class="search-btn-icon fa fa-search"></i>
</button>
</form>
</div>
This is search-result.blade.php
<div class="row row--35">
#foreach ($solutions as $solution)
<div class="col-lg-4 col-md-6 mt-10" >
<a href="{{route('service_detail',$solution->slug)}}" class="box-large-image__wrap wow move-up">
<div class="box-large-image__box">
<div class="box-large-image__midea">
<div class="images-midea">
<img src="{{ coverImg('service',$solution->id) }}" class="img-fluid" alt="">
<div class="button-wrapper">
<div class="btn tm-button">
<span class="button-text">Detayları Gör</span>
</div>
</div>
<div class="heading-wrap">
<h5 class="heading">{{ $solution->title }}</h5>
</div>
</div>
</div>
<div class="box-large-image__content mt-30 text-center"></div>
</div>
</a>
</div>
#endforeach
</div>

How can I get a single category of question in a quiz app using Laravel Eloquent

I want to select a single category of questions that the user can select with options. I have tried doing this with a resource I found online.
The category page:
#foreach($categories as $category)
<section>
<a href="#" class="image">
<img src="{{asset('images/pic09.jpg')}}" alt="" data-position="top center" />
</a>
<div class="content">
<div class="inner">
<header class="major">
<h3>{{$category->name}}</h3>
</header>
<p></p>
<ul class="actions">
<li>Learn more</li>
</ul>
</div>
</div>
</section>
#endforeach
Here is the TestController I'm using, the show controller is might to select questions and options with the category_id at random:
namespace App\Http\Controllers;
use App\Category;
use App\Http\Requests\StoreTestRequest;
use App\Option;
class TestsController extends Controller
{
public function show($id)
{
$categories = Category::find($id)->with(
['categoryQuestions' => function ($query) {
$query->inRandomOrder()
->with(
['questionOptions' => function ($query) {
$query->inRandomOrder();
}]
);
}]
)
->whereHas('categoryQuestions')
->get();
return view('client.test', compact('categories'));
}
public function store(StoreTestRequest $request)
{
$options = Option::find(array_values($request->input('questions')));
$result = auth()->user()->userResults()->create(
[
'total_points' => $options->sum('points')
]
);
$questions = $options->mapWithKeys(
function ($option) {
return [$option->question_id => [
'option_id' => $option->id,
'points' => $option->points
]
];
}
)->toArray();
$result->questions()->sync($questions);
return redirect()->route('client.results.show', $result->id);
}
}
web.php
// User
Route::group(['as' => 'client.', 'middleware' => ['auth']], function () {
Route::get('home', 'HomeController#redirect');
Route::get('dashboard', 'HomeController#index')->name('home');
Route::resource('/test', 'TestsController');
Route::get('results/{result_id}', 'ResultsController#show')->name('results.show');
Route::get('send/{result_id}', 'ResultsController#send')->name('results.send');
});
This is the Blade file from the resource I'm using:
#extends('layouts.home')
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Test</div>
<div class="card-body">
#if(session('status'))
<div class="row">
<div class="col-12">
<div class="alert alert-success" role="alert">
{{ session('status') }}
</div>
</div>
</div>
#endif
<form method="POST" action="{{ route('client.test.store') }}">
#csrf
#foreach($categories as $category)
<div class="card mb-3">
<div class="card-header">{{ $category->name }}</div>
<div class="card-body">
#foreach($category->categoryQuestions as $question)
<div class="card #if(!$loop->last)mb-3 #endif">
<div class="card-header">{{ $question->question_text }}</div>
<div class="card-body">
<input type="hidden" name="questions[{{ $question->id }}]" value="">
#foreach($question->questionOptions as $option)
<div class="form-check">
<input class="form-check-input" type="radio" name="questions[{{ $question->id }}]" id="option-{{ $option->id }}" value="{{ $option->id }}"#if(old("questions.$question->id") == $option->id) checked #endif>
<label class="form-check-label" for="option-{{ $option->id }}">
{{ $option->option_text }}
</label>
</div>
#endforeach
#if($errors->has("questions.$question->id"))
<span style="margin-top: .25rem; font-size: 80%; color: #e3342f;" role="alert">
<strong>{{ $errors->first("questions.$question->id") }}</strong>
</span>
#endif
</div>
</div>
#endforeach
</div>
</div>
#endforeach
<div class="form-group row mb-0">
<div class="col-md-6">
<button type="submit" class="btn btn-primary">
Submit
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
#endsection
How can the Testcontroller be made to select questions and answer from a single category and save the result from the user's answers?
public function index()
{
$questions = Category::select('categories.name', 'question_result.points')
->join('questions', 'categories.id', '=', 'questions.category_id')
->join('question_result', 'questions.id', '=', 'question_result.question_id')
->join('results', 'question_result.result_id', '=', 'results.id')
->where('results.user_id', auth()->id())
->get();
return view('client.home', compact('questions'));
}

Laravel - Data not pulling through to form

I have a create form for creating courses, I have assigned users to these courses however for some reason it is not working anymore. I have been through my code umpteen times and I can't find anything that has changed - so i have come here for help.
To give some context below is my index.blade.php. As you can see I have previously assigned users to a course.
Create.blade.php;
#extends('layouts.app')
#section('content')
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Create Course</div>
<div class="card-body">
<form method="POST" action="{{ route('admin.courses.store') }}" enctype="multipart/form-data">
#csrf
<div class="form-group">
<label class="required" for="name">Course Title</label>
<input class="form-control" type="text" name="title" id="id" value="{{ old('title', '') }}" required>
#if($errors->has('name'))
<div class="invalid-feedback">
{{ $errors->first('name') }}
</div>
#endif
</div>
<div class="form-group">
#can('create_courses')
{!! Form::label('Instructor', 'Instructor', ['class' => 'control-label']) !!}
{!! Form::select('Instructor[]', $instructors, Request::get('Instructor'), ['class' => 'form-control select2', 'multiple' => 'multiple']) !!}
#if($errors->has('Instructor'))
{{ $errors->first('Instructor') }}
#endif
#endcan
</div>
<div class="form-group">
<button class="btn btn-danger" type="submit">
Save
</button>
</div>
</div>
</form>
</div>
</div>
#endsection
Index.blade.php;
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-10">
<p>
#can('create_courses')
<button type="button" class="btn btn-success">Create Course</button>
#endcan('create_courses')
</p>
<div class="card">
<div class="card-header">Courses</div>
<div class="card-body">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Course Title</th>
<th>Instructor</th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
#foreach($course as $course)
<tr>
<th scope="row">{{ $course->id }}</th>
<td>{{ $course->title}}</td>
<td>{{ implode (', ', $course->instructors()->pluck('name')->toArray()) }}</td>
<td>
#can('edit_courses')
<a class="btn btn-xs btn-secondary" href="{{ route('admin.modules.index', $course->id) }}">
Modules
</a>
#endcan
</td>
<td>
#can('edit_courses')
<a class="btn btn-xs btn-primary" href="{{ route('admin.courses.edit', $course->id) }}">
Edit
</a>
#endcan
</td>
<td>
#can('delete_courses')
<form action="{{ route('admin.courses.destroy', $course->id) }}" method="POST" onsubmit="return confirm('Confirm delete?');" style="display: inline-block;">
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="submit" class="btn btn-xs btn-danger" value="Delete">
</form>
#endcan
</td>
</tr>
#endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- <div class="col-md-2 col-lg-2">
<div class="list-unstyled">
Courses
Modules
</div>
</div> -->
</div>
</div>
#endsection
CoursesController.php;
<?php
namespace App\Http\Controllers\Admin;
use Gate;
use App\User;
use App\Course;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Input;
class CoursesController extends Controller
{
public function __construct()
{
//calling auth middleware to check whether user is logged in, if no logged in user they will be redirected to login page
$this->middleware('auth');
}
public function index()
{
if(Gate::denies('manage_courses')){
return redirect(route('home'));
}
$courses = Course::all();
return view('admin.course.index')->with('course', $courses); //pass data down to view
}
public function create()
{
if(Gate::denies('create_courses')){
return redirect(route('home'));
}
$instructors = User::whereHas('role', function ($query) {
$query->where('role_id', 2); })->get()->pluck('name'); //defining instructor variable to call in create.blade.php. Followed by specifying that only users with role_id:2 can be viewed in the select form by looping through the pivot table to check each role_id
return view('admin.course.create', compact('instructors')); //passing instructor to view
}
public function store(Request $request)
{
$course = Course::create($request->all()); //request all the data fields to store in DB
$course->instructors()->sync($request->input('instructors', [])); //input method retrieves all of the input values as an array
if($course->save()){
$request->session()->flash('success', 'The course ' . $course->title . ' has been created successfully.');
}else{
$request->session()->flash('error', 'There was an error creating the course');
}
return redirect()->route ('admin.courses.index');
}
public function destroy(Course $course)
{
if(Gate::denies('delete_courses'))
{
return redirect (route('admin.course.index'));
}
$course->delete();
return redirect()->route('admin.courses.index');
}
public function edit(Course $course)
{
if(Gate::denies('edit_courses'))
{
return redirect (route('admin.courses.index'));
}
$instructors = User::whereHas('role', function ($query) {
$query->where('role_id', 2); })->get()->pluck('name');
return view('admin.course.edit')->with([
'course' => $course
]);
}
public function update(Request $request, Course $course)
{
$course->update($request->all());
if ($course->save()){
$request->session()->flash('success', $course->title . ' has been updated successfully.');
}else{
$request->session()->flash('error', 'There was an error updating ' . $course->title);
}
return redirect()->route('admin.courses.index');
}
public function show(Course $course)
{
return view('admin.course.show', compact('course'));
}
}
I am new to laravel so I would appreciate any help.

Categories