Laravel some questions (pagination, if - foreach) - php

I'm laravel newbie. I'm created simple code and I have some questions:
I think this code bad (it works, but I use #forelse($forums as $forum) and anywhere use $forum)
#extends('layouts.main')
#section('content')
#forelse($forums as $forum) <-- I don't like this line, it works but i think it's possible with if or something else
#forelse($topics as $topic)
{{ $topic->title }}<br>
#empty
Sorry but this forums empty.
#endforelse
#empty
Sorry but this forum not found
#endforelse
#stop
And second question how to make pagination? I'm tried this:
<?php
namespace App\Http\Controllers;
use DB;
use View;
class viewForum extends Controller
{
public function showForum($fname, $fid)
{
return View::make('forum', [
'forums' => DB::table('forums')
->where('id', $fid)
->where('seo_name', $fname)
->select()
->get()
->simplePagination(5)
]);
}
}
But not work's, I'm tried tutorials..etc, how to? Thanks so much in advance ! :)

for your first question. You can use #foreach or #each. these are the two that i usually used.
for your second question:
return View::make('forum', [
'forums' => DB::table('forums')
->where('id', $fid)
->where('seo_name', $fname)
->select()
->paginate(5);
]);
remove ->get()
and replace simplePagination(5) with paginate(5)
documation http://laravel.com/docs/5.0/pagination
Update
change you code block from
return View::make('forum', [
'forums' => DB::table('forums')
->where('id', $fid)
->where('seo_name', $fname)
->select()
->paginate(5);
]);
to
$forums = DB::table('forums')
->where('id', $fid)
->where('seo_name', $fname)
->select()
->paginate(5);
return View::make('forum', compact('forums'));
then check if $forums->render() got error.
Update
$forums = DB::table('forums')
->where('id', $fid)
->where('seo_name', $fname)
->select()
->get(5);
$topics = DB::table('topics')
->where('forum_id', $id)
->select()
->paginate(2)
return View::make('forums', compact('forums', 'topics'));
on your view you do <?php echo $topics->render() ?> since topic is the one you paginate. also you can remove ->select() from your code. if you don't specify fields to output.

For #foreach ($topics as $topic)
{{$topic->title}}
#endforeach
For Pagination
$users = User::where('status','1')
->paginate(10);
Note: In View add this {{$user->links()}} for getting the pagination links.

you can use #foreach() #endforeach and probably #if #else #endif
see sample:
#foreach($forums as $forum)
#if($forum==0)
{{'empty'}}
#else
{{ 'Not empty' }}
#endif
#endforeach

for pagination i will suggest you use jquery datatable for proper pagination. Its quite okay and saves lots of time. see below the sample implementation:
//this preload the jquery library for datatable together with the print button
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.5.2/js/dataTables.buttons.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.5.2/js/buttons.print.min.js"></script>
//this section call the document ready event making sure that datatable is loaded
<script>
$(document).ready(function() {
$('#').DataTable();
} );
//this section display the datatable
$(document).ready(function() {
$('#mytable').DataTable( {
dom: 'Bfrtip',
"pageLength": 5, //here you can set the page row limit
buttons: [
{
extend: 'print',
customize: function ( win ) {
$(win.document.body)
.css( 'font-size', '10pt' )
.prepend(
''
);
$(win.document.body).find( 'table' )
.addClass( 'compact' )
.css( 'font-size', 'inherit' );
}
}
]
} );
} );
</script>
//you can display record on the datatable as shown below
<div class="table-responsive col-md-12">
<table id="mytable" class="table table-bordered table-striped table-highlight">
<thead>
<tr bgcolor="#c7c7c7">
<th>S/N</th>
<th>Name</th>
</tr>
</thead>
<tbody>
#php
$i=1;
#endphp
#foreach($queryrecord as $list)
<tr>
<td>{{ $i++ }}</td>
<td>{{ $list->name }}</td>
</tr>
#endforeach
</tbody>
</table>
<hr />
</div>
Note: remember before displaying information on the datatable, you must have query your record from database.i'm using query builder here as sample
$data['queryrecord']=DB::table('tablename')->get();

Related

AJAX pagination in Laravel 7 (Internal Server Error)

I am using Laravel 7 and I want to use ajax for my pagination so that it would not refresh the whole page when I click for the next page. I searched up to solve my problem but it was not working and it would not go to the fetch() whenever I error_log() in controller. Whenever I click on page 2 it would error. In the console the error shown is:
app.js:16437 GET http://127.0.0.1:8000/ledger/fetch?page=2 500 (Internal Server Error)
In the storage/logs/laravel.log
[previous exception] [object] (BadMethodCallException(code: 0): Method Illuminate\\Database\\Eloquent\\Collection::links does not exist. at C:\\xampp\\htdocs\\final_Financial\\fin_book_09\\vendor\\laravel\\framework\\src\\Illuminate\\Support\\Traits\\Macroable.php:103)
LedgerController.php
public function index(Request $request)
{
$disableLedger = true;
$ledger = Ledger::orderBy('id', 'DESC')
->where('user_id', auth()->user()->id)
->paginate(5);
$ledgerCatType = DB::table('ledgers')
->orderBy('ledgers.id', 'DESC')
->join('categories', 'ledgers.cat_id', '=', 'categories.id')
->where('ledgers.user_id', auth()->user()->id)
->get('categories.type');
$category = Category::where('user_id', auth()->user()->id)->get();
return view('ledgers.index', [
'ledgers' => $ledger,
'categories' => $category,
'disableLedger' => $disableLedger,
'ledgerCatType' => $ledgerCatType
]);
}
function fetch(Request $request)
{
if ($request->ajax())
{
$ledger = Ledger::orderBy('id', 'DESC')
->where('user_id', auth()->user()->id)
->paginate(5);
$ledgerCatType = DB::table('ledgers')
->orderBy('ledgers.id', 'DESC')
->join('categories', 'ledgers.cat_id', '=', 'categories.id')
->where('ledgers.user_id', auth()->user()->id)
->get('categories.type');
$category = Category::where('user_id', auth()->user()->id)->get();
return view('ledger.entries', compact('ledger', 'categories', 'ledgerCatType'))->render();
}
}
script
$(document).ready(function () {
$('.pagination a').on('click', function(event) {
event.preventDefault();
var page = $(this).attr('href').split('page=')[1];
fetch(page);
})
function fetch(page) {
$.ajax({
url : '/ledger/fetch?page='+page,
success : function(data)
{
$('#ledger-entry').html(data);
},
error : function(){
alert("error!!!!");
}
});
}
});
under the folder ledgers which will be called in the index.blade.php
entries.blade.php
<div class="outer-cont">
<table class="table container inner-cont">
<thead>
<th scope="col">Date</th>
<th scope="col">Description</th>
<th scope="col">Category</th>
<th scope="col">Amount</th>
<th scope="col"></th>
</thead>
<tbody>
#for($i = 0; $i < count($ledgers); $i++)
<tr scope="row">
<td class="tbl-date">{{ $ledgers[$i]->month }} {{ $ledgers[$i]->day }}, {{ $ledgers[$i]->year }}</td>
<td class="tbl-desc">{{ $ledgers[$i]->description }} </td>
<td>{{ $ledgers[$i]->category}} </td>
#if($ledgerCatType[$i]->type == "Expense")
<td class="tbl-amount" style="color: #FF5349;">Php ({{ $ledgers[$i]->amount }})</td>
#else
<td class="tbl-amount" style="color: #3BC23E;">Php {{ $ledgers[$i]->amount }}</td>
#endif
</tr>
#endfor
</table>
</div>
<div class="pagination">{!! $ledgers->links() !!}</div>
index.blade.php
<div id="ledger-entry">
#include('ledgers.entries')
</div>
web.php
Route::resource('ledger','LedgerController')->middleware('auth');
Route::get('/ledger/fetch', 'LedgerController#fetch')->middleware('auth');
Okay nevermind, I fixed it. I'm just going to post the answer here in case anyone gets stuck with it too.
The problem was my route, instead of using the resource I manually added the routes:
Route::get('ledger', 'LedgerController#index')->name('ledger.index')->middleware('auth');
Route::post('/ledger', 'LedgerController#store')->name('ledger.store')->middleware('auth');
Route::delete('/ledger/{id}', 'LedgerController#destroy')->name('ledger.destroy')->middleware('auth');
Route::get('/ledger/fetch', 'LedgerController#index')->name('ledger.fetch')->middleware('auth');
I also edited my code for the index() and thus combining it with the fetch() method thus it now looks like this:
public function index(Request $request)
{
$disableLedger = true;
$ledgers = Ledger::orderBy('id', 'DESC')
->where('user_id', auth()->user()->id)
->paginate(10);
$ledgerCatType = DB::table('ledgers')
->orderBy('ledgers.id', 'DESC')
->join('categories', 'ledgers.cat_id', '=', 'categories.id')
->where('ledgers.user_id', auth()->user()->id)
->select('categories.type')
->paginate(10);
$categories = Category::where('user_id', auth()->user()->id)->get();
if ($request->ajax())
{
return view('ledgers.entries', compact('ledgers', 'categories', 'ledgerCatType', 'disableLedger'))->render();
}
return view('ledgers.index', compact('ledgers', 'categories', 'ledgerCatType', 'disableLedger'));
}

How to fix Show category in laravel

Hi I'm building a ticket system i made tables with heads as:
<table class="table">
<thead>
<tr>
<th>Category</th>
<th>Title</th>
<th>Status</th>
<th>Last Updated</th>
</tr>
</thead>
I'm having trouble calling category name in views:
#foreach ($tickets as $ticket)
#foreach ($categories as $category)
#if ($category->id === $ticket->category_id)
{{ $category->name }}
#endif
#endforeach
My #if statements seems to be wrong i thinks as i can pull all the category names but with #if code seems to be breaking and its showing me nothing.
My routes:
Route::get('my_tickets', 'TicketsController#userTickets');
My Controller Function:
public function userTickets()
{
$tickets = Ticket::where('user_id', Auth::user()->id)->paginate(10);
$categories = Category::all();
return view('tickets.user_tickets', compact('tickets', 'categories'));
}
Update:
My Category Model:
protected $fillable = ['name'];
public function tickets()
{
return $this->hasMany(Ticket::class);
}
&Ticket Model:
protected $fillable = [
'user_id', 'category_id', 'ticket_id', 'title', 'priority', 'message', 'status'
];
public function category()
{
return $this->belongsTo(Category::class);
}
I'm trying to follow this tutorial but i think I'm doing something wrong idk what.
https://scotch.io/tutorials/build-a-support-ticket-application-with-laravel-part-1
https://scotch.io/tutorials/build-a-support-ticket-application-with-laravel-part-2
I think that you are trying to do something like this:
#foreach ($tickets as $ticket)
{{ $ticket->category->name }}
#endforeach
If you made a relation between your classes with belongsTo and hasMany then you can access using $ticket->category->name. If it does not work perhaps you have to get tickets with:
$tickets = Ticket::with('category')->where('user_id', Auth::user()->id)->paginate(10);
You haven't really followed it through. See how it's done in the article
#foreach ($tickets as $ticket)
#foreach ($categories as $category)
#if ($category->id === $ticket->category_id)
{{ $category->name }}
#endif
#endforeach
$ticket->$category is not a valid syntax.

Laravel Paginate not working

I was trying to paginate some data with Query builder with the following query.
public function productSearch(Request $request)
{
$name = $request->name;
$products = DB::table('products')
->where('name', 'LIKE', "%$name%")
->paginate(4);
return view('product',compact('products');
}
But when I tried to show the pagination in the view page with the following line
{{ $products->links() }}
It shows
Method links does not exist
What could the possible error be since the pagination does not show?
2 types to print pagination link in laravel -
Try with -
use Illuminate\Support\Facades\DB;
public function productSearch(Request $request)
{
$name = $request->name;
$products = DB::table('products')
->where('name', 'LIKE', "%$name%")
->paginate(4);
return view('product',['products' => $products]);
}
In View -
<div class="container">
#foreach($products as $product)
<h4>{{ $product['name'] }}</h5> <br>
#endforeach
</div>
1st type to defined laravel pagination link -
{{ $products->links() }}
And 2nd type to defined laravel pagination link -
{{ $products->render(); }}
Note - Also you missed in your code -> return view('product',compact('products')); in return view('product',compact('products');
Here is your solution.
Just change your return view option
return view('product')->with('products', $products);
Hope this helps you.
Change to :
return view('product',compact('products'));
In View page try :
{{$products->render()}}
In your Controller:
return view('product',compact('products');
In your View:
#foreach($products as $product)
{{ $product->name }}
#endforach
{{ $products->links() }}
try with:
{{ $products->render() }}

updateExistingPivot won't work

I'm trying to update my pivot table approve_document where it has a extra column isApprove using ->withPivot method.
Model:
Document
class Document extends Model
{
public function sentToApprovers()
{
return $this->belongsToMany('App\Models\Approve', 'approve_document')->withPivot('isApprove');
}
}
Approve
class Approve extends Model
{
public function createdpendingDocuments()
{
return $this->belongsToMany('App\Models\Document', 'approve_document')->withPivot('isApprove');
}
}
This is where I get all my records in my approve_document.
Controller:
public function documentsSentForApproval()
{
$pendingDocumentLists = DB::table('approve_document')
->select('documents.title', 'documents.content', 'categories.category_type', 'users.username', 'approve_document.dateReceived', 'documents.id', 'approves.approver_id')
->join('documents', 'documents.id', '=', 'approve_document.document_id')
->join('categories', 'categories.id', '=', 'documents.category_id')
->join('approves', 'approves.id', '=', 'approve_document.approve_id')
->join('users', 'users.id', '=', 'approves.approver_id')
->where('approver_id', '=', Auth::id())
->orWhere('requestedBy', '=', Auth::id())
->get();
return view ('document.pending')
->with('pendingDocumentLists', $pendingDocumentLists);
}
View:
#foreach ($pendingDocumentLists as $list)
<tr class = "info">
<td>{{ $list->title }}</td>
<td>{{ strip_tags(substr($list->content, 0, 50)) }} {{ strlen($list->content) > 50 ? "..." : '' }}</td>
<td>{{ $list->category_type }}</td>
<td>{{ $list->username }}</td>
<td>{{ date('M, j, Y', strtotime($list->dateReceived)) }}</td>
<td>
#if (Auth::id() == $list->approver_id)
<a href = "{{ route ('document.pending', $list->id) }}">
<button type = "submit" class = "btn btn-success glyphicon glyphicon-thumbs-up"> Approve</button>
</a>
#endif
</td>
<td></td>
</tr>
#endforeach
You can see here I have a approve button where I need to set isApprove to true when the button is clicked. You can see that I get the current id of the document when the button was clicked.
This part of the Controller where I'm having a hard time updating my pivot table. It gives me a error MethodNotAllowedHttpException. Any tips or help would greatly appreciated!
public function updateIsApprove($id)
{
$document = new Document();
foreach ($document as $update)
{
$approve = new Approve();
$document->sentToApprovers()->updateExistingPivot([$approve->id => ['isApprove' => '1']],false);
}
return redirect()->route('document.pending');
}
routes:
Route::post('/documents/pending/approve/{id}',
[
'uses' => '\App\Http\Controllers\DocumentController#updateIsApprove',
'as' => 'document.pending',
]);
public function updateExistingPivot($id, array $attributes, $touch = true)
First parametr should be id of related thing.
public function updateIsApprove($documentId, $approveId)
{
$document = Document::find($documentId);
if (!$document) {
// Handle error that document not exists.
}
$approve = $document->sentToApprovers()->find($approveId);
if (!$approve) {
// Handle that approve not exists or is not related with document.
}
$document->sentToApproves()->updateExistingPivot($approve->id, ['isApprove' => 1]);
return redirect()->route('document.pending');
}
MethodNotAllowedHttpException is not for your controller but is for your Route. As you can see, in your Routes file, you have Route for handling POST request, but in your view you are making a GET request by accessing the URL directly.
So, just change the POST route to GET in your Routes file.
Route::get('/documents/pending/approve/{id}',
[
'uses' => '\App\Http\Controllers\DocumentController#updateIsApprove',
'as' => 'document.pending',
]);

Laravel print query error

I have this code in routes:
Route::get('forum/{fname}/{fid}', 'viewForum#showForum');
in controller:
<?php
namespace App\Http\Controllers;
use DB;
use View;
class viewForum extends Controller
{
public function showForum($fname, $fid)
{
return View::make('forum', [
'forums' => DB::table('forums')
->where('id', $fid)
->where('seo-name', $fname)
->select()
->get()
]);
}
}
And in the layout:
#extends('layouts.main')
#section('content')
#foreach($forums as $forum)
{{ $forum->name }}
#endforeach
#stop
It's ok, but when I write bad {fname} or {fid} then nothing prints, white page, but i wan't to show error, how can I do it? I've created same with viewProfile :
<?php
namespace App\Http\Controllers;
use DB;
use View;
class viewProfile extends Controller
{
public function showProfile($uname, $uid)
{
$u = DB::table('users')
->where('id', $uid)
->where('name', $uname)
->first();
return View::make('users', [
'username' => $u->name,
'userid' => $u->id,
'email' => $u->email,
'regdate' => $u->created_at
]);
}
}
In this code error prints, but in first nope, why? How can I fix it? Thanks in advance
I'm fixed, I just added this code:
#extends('layouts.main')
#section('content')
#forelse($forums as $forum)
{{ $forum->name }}
#empty
<div class="alert alert-danger">Forum not found</div>
#endforelse
#stop
if you want to show all errors,
Set APP_ENV=local in you .env file.
Allow recursive 777 permission to /vendor and /storage folder.
It should work..
also make sure that in '/config/databse.php' file 'fetch' => PDO::FETCH_ASSOC, or 'fetch' => PDO::FETCH_CLASS, is written.
You should also see that DB::table('forums')
->where('id', $fid)
->where('seo-name', $fname)
->select()
->get();
return a 2D array, and you are required a single dimension array.
Once you be able to show errors you will find all errors easily. :)

Categories