Nested replies almost done, only need to arrange them in view - laravel

I'm currently doing a small forum in Laravel. This will include(ofcourse) commenting on posts. I also done replies on top of comments. I've done this by adding post_id, commenter_id and parent_id field in Comment model. And that's all alright.And i also done small margin that each reply have depending on their parent .What i have trouble with is displaying appropriate reply, for example: Comment1, then reply to comm.1, then another reply to that reply and so on, then another direct reply on Comment1, every subsequent reply to reply after second direct comment on Comment1 isn't grouped with other replies. How to achieve that?
Here is image of what i'm trying to achieve:
Here is Comment model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Post;
use App\User;
class Comment extends Model
{
protected $fillable = [
'user_id',
'post_id',
'parent_id',
'body'
];
public function commentPost(){
return $this->belongsTo("App\Post","post_id");
}
public function commentAuthor(){
return $this->belongsTo("App\User","commenter_id");
}
public function replies() {
return $this->hasMany('App\Comment', 'parent_id');
}
}
Here is show view:
#extends("layouts.app")
#section("content")
<?php
/*Pregleda zasebno za title i description da li ima gresaka.
Ukoliko ih ima, dodeljume im klasu(crveni border).*/
$errBody = $errors->has('body') ? 'shake' : '';
?>
Go Back
<div style="float:right;">
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-right"></i>
</div>
<h1>{{$post->title}}</h1>
<div class="postContainer">
<img class="postCover" src="/storage/cover_images/{{$post->cover_image}}">
<div>
<!--Ovako prikazuje html kod.-->
<!--{{$post->body}}-->
{!!$post->body!!}
</div>
<small class="timestamp">Written on {{$post->created_at}}</small>
</div>
#if(!Auth::guest())
#if(Auth::check() && Auth::user()->role_id<3 && Auth::user()->role_id>0)
<hr>
Edit
<form action="/posts/{{$post->id}}" method="post" class="float-right">
#csrf
{{method_field("DELETE")}}
<!-- The Modal -->
<div class="modal" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title">Are yoy sure you want to delete this post?</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<!-- Modal body -->
<div class="modal-body">
<button type="submit" class="btn btn-outline-danger btn-sm">Delete</button>
</div>
<!-- Modal footer -->
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</form>
<button class="btn btn-outline-danger btn-sm float-right" data-toggle="modal" data-target="#myModal">Delete</button>
#endif
#endif
#auth
<hr>
#if(Auth::check() && Auth::user()->role_id<3 && Auth::user()->role_id>0)
<form method="POST" action="/posts/{{$post->id}}/comments">
#csrf
<!-- https://laravel.com/docs/5.7/validation#available-validation-rules -->
<div class="form-group animated {{$errBody}}">
<textarea id="ckeditor" class="form-control" name="body" placeholder="Post body" required value=""></textarea>
</div>
<div>
<button type="submit" class="btn btn-outline-success btn-sm">Post comment</button>
</div>
</form>
#endif
<hr>
#endauth
<h6 style="border-bottom: 1px solid whitesmoke;">Comments <span class="badge" style="background-color: whitesmoke; border: 1px solid silver;vertical-align: top;">{{count($comments)}}</span></h6>
<div class="container commContainer">
<ul class="list-group" style="list-style-type:none">
#if(count($comments) > 0)
#foreach ($comments as $index => $comment)
<li>
#if($index>0)
<div class="horDiv"></div>
#endif
{{$comment->commentAuthor->name}} has said parent_id: {{$comment->parent_id}}
</li>
<li class="list-group-item py-2 commBody" style="margin-left: calc({{$comment->parent_id}}*10px) !important" parent_id="{{$comment->parent_id}}" id="{{$comment->id}}">My id: {{$comment->id}} {!!$comment->body!!}
#if(Auth::check() && Auth::user()->role_id<3 && Auth::user()->role_id>0)
<br><span class="btn btn-outline-primary btn-sm" style="width: 40px;height: 20px;line-height: 5px;padding: 5px;" onclick="reply('reply{{ $comment->id }}')";>reply</span>
#include('inc.replyForm')
#endif
</li>
#endforeach
#endif
</ul>
</div>
#endsection
I'm just guessing, but can it be done by in view itself?I tried grouping and ordering before controller passes it to view, but nothing had desired effect. I appreciate every point in right direction.
Edit:
Here is store method in CommentsController.
public function store(Request $request, $id)
{
$this->validate($request, [
"body" => "required"
]);
$data = array(
"body" => $request->input("body"),
"post_id" => intval($id),
"commenter_id" => Auth::user()->id,
"imParent_id" => $request->input("comment_id")
);
//dd($data);
$comment = new Comment;
$comment->body = $data["body"];
$comment->post_id = $data["post_id"];
$comment->commenter_id = $data["commenter_id"];
$comment->parent_id = $data["imParent_id"];
$comment->save();
$post = Post::find($id);
$comments = $post->comments;
//return redirect("/posts/{{$id}}")->with("success", "Post Created")->with('comments', $comments);
//return view("posts.show")->with(compact('post', 'comments'));
//with(['replies' => function($comments){ $comments->orderBy('parent_id') } ])
return back()->with('comments', $comments);
}
Edit2:
And here is show method in PostController:
public function show($id)
{
$post = Post::find($id);
$comments = $post->comments;
$prev = $post->prev($post);
$next = $post->next($post);
return view("posts.show")->with(compact("post", "prev", "next", "comments"));
}
Edit3:
Here is rather flawed attempt(in show view):
#if(count($comments) > 0)
#for($i=0;$i<count($comments);$i++)
#if(!$comments[$i]->parent_id)
<li class="list-group-item py-2 commBody" parent_id="{{$comments[$i]->parent_id}}" id="{{$comments[$i]->id}}">
{!!$comments[$i]->body!!}
</li>
#for($k=0;$k<count($comments);$k++)
#if($comments[$i]->id==$comments[$k]->parent_id)
<?php array_push($myArray,$comments[$i]->id); ?>
<li class="list-group-item py-2 commBody" style="margin-left: calc({{$comments[$k]->parent_id}}*10px) !important" parent_id="{{$comments[$k]->parent_id}}" id="{{$comments[$k]->id}}">
{!!$comments[$k]->body!!}
</li>
#endif
#endfor
{{"///////////////////////////////////////////////"}}
#endif
#if(array_search($comments[$i]->parent_id,$myArray)===false)
#for($k=0;$k<count($comments);$k++)
#if($comments[$i]->id==$comments[$k]->parent_id)
<li class="list-group-item py-2 commBody" style="margin-left: calc({{$comments[$k]->parent_id}}*10px) !important" parent_id="{{$comments[$k]->parent_id}}" id="{{$comments[$k]->id}}">
{!!$comments[$k]->body!!}
</li>
#endif
#endfor
#endif
#endfor
#endif
And how it looks along with duplicates:
Edit4:
Followed Tim Lewis advice of separating comments(parentless) from replies(with parents), here's how to displayed them and sending additional parameter to reply form partial:
<ul class="list-group" style="list-style-type:none">
#if(count($comms) > 0)
#for($i=0;$i<count($comms);$i++)
<li class="list-group-item py-2 commBody" style="margin-left: calc({{"0"}}*10px) !important" parent_id="{{$comms[$i]->parent_id}}" id="{{$comms[$i]->id}}">
{{$comms[$i]->body}}
#if(Auth::check() && Auth::user()->role_id<3 && Auth::user()->role_id>0)
<br><span class="btn btn-outline-primary btn-sm" style="width: 40px;height: 20px;line-height: 5px;padding: 5px;" onclick="reply('reply{{ $comms[$i]->id }}')";>reply</span>
#include('inc.replyForm', array('par' => $comms[$i]))
#endif
</li>
<li>#if($i>0) <div class="horDiv"></div> #endif </li>
#if(count($replies) > 0)
#for($j=0;$j<count($replies);$j++)
#if($comms[$i]->id==$replies[$j]->parent_id)
<li class="list-group-item py-2 commBody" style="margin-left: calc({{$comms[$i]->id}}*10px) !important" parent_id="{{$replies[$j]->parent_id}}" id="{{$replies[$j]->id}}">
{{$replies[$j]->body}}
#if(Auth::check() && Auth::user()->role_id<3 && Auth::user()->role_id>0)
<br><span class="btn btn-outline-primary btn-sm" style="width: 40px;height: 20px;line-height: 5px;padding: 5px;" onclick="reply('reply{{ $replies[$j]->id }}')";>reply</span>
#include('inc.replyForm', array('par' => $replies[$j]))
#endif
</li>
<li>#if($j>0) <div class="horDiv"></div> #endif </li>
#endif
#for($k=$j;$k<count($replies);$k++)
#if($replies[$k]->parent_id==$replies[$j]->id)
<li class="list-group-item py-2 commBody" style="margin-left: calc({{$replies[$j]->id}}*10px) !important" parent_id="{{$replies[$k]->parent_id}}" id="{{$replies[$k]->id}}">
{{$replies[$k]->body}}
#if(Auth::check() && Auth::user()->role_id<3 && Auth::user()->role_id>0)
<br><span class="btn btn-outline-primary btn-sm" style="width: 40px;height: 20px;line-height: 5px;padding: 5px;" onclick="reply('reply{{ $replies[$k]->id }}')";>reply</span>
#include('inc.replyForm', array('par' => $replies[$k]))
#endif
</li>
<li>#if($k>0) <div class="horDiv"></div> #endif </li>
#endif
#endfor
#endfor
#endif
#endfor
#endif
</ul>

I did it before for making categories. Here is a tip:
<select name="category_id" class="form-control chosen-select" required value="{{ old('category_id') }}">
#foreach(App\Category::where('parent_id',0)->get() as $c)
<option value="{{$c->id}}">*{{$c->name}}</option>
#foreach(App\Category::where('parent_id',$c->id)->get() as $d1)
<option value="{{$d1->id}}"> - {{$d1->name}}</option>
#endforeach
#endforeach
</select>

Related

search in PHP Array, similar to MySQL Like %var% search with livewire

I saw other questions that usually use preg_grep but my problem was not solved
In the LiveWire component, I receive information from the web service and display it in a table.
Now the user does the search and I want to display the items that look like the searched phrase
I wrote the code like this:
class Cryptolist extends Component
{
use WithPagination;
public bool $loadData = false;
protected $paginationTheme = 'bootstrap';
public $perPage = 10;
public $search = '';
public function init()
{
$this->loadData = true;
}
public function getBalance($asset)
{
$this->dispatchBrowserEvent('setPrice' ,[
'asset' => $asset,
'price' => getCryptoBalance($asset)
]);
}
public function setPerPage(int $page)
{
$this->perPage = $page;
}
public function render()
{
try {
if ($this->loadData == true) {
$api = new \Binance\API('','');
$coins = $api->coins();
} else {
$coins = [];
}
return view('livewire.backend.crypto.cryptolist')->with('coins' , collect(preg_grep('~'.$this->search.'~i', $coins))->paginate($this->perPage));
}catch(\Exception $e)
{
return view('wrong')->with('e' , $e);
}
}
}
and this is view:
<div class="nk-block" id="loadesh1" >
<div class="card card-bordered card-stretch">
<div class="card-inner-group">
<div class="card-inner position-relative card-tools-toggle">
<div class="card-title-group">
<div class="card-tools mr-n1">
<ul class="btn-toolbar gx-1">
<li>
<a class="btn btn-icon search-toggle toggle-search" data-target="search" href="#"><em class="icon ni ni-search"></em></a>
</li>
<li class="btn-toolbar-sep"></li>
<li>
<div class="toggle-wrap">
<a class="btn btn-icon btn-trigger toggle" data-target="cardTools" href="#"><em class="icon ni ni-menu-right"></em></a>
<div class="toggle-content" data-content="cardTools">
<ul class="btn-toolbar gx-1">
<li class="toggle-close">
<a class="btn btn-icon btn-trigger toggle" data-target="cardTools" href="#"><em class="icon ni ni-arrow-left"></em></a>
</li>
<li>
<div class="dropdown">
<a class="btn btn-trigger btn-icon dropdown-toggle" data-toggle="dropdown" href="#"><em class="icon ni ni-setting"></em></a>
<div class="dropdown-menu dropdown-menu-xs dropdown-menu-right">
<ul class="link-check">
<li><span>show</span></li>
<li #if($perPage === 10) class="active" #endif>
10
</li>
<li #if($perPage === 20) class="active" #endif>
20
</li>
<li #if($perPage === 50) class="active" #endif>
50
</li>
</ul>
</div>
</div>
</li>
</ul>
</div>
</div>
</li>
</ul>
</div>
</div>
<div class="card-search search-wrap" data-search="search">
<div class="card-body">
<div class="search-content">
<a class="search-back btn btn-icon toggle-search" data-target="search" href="#"><em class="icon ni ni-arrow-left"></em></a><input wire:model="search" class="form-control border-transparent form-focus-none" placeholder="type for search" type="text"><button class="search-submit btn btn-icon"><em class="icon ni ni-search"></em></button>
</div>
</div>
</div>
</div>
<div class="card-inner p-0" wire:init="init">
<div class="nk-tb-list nk-tb-ulist">
<div class="nk-tb-item nk-tb-head">
<div class="nk-tb-col">
<span class="sub-text">name</span>
</div>
<div class="nk-tb-col tb-col-mb">
<span class="sub-text">balance</span>
</div>
</div>
#foreach ($coins as $item => $value)
<div class="nk-tb-item">
<div class="nk-tb-col">
<a href="/demo5/user-details-regular.html">
<div class="user-card">
<div class="user-avatar d-none d-sm-flex">
#if(file_exists(public_path() . '/img/crypto/'.strtolower($value['coin'].".svg")))
<img style="border-radius: 0" src="{{asset('/img/crypto/'.strtolower($value['coin']))}}.svg" class="img-fluid" alt="">
#else
<img style="border-radius: 0" src="https://demo.rayanscript.ir/-/vendor/cryptocurrency-icons/32/color/noimage.png" class="img-fluid" alt="">
#endif
</div>
<div class="user-info">
<span class="tb-lead english" style="font-weight: bolder">{{$value['name']}}</span>
<span class="english">{{$value['coin']}}</span>
</div>
</div>
</a>
</div>
<div class="nk-tb-col tb-col-mb">
<div class="btn-group" aria-label="Basic example">
<button type="button" class="btn btn-sm btn-dim btn-light" wire:click="getBalance('{{$value['coin']}}')">
<div wire:loading wire:target="getBalance('{{$value['coin']}}')">
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
</div>
<span class="w-120px" id="coin-{{$value['coin']}}">get balance</span>
</button>
<button type="button" class="btn btn-sm btn-dim btn-primary">add coin</button>
</div>
</div>
</div>
#endforeach
</div>
</div>
</div>
</div>
</div>
But this error is given. Is my search method correct?
Array to string conversion

Failed to load excel\laravel-excel

I want to export only filtered data in view blade. I am using Laravel 7 and maatwebsite/excel 3.1 and PHP 7.4.2.
I went through the documentation and applied this:
View
<a href="{!! route('users.export-filter') !!}" class="btn btn-success">
<i class="la la-download"></i>
Export Filter
</a>
web.php
Route::get('/users/export-filter', 'Admin\UserController#filter')->name('users.export-filter');
UserController.php
public function filter()
{
return Excel::download(new FilterUserExport, 'filter.xlsx');
}
FilterUserExport.php
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromView;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\AfterSheet;
use Modules\User\Entities\User;
use Illuminate\Contracts\View\View;
class FilterUserExport implements FromView, ShouldAutoSize, WithEvents
{
/**
* #return View
*/
public function view(): View
{
$users = app(User::class)->newQuery();
if ( request()->has('search') && !empty(request()->get('search')) ) {
$search = request()->query('search');
$users->where(function ($query) use($search) {
$query->where('first_name', 'LIKE', "%{$search}%")
->orWhere('last_name', 'LIKE', "%{$search}%")
->orWhere('email', 'LIKE', "%{$search}%")
->orWhere('mobile', 'LIKE', "%{$search}%");
});
}
return view('users.index', compact('users'));
}
/**
* #return array
*/
public function registerEvents(): array
{
return [
AfterSheet::class => function(AfterSheet $event) {
$event->sheet->getDelegate()->setRightToLeft(true);
},
];
}
}
index.blade.php
#extends("admin-panel.layouts.master")
#section("content")
<div class="content-body">
<section class="grid-with-inline-row-label" id="grid-with-inline-row-label">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">
<a data-action="collapse">
<i class="ft-plus mr-1"></i>
ثبت فیلتر
</a>
</h4>
<a class="heading-elements-toggle"><i class="ft-align-justify font-medium-3"></i></a>
<div class="heading-elements">
<ul class="list-inline mb-0">
<li><a data-action="collapse"><i class="ft-plus"></i></a></li>
<li><a data-action="reload"><i class="ft-rotate-cw"></i></a></li>
<li><a data-action="expand"><i class="ft-maximize"></i></a></li>
<li><a data-action="close"><i class="ft-x"></i></a></li>
</ul>
</div>
</div>
<div class="card-content collapse #if( $errors->any() ) show #endif">
<div class="card-body">
<form action="{!! route('admin::users.index') !!}" method="get">
<div class="form-body">
<div class="row">
<div class="col-6 form-group">
<label for="search">جستجو</label>
<input type="text" name="search" id="search" class="form-control"
placeholder="جستجو..."
aria-label="جستجو" value="{{ request()->query('search') }}">
</div>
<div class="col-6 form-group">
<label for="user_type">گروه کاربری</label>
<select id="user_type" name="user_type" class="form-control">
<option value="" {{ (request()->query('user_type') == '')? "selected" : "" }}>-</option>
<option value="is_special" {{ (request()->query('user_type') == 'is_special')? "selected" : "" }}>کاربر ویژه</option>
<option value="is_user" {{ (request()->query('user_type') == 'is_user')? "selected" : "" }}>کاربر عادی</option>
<option value="is_admin" {{ (request()->query('user_type') == 'is_admin')? "selected" : "" }}>مدیریت سیستم</option>
</select>
</div>
<div class="col-6 form-group">
<label for="target">فیلتر کاربران</label>
<select id="target" name="target" class="form-control">
<option value="" {{ (request()->query('target') == '')? "selected" : "" }}>-</option>
<option value="active" {{ (request()->query('target') == 'active')? "selected" : "" }}>کاربر ویژه</option>
<option value="orderedAtLeastOnce" {{ (request()->query('target') == 'orderedAtLeastOnce')? "selected" : "" }}>کاربر عادی</option>
<option value="orderedInLastMonth" {{ (request()->query('target') == 'orderedInLastMonth')? "selected" : "" }}>مدیریت سیستم</option>
<option value="neverOrdered" {{ (request()->query('target') == 'neverOrdered')? "selected" : "" }}>مدیریت سیستم</option>
</select>
</div>
<div class="col-md-6 form-group">
<label for="categoryId">دسته بندی</label>
{!! Form::select('categoryId', \Modules\Category\Entities\Category::whereNull('parentId')->get()->pluck('title', 'id')->toArray(), null, [
'class' => 'form-control',
'id' => 'categoryId',
'placeholder' => 'انتخاب دسته بندی',
]) !!}
</div>
</div>
<div class="d-flex justify-content-between form-actions pb-0">
<div>
<button type="submit" class="btn btn-primary">ارسال <i class="ft-send position-right"></i>
</button>
<button type="reset" class="btn btn-warning">ریست <i class="ft-refresh-cw position-right"></i>
</button>
</div>
<div>
<a href="{!! route('admin::users.export-excel') !!}" class="btn btn-success">
<i class="la la-download"></i>
صادر
</a>
<a href="{!! route('admin::users.export-filter') !!}" class="btn btn-success">
<i class="la la-download"></i>
Export Filter
</a>
<a href="{!! route('admin::users.export-special-excel') !!}" class="btn btn-success">
<i class="la la-download"></i>
صدور کاربران ویژه
</a>
<a href="{!! route('admin::users.import-excel') !!}" class="btn btn-primary">
<i class="la la-cloud-download"></i>
آپلود
</a>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div id="recent-transactions" class="col-xl-12 col-12">
<div class="card">
<div class="card-header">
<div class="row">
<div class="col-md">
<div class="row justify-content-between align-items-center mr-md-1 mb-1">
<div class="col-sm">
<h4 class="card-title mb-2 mb-sm-0">فهرست کاربران</h4>
</div>
</div>
</div>
<div class="col-auto">
<a href="{!! route('admin::users.create') !!}" class="btn btn-info">
<i class="la la-plus"></i>
ایجاد کاربر جدید
</a>
</div>
</div>
</div>
<div class="card-content">
#if( $users->count() > 0 )
#includeWhen( Module::find('notification') && request()->has('search'), 'user::admin.users._notification' )
<div class="table-responsive">
<table id="recent-orders" class="table table-hover table-xl mb-0">
<thead>
<tr>
<th class="border-top-0"># شناسه</th>
<th class="border-top-0">نام و نام خانوادگی</th>
<th class="border-top-0">موبایل</th>
{{-- <th class="border-top-0">ایمیل</th>--}}
<th class="border-top-0">کد ملی</th>
<th class="border-top-0">مدیر</th>
<th class="border-top-0">وضعیت</th>
<th class="border-top-0">ویژه</th>
<th class="border-top-0">آخرین ورود</th>
<th class="border-top-0">عملیات</th>
</tr>
</thead>
<tbody>
#foreach($users as $user)
<tr>
<td class="text-truncate">
<i class="la la-dot-circle-o success font-medium-1 mr-1"></i>
{{ $user->id }}
</td>
<td class="text-wrap">
{{ $user->first_name.' '.$user->last_name }}
</td>
<td class="text-wrap">
{{ $user->mobile }}
</td>
{{--<td class="text-wrap">
{{ $user->email }}
</td>--}}
<td class="text-wrap">
{{ $user->national_id }}
</td>
<td class="text-wrap">
#if( $user->is_admin )
<i class="ft-check-circle text-success"></i>
#else
<i class="ft-x-circle text-danger"></i>
#endif
</td>
<td class="text-wrap">
#if( !$user->disabled_at )
<i class="ft-check-circle text-success"></i>
#else
<i class="ft-x-circle text-danger"></i>
#endif
</td>
<td class="text-wrap">
#if( $user->is_special_user == 1 )
<i class="ft-check-circle text-success"></i>
#else
<i class="ft-x-circle text-danger"></i>
#endif
</td>
<td class="text-wrap">
#if( $user->last_login_at )
{{ getShamsiDate($user->last_login_at) }}
#else
—
#endif
</td>
<td>
<div class="row flex-nowrap">
<a href="{{ route('admin::users.show', $user) }}" class="mr-1">
<i class="ft-eye text-grey text-shadow-custom font-medium-5 font-weight-normal"></i>
</a>
<a href="{{ route('admin::users.edit', $user) }}" class="mr-1">
<i class="ft-edit text-grey text-shadow-custom font-medium-4 font-weight-normal"></i>
</a>
<form action="{{ route('admin::users.destroy', $user) }}"
method="post"
#submit.prevent="confirmDelete">
#method('delete')
#csrf
<button type="submit" class="btn btn-default p-0">
<i class="ft-trash-2 text-grey font-medium-5 font-weight-normal"></i>
</button>
</form>
</div>
</td>
</tr>
#endforeach
</tbody>
</table>
<div class="pagination-flat">
{{ $users->links() }}
</div>
</div>
#else
<div class="text-center my-2">
<p>نتیجه‌ای برای نمایش وجود ندارد.</p>
</div>
#endif
</div>
</div>
</div>
</div>
</section>
</div>
#endsection
I get this error
The export submit button is sending everything to Excel. How do I make it to send only the filtered data. Thanks
You need to get rid of the other HTML in your view such as forms, inputs, and buttons. Keep the view only to a minimum of the table that needed for your Excel.

Access data in laravel

I need to access data on my view. can you assist me in reviewing my code its throwing me an error massage: "Trying to get property 'avatar' of non-object"
My controller:
$user = User::find($id);
$profile = Personal_Details::select('*')->where('user_id', $id)->first();
//return $profile;
$idd = $user->id;
$name = $user->name;
$email = $user->email;
$avatar = $user->avatar;
$lastname = $profile->lastname;
$cellNumber = $profile->cellNumber;
$street = $profile->address_street;
$city = $profile->address_city;
$province = $profile->address_province;
$postal = $profile->address_postal_code;
$records = array(['id'=>$idd, 'avatar'=>$avatar, 'name'=>$name." ".$lastname,'email'=>$email, 'cellnumber'=>$cellNumber, 'address1'=>$street.", ".$city, 'address2'=>$province.", ".$postal]);
$record = $records[0];
// return $record;
return view('admin.profile.specialist')->with(['record'=>$record]);
My view:
<div class="px-4 pt-0 pb-4 bg-dark">
<div class="media align-items-end profile-header" style="padding-top: 5%">
<div class="profile mr-3"><img src="/storage/avatars/{{ $record->avatar }}" alt="..." width="130" class="rounded mb-2 img-thumbnail">Edit profile</div>
<div class="media-body mb-4 text-white">
<h4 class="mt-0 mb-0">{{ $record->name }}</h4>
<p class="small mb-4">
<i class="fa fa-envelope mr-2"></i>{{ $record->email }}<br>
<i class="fa fa-phone mr-2"></i>{{ $record->cellnumber }}<br>
<i class="fa fa-map-marker mr-2"></i>{{ $record->address1 }},<br> {{ $record->address2 }}<br>
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
<span class="fa fa-star"></span>
<span class="fa fa-star"></span>
</p>
</div>
<div class="custom-control custom-switch text-white">
<div class="row">
<a hrt="" style="padding-right:43px">Personal</a>
<input type="checkbox" class="custom-control-input" id="customSwitch1">
<label class="custom-control-label" for="customSwitch1">Business</label>
</div>
</div>
</div>
</div>
my response when i uncomment return $record:
{"id":2,"avatar":"default.jpg","name":"Test Data","email":"example#example.io","cellnumber":"0711234567","address1":"1002 Highway, Geelong","address2":"Melbe, 21910"}
I'm not sure what i have missed or maybe the way m trying to access code is wrong.
"Trying to get property 'avatar' of non-object"
This means you're using a variable as an object when it's something else (aray, string, null, etc). This happens in your case because of the following lines
$records = array(['id'=>$idd, 'avatar'=>$avatar, 'name'=>$name." ".$lastname,'email'=>$email, 'cellnumber'=>$cellNumber, 'address1'=>$street.", ".$city, 'address2'=>$province.", ".$postal]);
$record = $records[0];
$record is an array here. $record->avatar will throw the error. $record['avatar'] will access the avatar key of the $record array.
But that is a bit redundant because you've already got all the information you need in the $user and $profile variables. $records and $record have no reason to exist.
$user = User::find($id);
$profile = Personal_Details::select('*')->where('user_id', $id)->first();
return view('admin.profile.specialist', compact('user', 'profile');
$user and $profile are objects so you can use them as such in your view.
<div class="px-4 pt-0 pb-4 bg-dark">
<div class="media align-items-end profile-header" style="padding-top: 5%">
<div class="profile mr-3">
<img src="/storage/avatars/{{ $user->avatar }}" alt="..." width="130" class="rounded mb-2 img-thumbnail">
Edit profile
</div>
<div class="media-body mb-4 text-white">
<h4 class="mt-0 mb-0">{{ $user->name }}</h4>
<p class="small mb-4">
<i class="fa fa-envelope mr-2"></i>{{ $user->email }}<br>
<i class="fa fa-phone mr-2"></i>{{ $profile->cellnumber }}<br>
<i class="fa fa-map-marker mr-2"></i>{{ $profile->address_street}}, {{ $profile->address_city }},<br> {{ $profile->address_province }}, {{ $profile->address_postal_code }}<br>
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
<span class="fa fa-star"></span>
<span class="fa fa-star"></span>
</p>
</div>
<div class="custom-control custom-switch text-white">
<div class="row">
Personal
<input type="checkbox" class="custom-control-input" id="customSwitch1">
<label class="custom-control-label" for="customSwitch1">Business</label>
</div>
</div>
</div>
</div>
And that's it. The following might not apply to you, so feel free to ignore.
The query Personal_Details::where('user_id', $user->id)->get() suggests a One-to-one relationship.
You could declare it and then use it in your controller/view.
# User model
public function profile()
{
return $this->hasOne(Personal_Detail::class, 'user_id');
}
# Personal_Detail model
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
# Controller
$user = User::with('profile')->find($id);
return view('admin.profile.specialist', compact('user');
And then in your view, you could replace $profile->... by $user->profile->...

Laravel Error: Too few arguments to function, 0 passed and exactly 1 expected

Using Laravel-5.8, I have this code:
public function manager_employee_list(Request $request)
{
$employees = HrEmployee::paginate(6);
return view('appraisal.appraisal_goals.manager_employee_list')->with('employees', $employees);
}
And it render this view: manager_employee_list
<div class="row d-flex align-items-stretch">
#if (count($employees))
#foreach($employees as $key => $employee)
<div class="col-12 col-sm-6 col-md-4 d-flex align-items-stretch">
<div class="card bg-light">
<div class="card-header text-muted border-bottom-0">
{{isset($employee->designation) ? $employee->designation->designation_name : ''}}
</div>
<div class="card-body pt-0">
<div class="row">
<div class="col-7">
<h2 class="lead"><b>Staff ID: {{$employee->employee_code}}</b></h2>
<h2 class="lead"><b>{{$employee->first_name}} {{$employee->last_name}}</b></h2>
<h6 class="lead"><b>Employee Department: </b>{{isset($employee->department) ? $employee->department->dept_name : ''}}</h6>
</div>
<div class="col-5 text-center">
#if($employee->emp_image != '')
<img src="{{ URL::to('/') }}/public/storage/employees/image/{{ $employee->emp_image }}" class="img-circle img-fluid" />
#else
<img class="profile-user-img img-fluid img-circle" src="{{asset('theme/adminlte3/dist/img/default.png')}}" alt="" class="img-circle img-fluid">
#endif
</div>
</div>
</div>
<div class="card-footer">
<div class="text-right">
<a href="{{ route('appraisal.appraisal_goals.manager_employee_goal', ['id'=>$employee->id]) }}" class="btn btn-sm btn-primary">
<i class="fas fa-user"></i> View Goal
</a>
</div>
</div>
</div>
</div>
#endforeach
#else
<h4 style="text-align:center;">No matching records found</h4>
#endif
</div>
I want to pass the parameter
['id'=>$employee->id]
from above to another controller action:
public function manager_employee_goal($id)
{
$goals = AppraisalGoal::where('employee_id', $id)->get();
return view('appraisal.appraisal_goals.manager_employee_goal')->with('goals', $goals);
}
It utilizes it here:
$goals = AppraisalGoal::where('employee_id', $id)->get();
When I clicked on
<a href="{{ route('appraisal.appraisal_goals.manager_employee_goal', ['id'=>$employee->id]) }}" class="btn btn-sm btn-primary">
<i class="fas fa-user"></i> View Goal
</a>
I got this error:
Too few arguments to function App\Http\Controllers\Appraisal\AppraisalGoalsController::manager_employee_goal(), 0 passed and exactly 1 expected
and this is underlined:
public function manager_employee_goal($id)
route/web.php
Route::get('appraisal_goals/manager_employee_list', 'Appraisal\AppraisalGoalsController#manager_employee_list')->name('appraisal.appraisal_goals.manager_employee_list');
Route::get('appraisal_goals/manager_employee_goal', 'Appraisal\AppraisalGoalsController#manager_employee_goal')->name('appraisal.appraisal_goals.manager_employee_goal');
How do I resolve it?
Thank you.
You need to change in your web.php file. add {id} in URL.
otherwise, all are fine as now your get method will be like 'appraisal_goals/manager_employee_goal/{id}'
Route::get('appraisal_goals/manager_employee_goal/{id}','Appraisal\AppraisalGoalsController#manager_employee_goal')->name('appraisal.appraisal_goals.manager_employee_goal');
I believe your route need to be updated to
Route::get('appraisal_goals/manager_employee_goal/{id}','Appraisal\AppraisalGoalsController#manager_employee_goal')->name('appraisal.appraisal_goals.manager_employee_goal');

Laravel ajax store request errormessage, data append to view

I'm new to ajax and I have two little problems.
With my code I can write the data in the database. I get no error messages and the data are not synonymous directly loaded into the view.
how can I load the data directly into the view without reload the page?
if the privacy is 1, the code should be displayed in the right column, and if the privacy is 0, the code should be displayed in the left column.
How can I output the error messages with my errormessage code?
view
<div id="content" class="dashboard padding-10">
<div class="row">
<div class="col-md-offset-3 col-md-6">
<a data-toggle="modal" data-target=".todolist-create-modal" class="btn btn-success btn-block btn-sm margin-bottom-10">Neue Liste erstellen</a>
</div>
<div class="col-md-6">
<div id="panel-misc-portlet-l3" class="panel panel-default text-center">
<div class="panel-heading nohover">
<span class="elipsis">
<strong>Private Tasks</strong>
</span>
</div>
</div>
<div class="alert alert-danger margin-bottom-30 {{ $todolistpublic->count() ? 'hidden' : '' }}">
Es wurden keine <strong>Einträge</strong> gefunden.
</div>
#foreach ($todolistpublic as $list)
<div id="todo-list-{{$list->id}}" class="panel panel-default panel-primary margin-bottom-0">
<div class="panel-heading panel-pointer">
<span class="elipsis"><!-- panel title -->
<strong>{{ $list->title }}</strong> <span class="label label-info white">0</span>
</span>
<ul class="options pull-right relative list-unstyled hover-visible">
<li><a data-toggle="modal" data-target=".task-modal" class="btn btn-success btn-xs white hover-hidden">
<i class="fa fa-plus"></i> Erstellen
</a>
</li>
<li><a data-toggle="modal" data-target=".todolist-modal" data-id="{{ $list->id }}" data-title="{{ $list->title }}" data-description="{{ $list->description }}" class="btn btn-info btn-xs white hover-hidden">
<i class="fa fa-edit"></i> Bearbeiten
</a>
</li>
<li><a data-toggle="modal" data-target=".todolist-delete-modal" data-id="{{ $list->id }}" data-title="{{ $list->title }}" data-description="{{ $list->description }}" class="btn btn-danger btn-xs white hover-hidden">
<i class="fa fa-times"></i> Löschen
</a>
</li>
<li></li>
</ul>
</div>
<div class="panel-body">
<div class="slimscroll" data-always-visible="false" data-rail-visible="false" data-railOpacity="1" data-height="100">
{{ $list->description }}
</div>
</div>
</div>
#endforeach
<div class="panel-footer mtm-10">
<span id="todo-list-counter-public">{{ $todolistpublic->count() }}</span> <span>{{ $todolistpublic->count() > 1? 'Listen' : 'Liste' }}</span>
</div>
</div>
<div class="col-md-6">
<div id="panel-misc-portlet-l3" class="panel panel-default text-center">
<div class="panel-heading nohover">
<span class="elipsis">
<strong>Öffentliche Tasks</strong>
</span>
</div>
</div>
<div class="alert alert-danger margin-bottom-30 {{ $todolistprivate->count() ? 'hidden' : '' }}">
Es wurden keine <strong>Einträge</strong> gefunden.
</div>
#foreach ($todolistprivate as $list)
<div id="todo-list-{{$list->id}}" class="panel panel-default panel-primary margin-bottom-0">
<div class="panel-heading panel-pointer">
<span class="elipsis"><!-- panel title -->
<strong>{{ $list->title }}</strong> <span class="label label-info white">0</span>
</span>
<ul class="options pull-right relative list-unstyled hover-visible">
<li><a data-toggle="modal" data-target=".task-modal" class="btn btn-success btn-xs white hover-hidden"><i class="fa fa-plus"></i> Erstellen</a></li>
<li><a data-toggle="modal" data-target=".todolist-modal" class="btn btn-info btn-xs white hover-hidden"><i class="fa fa-edit"></i> Bearbeiten</a></li>
<li><i class="fa fa-times"></i> Löschen</li>
<li></li>
</ul>
</div>
<div class="panel-body">
<div class="slimscroll" data-always-visible="false" data-rail-visible="false" data-railOpacity="1" data-height="100">
{{ $list->description }}
</div>
</div>
</div>
#endforeach
<div class="panel-footer mtm-10">
<span id="todo-list-counter-private">{{ $todolistprivate->count() }}</span> <span>{{ $todolistprivate->count() > 1? 'Listen' : 'Liste' }}</span>
</div>
</div>
#include('elements.addTodoList')
#include('elements.createTodoList')
#include('elements.addTask')
</div>
</div>
$(document).ready(function () {
var CSRF_TOKEN = $('meta[name="csrf-token"]').attr('content');
$('#add-todo-list').click(function(e) {
e.preventDefault();
var _token = $("input[name='_token']").val(); // get csrf field.
var title = $("input[name='title']").val();
var description = $("textarea[name='description']").val();
var privacy = $("select[name='privacy']").val();
$.ajax({
url:'{{ route('todolists.store') }}',
type: 'POST',
data: {_token:_token, title:title, description:description, privacy:privacy},
success: function (data) {
console.log(data);
}
});
});
});
Controller
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'title' => 'required|min:5',
'description' => 'required|min:10',
'privacy' => 'required|integer'
]);
$attributeNames = array(
'title' => 'Title',
'description' => 'Description',
);
$validator->setAttributeNames($attributeNames);
//Redirect back if validation fails
if($validator->fails()) {
return response()->json(['error'=>$validator->errors()->all()]);
}
else{
$todolists = new Todolists;
$todolists->admin_id = auth::user();
$todolists->title = $request->title;
$todolists->description = $request->description;
$todolists->privacy = $request->privacy;
$todolists->save();
return response()->json(['success'=>'Your enquiry has been successfully submitted!']);
}
}
modal
<div class="modal fade todolist-create-modal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Erstelle eine neue Liste</h4>
</div>
<div class="modal-body">
<form action="{{ route('todolists.store') }}" method="post">
{{ csrf_field() }}
<div class="form-group">
<label for="" class="control-label">Titelname</label>
<div class="fancy-form">
<i class="fa fa-header"></i>
<input id="title" name="title" type="text" class="form-control input-lg" placeholder="Titel">
</div>
</div>
<div class="form-group">
<label for="" class="control-label">Beschreibung</label>
<div class="fancy-form">
<textarea id="description" name="description" rows="2" class="form-control" placeholder="Beschreibe deine Aufgabe"></textarea>
<i class="fa fa-comments"><!-- icon --></i>
</div>
</div>
<div class="form-group">
<label for="" class="control-label">Privatsphäre</label>
<div class="fancy-form fancy-form-select">
<select id="privacy" name="privacy" class="form-control">
<option selected value="0">Öffentlich</option>
<option value="1">Privat</option>
</select>
<i class="fancy-arrow"></i>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-success" id="add-todo-list">Save changes</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
errormessages
#if (count($errors) > 0)
<div class="toastr-notify"></div>
#foreach ($errors -> all() as $e)
<script type="text/javascript">
_toastr("{{$e}}","top-right","error",false);
</script>
#endforeach
#endif
#if (session('fail'))
<div class="toastr-notify"></div>
<script type="text/javascript">
_toastr("{{ session('fail') }}","top-full-width","warning",false);
</script>
#endif
#if (session('status'))
<div class="toastr-notify"></div>
<script type="text/javascript">
_toastr("{{ session('status') }}","top-full-width","info",false);
</script>
#endif
#if (session('success'))
<div class="btn btn-info toastr-notify"></div>
<script type="text/javascript">
_toastr("{{ session('success') }}","top-full-width","success", false);
</script>
#endif
#if (session('error'))
<div class="toastr-notify"></div>
<script type="text/javascript">
_toastr("{{ session('error') }}","top-full-width","error",false);
</script>
#endif
I believe you have a typo in your ajax backend code; this line to be specific:
$todolists->admin_id = auth::user();
This should be:
$todolists->admin_id = auth()->user()->id;
The typo is generating a Throwable error, which is getting caught by the laravel exception handler and it's detecting that the code is being executed under a ajax request and hence returning a 500 internal server error.

Resources