Is it true, in terms of architecture I did?
I'm not sure if I can use model access in section view.
Do you need to change something.
<!-- Navigation Links -->
<x-section :sectionNumber="1"></x-section>
section.blade.php
#php
$sections = \App\Models\BasicSection::all()->where('section_number', '=', $sectionNumber);
#endphp
<div class="hidden sm:flex sm:items-center sm:ml-10">
<x-dropdown :href="route('dashboard')" :active="request()->routeIs('dashboard')">
<x-slot name="trigger">
<button
class="flex items-center text-sm font-medium text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-300 transition duration-150 ease-in-out">
{{ __($sectionNumber) }}
<div class="ml-1">
<svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20">
<path fill-rule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clip-rule="evenodd"/>
</svg>
</div>
</button>
</x-slot>
<x-slot name="content">
#foreach($sections as $section)
<x-dropdown-link :href="route('dashboard')">
{{ $section->name }}
</x-dropdown-link>
#endforeach
</x-slot>
</x-dropdown>
</div>
I have a component using Laravel livewire which disappear after I submit the form inside of it.
Here is the blade content:
<div class="w-full flex flex-col justify-start items-start px-5 wow delay-100 fadeInUp">
<h3 class="w-full flex flex-row justif-start items-center text-center text-2xl font-medium text-gray-700 mt-5 mb-0">
{{ $survey->name }}
</h3>
<div class="w-full mt-5">
<div class="prose w-full max-w-full">
{!! $survey->description !!}
</div>
</div>
<form wire:submit.prevent="submit" class="w-full mt-10">
#foreach($survey->fields as $field)
<div class="w-full flex flex-col justify-start items-start gap-2 mb-10" wire:key="field{{ $field->id }}">
<span class="font-medium" #class([
'text-gray-700',
'text-danger-700' => $errors_list && $errors_list->has($field->slug)
])>
{{ $field->name }}
#if($field->is_required)
<sup class="font-medium text-danger-700">*</sup>
#endif
</span>
<div class="prose w-full max-w-full">
{!! $field->description !!}
</div>
<div class="w-full">
#switch($field->type)
#case('text')
<div class="w-full flex flex-row justify-start items-center gap-2">
{{ html()->text($field->slug)->class($field_class)->attribute('wire:model.defer', 'model.' . $field->slug) }}
</div>
#break;
#case('textarea')
<div class="w-full flex flex-row justify-start items-center gap-2">
{{ html()->textarea($field->slug)->class($field_class)->attribute('wire:model.defer', 'model.' . $field->slug) }}
</div>
#break;
#case('select')
<div class="w-full flex flex-row justify-start items-center gap-2">
{{ html()->select($field->slug, explode(',', $field->values))->class($field_class)->attribute('wire:model.defer', 'model.' . $field->slug) }}
</div>
#break;
#case('multiselect')
<div class="w-full flex flex-row justify-start items-center gap-2">
{{ html()->multiselect($field->slug, explode(',', $field->values))->class($field_class)->attribute('wire:model.defer', 'model.' . $field->slug) }}
</div>
#break;
#case('file')
<div class="w-full flex flex-row justify-start items-center gap-2">
{{ html()->file($field->slug) }}
</div>
#break;
#case('checkbox')
#foreach(explode(',', $field->values) as $value)
<div class="w-full flex flex-row justify-start items-center gap-2" wire:key="{{ $field->slug . '_' . $value }}">
{{ html()->checkbox($field->slug, false, $value)->id($field->slug . '_' . $value)->attribute('wire:model.defer', 'model.' . $field->slug) }}
{{ html()->label($value, $field->slug . '_' . $loop->index)->class('p-0') }}
</div>
#endforeach
#break;
#case('radio')
#foreach(explode(',', $field->values) as $value)
<div class="w-full flex flex-row justify-start items-center gap-2" wire:key="{{ $field->slug . '_' . $value }}">
{{ html()->radio($field->slug, false, $value)->id($field->slug . '_' . $value)->attribute('wire:model.defer', 'model.' . $field->slug) }}
{{ html()->label($value, $field->slug . '_' . $loop->index)->class('p-0') }}
</div>
#endforeach
#break;
#case('date')
<div class="w-full flex flex-row justify-start items-center gap-2">
{{ html()->date($field->slug, null, __('Y-m-d'))->class($field_class)->attribute('wire:model.defer', 'model.' . $field->slug) }}
</div>
#break;
#case('datetime')
<div class="w-full flex flex-row justify-start items-center gap-2">
{{ html()->datetime($field->slug, null, __('Y-m-d g:i A'))->class($field_class)->attribute('wire:model.defer', 'model.' . $field->slug) }}
</div>
#break;
#case('time')
<div class="w-full flex flex-row justify-start items-center gap-2">
{{ html()->time($field->slug, null, __('g:i A'))->class($field_class)->attribute('wire:model.defer', 'model.' . $field->slug) }}
</div>
#break;
#endswitch
</div>
</div>
#endforeach
<div class="w-full flex flex-row justify-start items-center gap-2">
<button type="submit" class="px-3 py-1 text-white bg-fprimary hover:text-fprimary hover:bg-white border border-fprimary rounded">
{{ __('Submit') }}
</button>
</div>
</form>
</div>
And the submit function, is only checking the errors:
protected function rules(): array
{
return $this->survey->form_rules;
}
public function submit()
{
$this->validate();
}
All works well before the line $this->validate(), after I call this function the component disappear from the rendered view.
But if the form is valid and no errors are fired when form is validated, all works well.
FYI, I am rendering the livewire component in a blade page:
<livewire:survey :survey="$survey"></livewire:survey>
I know this issue is already discussed in other questions, but I tried all the solutions without getting it work.
I found the solution which is simply to remove the <div> element that contains all the other elements and leave the <form> element as the root.
So now I have the following code in my blade file:
<form wire:submit.prevent="submit" class="w-full mt-10 w-full flex flex-col justify-start items-start">
<h3 class="w-full flex flex-row justif-start items-center text-center text-2xl font-medium text-gray-700 mt-5 mb-0">
{{ $survey->name }}
</h3>
<div class="w-full mt-5 mb-10">
<div class="prose w-full max-w-full">
{!! $survey->description !!}
</div>
</div>
#foreach($survey->fields as $field)
<div class="w-full flex flex-col justify-start items-start gap-2 mb-10" wire:key="field{{ $field->id }}">
<span class="font-medium #if($errors->has('model.' . $field->slug)) text-danger-700 #else text-gray-700 #endif">
{{ $field->name }}
#if($field->is_required)
<sup class="font-medium text-danger-700">*</sup>
#endif
</span>
<div class="prose w-full max-w-full">
{!! $field->description !!}
</div>
<div class="w-full">
#switch($field->type)
#case('text')
<div class="w-full flex flex-row justify-start items-center gap-2">
{{ html()->text($field->slug)->class($field_class)->attribute('wire:model.defer', 'model.' . $field->slug) }}
</div>
#break;
#case('textarea')
<div class="w-full flex flex-row justify-start items-center gap-2">
{{ html()->textarea($field->slug)->class($field_class)->attribute('wire:model.defer', 'model.' . $field->slug) }}
</div>
#break;
#case('select')
<div class="w-full flex flex-row justify-start items-center gap-2">
{{ html()->select($field->slug, explode(',', $field->values))->class($field_class)->attribute('wire:model.defer', 'model.' . $field->slug) }}
</div>
#break;
#case('multiselect')
<div class="w-full flex flex-row justify-start items-center gap-2">
{{ html()->multiselect($field->slug, explode(',', $field->values))->class($field_class)->attribute('wire:model.defer', 'model.' . $field->slug) }}
</div>
#break;
#case('file')
<div class="w-full flex flex-row justify-start items-center gap-2">
{{ html()->file($field->slug) }}
</div>
#break;
#case('checkbox')
#foreach(explode(',', $field->values) as $value)
<div class="w-full flex flex-row justify-start items-center gap-2" wire:key="{{ $field->slug . '_' . $value }}">
{{ html()->checkbox($field->slug, false, $value)->id($field->slug . '_' . $value)->attribute('wire:model.defer', 'model.' . $field->slug) }}
{{ html()->label($value, $field->slug . '_' . $loop->index)->class('p-0') }}
</div>
#endforeach
#break;
#case('radio')
#foreach(explode(',', $field->values) as $value)
<div class="w-full flex flex-row justify-start items-center gap-2" wire:key="{{ $field->slug . '_' . $value }}">
{{ html()->radio($field->slug, false, $value)->id($field->slug . '_' . $value)->attribute('wire:model.defer', 'model.' . $field->slug) }}
{{ html()->label($value, $field->slug . '_' . $loop->index)->class('p-0') }}
</div>
#endforeach
#break;
#case('date')
<div class="w-full flex flex-row justify-start items-center gap-2">
{{ html()->date($field->slug, null, __('Y-m-d'))->class($field_class)->attribute('wire:model.defer', 'model.' . $field->slug) }}
</div>
#break;
#case('datetime')
<div class="w-full flex flex-row justify-start items-center gap-2">
{{ html()->datetime($field->slug, null, __('Y-m-d g:i A'))->class($field_class)->attribute('wire:model.defer', 'model.' . $field->slug) }}
</div>
#break;
#case('time')
<div class="w-full flex flex-row justify-start items-center gap-2">
{{ html()->time($field->slug, null, __('g:i A'))->class($field_class)->attribute('wire:model.defer', 'model.' . $field->slug) }}
</div>
#break;
#endswitch
</div>
#error('model.' . $field->slug)
<span class="text-sm font-medium text-danger-700">{{ $message }}</span>
#enderror
</div>
#endforeach
<div class="w-full flex flex-row justify-start items-center gap-2">
<button type="submit" class="px-3 py-1 text-white bg-fprimary hover:text-fprimary hover:bg-white border border-fprimary rounded">
{{ __('Submit') }}
</button>
</div>
</form>
If anyone can give me some information about why this change made it works it will be great, because I don't understand why having a <div> element as root element didn't work, and <form> works.
FYI, I have other pages containing <div> root element and all is working just fine.
I've built a nested comment system and it works fine, but I have a problem.
when I want to show the comments, it runs too many queries. for example if I have 10 comments and two replies each, laravel debugger shows 40+ queries, and I want to reduce them, here is my code :
Query
$comments = $post->mentions()->with(['author', 'reply'])->get();
Relationship in Post.php Model
public function mentions()
{
return $this->hasMany(Comment::class, 'post_id')->where('approved',1)->where('parent_id',0);
}
Comments Relationships
public function author()
{
return $this->belongsTo(User::class, 'author_id')->select('id', 'name', 'avatar', 'role');
}
public function reply()
{
return $this->hasMany(Comment::class, 'parent_id')->where('approved', 1);
}
Blade File
#foreach ($comments as $comment)
<div x-data="{reply:false}" class="break-words bg-white border-2 rounded-lg p-4 my-5" id="answer-{1}">
<div wire:ignore class="flex justify-between items-center">
<div class="flex items-center">
<img class="rounded-full w-20 border-4 #if ($comment->author->role == 'administrator') border-blue-500 #else border-gray-500 #endif " src="{{ $comment->author->avatar }}"
alt="{{ $comment->author->name }}">
<div>
<div class="flex pr-3">
<a href="/#username"
class="font-bold text-lg text-gray-800 hover:text-gray-900">{{ $comment->author->name }}</a>
#if ($comment->author->role == 'administrator')
<img class="w-5 mr-1" src="/img/verified.svg" alt="" title="admin">
#endif
</div>
<p class="font-light cursor-default text-gray-700 pt-1 pr-3">
{{ $comment->created_at->diffForHumans() }}</p>
</div>
</div>
<svg #click="reply = true" xmlns="http://www.w3.org/2000/svg" class="h-6 cursor-pointer hover:text-rose-600"
fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" />
</svg>
</div>
<div class="comment_body leading-8 pt-3 text-gray-800 cursor-default">
<div wire:ignore>
{!! nl2br($comment->body) !!}
</div>
<div x-cloak x-show="reply">
<form class="py-3" wire:submit.prevent="SubmitComment({{ $comment->id }})">
<textarea wire:model.defer="commentBody"
class="w-full focus:ring-0 bg-zinc-200 border shadow focus:bg-zinc-100 mt-3 p-4 rounded-lg"
id="editor" rows="6" placeholder=""></textarea>
#error('commentBody') <p class="text-red-600 mt-1 text-sm">{{ $message }}</p>
#enderror
<div class="flex mt-3">
<div #click="reply = false"
class="bg-red-600 rounded-lg ml-3 text-white px-3 py-2 cursor-pointer">
Cancel
</div>
<button wire:loading.remove wire:target="SubmitComment" type="submit"
class="inline-block bg-gray-800 hover:bg-gray-900 transition duration-300 px-3 py-2 text-white rounded-md">
Send
</button>
<button wire:loading="" wire:target="SubmitComment" type="button"
class="flex bg-gray-800 hover:bg-gray-900 transition duration-300 px-3 py-2 text-white rounded-md"
disabled>
<span class="flex justify-center">
<svg class="animate-spin w-6 h-6" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor"
stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z">
</path>
</svg>
</span>
</button>
</div>
</form>
</div>
<div class="my-3">
#include('partials.comment',['comments'=>$comment->reply])
</div>
</div>
</div>
#endforeach
You can use dot seperator to get the nested relationship
$comments = $post->with(['mentions.author','mentions.reply'])
->first()
->mentions;
Weird issue with my Livewire: the validation, when I send a file, always fails on the first time. If I have the criteria that it must be a pdf, I will put the PDF, submit the form, get a message telling me I have the wrong format, I won't change anything, resubmit and it will go through with no issue.
Does anyone knows why it might be happening?
<?php
namespace App\Http\Livewire\Branch\Documents;
use App\Models\BranchDocument;
use Livewire\Component;
use Livewire\WithFileUploads;
class Upload extends Component
{
use WithFileUploads;
public BranchDocument $document;
public $file;
public $saved = false;
public function render()
{
return view('livewire.branch.documents.upload');
}
public function save() {
$this->validate([
'file' => 'mimes:jpg,bmp,png,pdf|max:10240', // 1MB Max
]);
$this->document->file = $this->file;
$this->saved = true;
}
}
<div x-data="{ open: false }">
<li class="#if(!$saved) hover:bg-gray-100 py-2 px-2 rounded cursor-pointer #endif" #click="open = true">
<div class="relative">
<div class="relative flex space-x-3">
<div class="min-w-0 flex-1 flex justify-between space-x-4 items-center">
<div>
<p class="text-sm text-porange">{{ $document->document_type->title }}#if($saved)<span class="text-sm text-gray-600"> - {{ __('Document sent!') }}</span>#endif</p>
<p class="text-xs text-gray-600">{{ $document->created_at->diffForHumans() }}</p>
</div>
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-600" fill="none" viewBox="0 0 24 24" stroke="currentColor" >
#if(!$saved)
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" />
#else
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
#endif
</svg>
</div>
</div>
</div>
</li>
#if(!$saved)
<div x-show="open" class="fixed z-10 inset-0 overflow-y-auto" aria-labelledby="modal-title" role="dialog" aria-modal="true">
<div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<!--
Background overlay, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0"
To: "opacity-100"
Leaving: "ease-in duration-200"
From: "opacity-100"
To: "opacity-0"
-->
<div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>
<!-- This element is to trick the browser into centering the modal contents. -->
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true"></span>
<!--
Modal panel, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
To: "opacity-100 translate-y-0 sm:scale-100"
Leaving: "ease-in duration-200"
From: "opacity-100 translate-y-0 sm:scale-100"
To: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
-->
<div #click.away="open = false" class="inline-block align-bottom bg-white rounded-lg px-4 py-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full sm:p-6">
<div>
<div class="text-center">
<h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">
{{ __('Upload ":title"', ['title' => $document->document_type->title])}}
</h3>
</div>
</div>
<form wire:submit.prevent="save">
<input type="file" wire:model="file" class="file-input-business block mx-auto mt-4"/>
#error('file') <span class="error">{{ $message }}</span> #enderror
<div class="mt-5 sm:mt-6 sm:grid sm:grid-cols-2 sm:gap-3 sm:grid-flow-row-dense">
<button type="submit" type="button" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-porange text-base font-medium text-white hover:bg-porange-darker focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-porange sm:col-start-2 sm:text-sm">
{{ __('Send')}}
</button>
<button #click="open = false" type="button" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-porange sm:mt-0 sm:col-start-1 sm:text-sm">
{{ __('Cancel')}}
</button>
</div>
</form>
</div>
</div>
</div>
#endif
</div>
Thank you!
Is the file uploaded before you hit submit? If not then the file is null hence the wrong format error. Check its value in the save method before validation. You can also use wire.loading on a div to determine if the file is still uploading.
You may also run into issues with built in artisan development server (the one you start with php artisan serve command). It has different limitations to a 'real' server - upload file size, formats, etc.
im doing the Laravel 8 from Scratch Tutorial but get the Error "Syntax error, unexpected 'endif' (T_ENDIF)".
Cant find where the problem is because there is not even a "#if" statement in the file which is throwing the error.
The file is the header for filtering posts.
It seems the dropdown component which is responsible for selecting a post category is the reason for the problem, because everything workes fine when i comment this out.
I have shared the Error Code on flareapp.io
Dropdown Component:
#props(['trigger'])
<div x-data="{ show:false }" #click.away="show = false">
<div #click="show = ! show">
{{ $trigger }}
</div>
<div x-show="show" class="py-2 absolute bg-gray-100 mt-2 rounded-xl w-32 z-50" style="display: none">
{{ $slot }}
</div>
</div>
Dropdown-item Component:
#props(['active' => false])
#php
$classes = 'block text-left px-3 text-sm loading-6 hover:bg-blue-500 focues:bg-blue-500 hover:text-white focus:text-white';
if ($active) {
$classes += 'bg-blue-500 text-white';
}
#endphp
<a {{ $attributes(['class' => $classes]) }}>
{{ $slot }}
</a>
Posts header:
<header class="max-w-xl mx-auto mt-20 text-center">
<h1 class="text-4xl">
Latest <span class="text-blue-500">Laravel From Scratch</span> News
</h1>
<h2 class="inline-flex mt-2">By Lary Laracore <img src="./images/lary-head.svg" alt="Head of Lary the mascot"></h2>
<p class="text-sm mt-14">
Another year. Another update. We're refreshing the popular Laravel series with new content.
I'm going to keep you guys up to speed with what's going on!
</p>
<div class="space-y-2 lg:space-y-0 lg:space-x-4 mt-8">
<!-- Category -->
<div class="relative lg:inline-flex bg-gray-100 rounded-xl">
<x-dropdown>
<x-slot name="trigger">
<button class="py-2 pl-3 pr-9 text-sm font-semibold w-full lg:w-32 text-left flex lg:inline-flex">
{{ isset($currentCategory) ? ucwords($currentCategory->name) : 'Categories' }}
<svg class="transform -rotate-90 absolute pointer-events-none" style="right: 12px;" width="22"
height="22" viewBox="0 0 22 22">
<g fill="none" fill-rule="evenodd">
<path stroke="#000" stroke-opacity=".012" stroke-width=".5" d="M21 1v20.16H.84V1z">
</path>
<path fill="#222"
d="M13.854 7.224l-3.847 3.856 3.847 3.856-1.184 1.184-5.04-5.04 5.04-5.04z"></path>
</g>
</svg>
</button>
</x-slot>
<x-dropdown-item href="/blog/" :active="request()->routeIs(" none")">
All
</x-dropdown-item>
#foreach ($categories as $category)
<x-dropdown-item href="/blog/categories/{{ $category->slug }}" :active="request()->is("
categories/{$category->slug}")"
>
{{ ucwords($category->name) }}
</x-dropdown-item>
#endforeach
</x-dropdown>
</div>
<!-- Other Filters -->
<div class="relative flex lg:inline-flex items-center bg-gray-100 rounded-xl">
<select class="flex-1 appearance-none bg-transparent py-2 pl-3 pr-9 text-sm font-semibold">
<option value="category" disabled selected>Other Filters
</option>
<option value="foo">Foo
</option>
<option value="bar">Bar
</option>
</select>
{{-- ERROR THROWN IN NEXT LINE --}}
<svg class="transform -rotate-90 absolute pointer-events-none" style="right: 12px;" width="22" height="22"
viewBox="0 0 22 22">
<g fill="none" fill-rule="evenodd">
<path stroke="#000" stroke-opacity=".012" stroke-width=".5" d="M21 1v20.16H.84V1z">
</path>
<path fill="#222" d="M13.854 7.224l-3.847 3.856 3.847 3.856-1.184 1.184-5.04-5.04 5.04-5.04z">
</path>
</g>
</svg>
</div>
<!-- Search -->
<div class="relative flex lg:inline-flex items-center bg-gray-100 rounded-xl px-3 py-2">
<form method="GET" action="#">
<input type="text" name="search" placeholder="Find something"
class="bg-transparent placeholder-black font-semibold text-sm">
</form>
</div>
</div>
</header>
Try this
#foreach ($categories as $category)
<x-dropdown-item href="/blog/categories/{{ $category->slug }}" :active="request()->is('categories/' . $category->slug)">
{{ ucwords($category->name) }}
</x-dropdown-item>
#endforeach