generate link to pages in laravel issue - laravel

I have a problem with link in laravel.
I have this route:
$lingua = Request::segment(1);
Route::group(array('prefix' => $lingua), function()
{
Route::get('/', 'ItemController#menu');
Route::get('/{idcampo}/{idcat}','ItemController#show');
});
The first is language and request the 1st segment, and use as prefix. in /
THis is my ItemController Controller
public function menu()
{$lingua = Request::segment(1);
return View::make('index', ['categorie'=>DB::table('cat_nome')->join('lingua', 'cat_nome.id_lingua', '=', 'lingua.id') ->where('lingua.lingua','=',$lingua)->get(),
'campi' => DB::table('campo_nome')->join('lingua', 'campo_nome.id_lingua', '=', 'lingua.id') ->where('lingua.lingua','=',$lingua)->get(),
'lingua'=>$lingua,
]
);
}
public function show($camps,$cats)
{$lingua = Request::segment(1);
return View::make('categorie', ['categorie'=>DB::table('cat_nome')->join('lingua', 'cat_nome.id_lingua', '=', 'lingua.id') ->where('lingua.lingua','=',$lingua)->get(),
'campi' => DB::table('campo_nome')->join('lingua', 'campo_nome.id_lingua', '=', 'lingua.id') ->where('lingua.lingua','=',$lingua)->get(),
'dd' => DB::table('description')->join('lingua', 'description.id_lingua', '=', 'lingua.id')->where('lingua.lingua','=',$lingua)->where ('description.id_cat','=',$cats)->where ('description.id_campo','=',$camps)->select('description.descrizione')->get(),
'lingua' => $lingua,
]);
}
In index i query a the entries of a menu.
#foreach ($campi as $campo)
{{$campo->nome}}
<ul class="list-unstyled">
#foreach($categorie as $categoria)
<li> {{$categoria->nome}} </li>
#endforeach
</ul>
#endforeach
Now when i pass to the controller, i keep the menu visualized and i visualize the single entries of the database (the description).
My problem is that when i click the first time on the link, which appear to be:
language/id1/id2
I go in the right page, visualize the description of the product BUT now the link on the side menu became:
language/id1/language/id1/id2
But it should always be language/id1/id2 even when i am in Itemcontroller#show
The second time the link are generated in the side menu, something is added on the link, and i can't quite understand why.

You might try to use URL::to like this:
<a href="{{ URL::to($lingua. '/'. $campo->id_campo. '/'. $categoria->id_cat) }}">

Related

Weird Livewire + Turbolinks behavior

I'm building an admin panel in TALL (Laravel 7) + Turbolinks. One section only includes a Livewire component that shows a paginated table of Product elements and a search field (the only "strange" thing that I'm doing before this is injecting a Market model instance to the request in a middleware).
The problem arises when I go to /products route where is the livewire component included nothing works... The records of the first page are fine, but pagination links are dead and search field does nothing, no console errors, no livewire errors, it's like javascript is not working at all, and here's the strangest thing: if I reload the page, the Market data I loaded in middleware is added to the query string and everything starts working as intended.
Middleware:
public function handle($request, Closure $next) {
$market = Market::findOrFail(session('selected_market'));
$request->request->add(['market' => $market]);
return $next($request);
}
Livewire Component:
class ProductsTable extends Component{
use WithPagination;
public $search = '';
protected $queryString = [
'search' => ['except' => ''],
'page' => ['except' => 1],
];
public function render(){
$products = Product::where('market_id', request('market')->id)
->when($this->search !== '', function($query) {
$query->where('name', 'like', "%{$this->search}%");
$query->orWhere('brand', 'like', "%{$this->search}%");
})->paginate(15);
return view('livewire.products-table', ['products' => $products]);
}
}
Livewire Component View:
<input wire:model.debounce.500ms="search" type="search" name="search" id="search">
<table>
#forelse($products as $product)
<tr onclick="Turbolinks.visit('{{ route('product', $product->id) }}')">
<td>{{ $product->name }}</td>
...
</tr>
#empty
<tr><td>Nothing to show for {{ $search }}</td></tr>
#endforelse
</table>
{{ $products->links() }}
I'm really confused and tired with this, I have no clue what is going on and similar questions haven't been answered clearly.
Thanks
The solution was as simple as adding this to your scripts:
document.addEventListener("turbolinks:load", function(event) {
window.livewire.restart();
});

laravel display data on a page based on id

I have a page that shows links with name of businesses that are retrieved in database like this:
Controller:
public function viewBusiness() {
// Return our "website" object
$business = Business::all();
// Pass the contents of the "html" property to the view
return view('viewBusiness', ['business' => $business]);
}
View:
#extends('master') #section('title', 'Live Oldham') #section('content')
#section('content')
#foreach ($business as $businesses)
<a target="_blank" href="{{ url('business/' . $businesses->name) }}"> {{($businesses->name) }}
</a> #endforeach
#endsection
Route:
Route::get('business/list', 'BusinessController#viewBusiness')->name('viewBusiness');
I then have added a function where user click on a link and it is taken to a page which displays all data for that specific business, however it diplays all data but for all businesses.
Controller:
function displayBusiness() {
$business = Business::all();
$address = Address::all();
return view('displayBusiness', ['business' => $business, 'address' => $address]);
}
View:
#foreach ($business as $businesses)
<p>{{$businesses->name}}</p>
<p>{{$businesses->email}}</p>
#endforeach
#foreach ($address as $addresses)
<p>{{$addresses->firstline_address}}</p>
<p>{{$addresses->secondline_address}}</p>
<p>{{$addresses->town}}</p>
<p>{{$addresses->city}}</p>
<p>{{$addresses->postcode}}</p>
<p>{{$addresses->telephone}}</p>
#endforeach
Route:
Route::get('business/{name}', 'BusinessController#displayBusiness')->name('displayBusiness');
Now here's the question, how can this code be modified so only a business that match either bussiness->name or business->id is displayed. (I guess name is taken when user clicks on a name.
Another question is how to restrict the url so that if localhost/business/{name} is not equal to any business->name in the database returns error? at the moment it shows the page no matter what you enter.
Thanks!
I do not know if I understood the question, but that may be the beginning of a solution ...
First view :
#extends('master') #section('title', 'Live Oldham')
#section('content')
#foreach ($business as $businesses)
<a target="_blank" href="{{ url('business/' . $businesses->id) }}"> {{($businesses->name) }}
</a> #endforeach
#endsection
Second Controller :
function displayBusiness($id) {
$business = Business::find($id);
$address = Address::find($id);
return view('displayBusiness', compact('business', 'address'));
}
Second View :
<p>{{$business->name}}</p>
<p>{{$business->email}}</p>
<p>{{$address->firstline_address}}</p>
<p>{{$address->secondline_address}}</p>
<p>{{$address->town}}</p>
<p>{{$address->city}}</p>
<p>{{$address->postcode}}</p>
<p>{{$address->telephone}}</p>
Second Route :
Route::get('business/{id}', 'BusinessController#displayBusiness')->name('displayBusiness');
Route parameters are available in the controller function as parameters. Now you can build a query with this function. If your query does not return any results, you can send the user back to the business overview.
function displayBusiness($name) {
$business = Business::where('name', $name)->orWhere('id', $name)->first();
if ($business === null)
{
// No business with this name or id found.
// Redirect to businesses list page.
}
$address = Address::all();
return view('displayBusiness', ['business' => $business, 'address' => $address]);
}

Passed data lost in Laravel paginator starting from page 2

I am trying to list people by their appRole. Here's the controller:
public function indexByAppRole(Request $request, $appRoleId)
{
$h1 = AppRole::where('id', $appRoleId)->first()->name;
return view('admin.people.index', [
'people' => $this->people->byAppRole($appRoleId),
'appRoles' => $this->appRoles->forAll(),
'h1' => 'Role: '. $h1,
]);
}
Paginator is used in the repository:
public function byAppRole($appRoleId)
{
return Person::where('person_app_role.app_role_id', $appRoleId)
->join('person_app_role', 'person_app_role.person_id', '=', 'people.id')
->select('people.*') // fix ID confusion but why?
->paginate(20);
}
The main view lists the returned people. In the sidebar, I have the following list as side-navigation:
<ul class="list-group nav nav-pills nav-stacked">
#foreach ($appRoles as $appRole)
<li>
{{ str_plural($appRole->name) }}
</li>
#endforeach
</ul>
The navigation list works on page 1 of search results or listings, but the list is not showing up on page 2 and subsequent pages. What did I do wrong?
I solved the problem. For AppRole, I also used a paginator, so this was fixed by using all() instead of paginate() to get all appRoles.
// Before...........
public function forAll()
{
return AppRole::paginate(20);
}
And:
// After............
public function forAll()
{
return AppRole::all();
}

NotFoundHttpException Laravel

I am very new in learning Laravel. I want to fetch data from a database and show it. I can do it. But I want to use the title (fetched from the database) as a link. but then I get a NotFoundHttpException.
Routes
Route::get('articles', 'ArticleController#index');
Route::get('articles/{id}', 'ArticleController#show');
Controller
class ArticleController extends Controller
{
public function index()
{
$articles = Article::all();
return view('articles.index', compact('articles'));
}
public function show($id){
$article = Article::find($id);
return view('articles.show', compact('article'));
}
}
View
#extends('new_welcome')
#section('content')
<h1>Articles</h1>
#foreach($articles as $article)
<article>
<h2>
{{$article->title}}
</h2>
<div class="body">{{ $article->body}}</div>
</article>
#endforeach
#stop
Can someone help me in this case?
Your problem is because of You've "eat" one curly brace (blade engine skips it):
was:
href="{url ('/articles',$article->id)}"
have to be:
href="{{url ('/articles',$article->id)}}"
as You said:
if I click on any single article title then it can not show me the
specific article. But, if I give the URL "homestead.app/articles/2";
so You can see that when You click on link Your browser's address bar becomes:
homestead.app/{url ('/articles',$article->id)}
Because You're beginner so I'll give You advice to not to set direct url in views using url() helper.
Named routes are better if You want to have app that will work properly if in future You decide to change url from: articles to artcls. In this named routes will save You from bulk changing urls in view files.
set name to Your route using 'as' directive that makes Your routing flexible for changes (when You need to change URL so You change only path and keep views unchanged):
Route::get('articles/{id}', ['as' => 'article', 'uses' => 'ArticleController#show']);
Route::get('articles', ['as' => 'articles', 'uses' => 'ArticleController#index']);
change Your view file (find route helper in href):
#extends('new_welcome')
#section('content')
<h1> Articles </h1>
#foreach($articles as $article)
<article>
<h2>
{{$article->title}}
</h2>
<div class="body">{{ $article->body}}</div>
</article>
#endforeach
#stop

search form using laravel shows 'Call to a member function getNumCommentsStr() on a non-object'

i have made a search bar using laravel, but it did not succeed. it shows the error as said below. And it seems that something wrong with my post object. But i do not know where.
source code as follows, thanks for helping.
//the searchController for seach code
public function search(){
$keyword = Input::get('keyword');
if(empty($keyword)){
return Redirect::route('/');
//->with('message',array('type' => 'alert', 'content' => '不能为空'))
}
$posts = Post::where('content', 'like', '%'.$keyword.'%')->orderBy('created_at', 'desc')->paginate(10);
$tags = Tag::where('count','>','0')->orderBy('count','desc')->orderBy('updated_at', 'desc')->take(20)->get();
return Redirect::route('searchResults')->with('posts', $posts->toArray())->with('tags',$tags);
}
public function searchResults(){
return View::make('frontend.search.search',['posts' => Session::get('posts'),'tags' => Session::get('tags')]);
}
//search bar route
Route::get('/searchResults', array(
'uses' => 'SearchController#searchResults',
'as' => 'searchResults'
));
Route::post('/search', array(
'before' => 'csrf',
'uses' => 'SearchController#search',
'as' => 'search'
));
//search from
{{ Form::open(array('url'=>'/search','method' => 'post','class'=>''))}}
{{ Form::token()}}
<label for="docSearch">
<i class="fa fa-search"></i>
</label>
<div class="searchInput">
{{Form::text('keyword', '', array('class'=>'docsSearch', 'placeholder'=>'搜索论坛动态...'))}}
{{ Form::submit('提交',array('class'=>''))}}
{{Form::close()}}
//now i just wanna to get it like this:
#if(!$posts)
{{'<section class="oneQuestion">sorry,no content...</section>'}}
#else
#foreach($posts as $post)
<section class="oneQuestion">
<div class="askResult">
<!-- <i class="fa fa-question notSolved"></i>
<i class="fa fa-check solved" style="display:none;"></i> -->
#if($post->getNumCommentsStr() == 0)
<a href="{{URL::route('viewPost', array('id' => $post->id))}}#reviews" class="notSolved"><span class="post_comment_Num">{{$post->getNumCommentsStr()}}</span>
<span> 回答</span>
</a>
#else
<a href="{{URL::route('viewPost', array('id' => $post->id))}}#reviews" class="solved"><span class="post_comment_Num">{{$post->getNumCommentsStr()}}</span>
<span> 回答</span>
</a>
#endif
</div><!--
--><div class="titlePart">
<span>
{{$post->user->username}}
{{$post->created_at->diffForHumans()}}
</span>
<a href="{{ URL::route('viewPost', $post->id)}}">
{{-- {{ substr($post->content,0,200) }}... --}}
{{$post->title}}
</a>
<div class="tagWrapper">
#foreach ($post->tags as $tag)
<span class="askTag" title="">{{$tag->name}} </span>
#endforeach
</div>
</div>
</section>
#endforeach
#endif
<div class="forumLink">
{{$posts->links()}}
</div>
//it showed me an error:
**Call to a member function getNumCommentsStr() on a non-object**
and my getNumCommentsStr like:
public function getNumCommentsStr()
{
$num = $this->reviews()->count();
// if($num == 1){
// return "1";
// }
return $num;
}
code seems a lot but i wanna to make it clear so you can find any errors. Thanks again.
Edit 2
Thanks for NightMICU's suggest and I change
Redirect::route('searchResults')->with('posts', $posts->toArray())->with('tags',$tags);
to the following:
Redirect::route('searchResults')->with('posts')->with('tags',$tags);
THE result is without any alert any more, it just shows: sorry, no content...
And did not show any search result, any problem? Thanks
EDIT TWO
//delete the searchResult method, all in one search method so that i can return the view in right in the search method.
public function search(){
$keyword = Input::get('keyword');
if(empty($keyword)){
return Redirect::route('developer');
//->with('message',array('type' => 'alert', 'content' => '不能为空'))
}
$posts = Post::where('content', 'like', '%'.$keyword.'%')->orderBy('created_at', 'desc')->paginate(10);
$tags = Tag::where('count','>','0')->orderBy('count','desc')->orderBy('updated_at', 'desc')->take(20)->get();
return View::make('frontend.search.search',['posts' => $posts,'tags' => $tags]);
}
EDIT 3
there are two questions exsiting here.
ONE is that when i change to that ,it can output the result but all the result the database has. Not the keyword results.
Two is that when there are extra page, once i open the link http://localhost/html5lav/public/search?page=2, it just show an error:
No query results for model [Post].
The initial issue most likely has to do with the unusual way you are displaying the search results; by passing the Eloquent collections via session to another method, only to display the View. You were also converting the Post Eloquent collection to a regular array with ->toArray(), pagination requires a collection rather than an array.
The solution for that part:
public function search(){
$keyword = Input::get('keyword');
if(empty($keyword)){
return Redirect::route('/');
//->with('message',array('type' => 'alert', 'content' => '不能为空'))
}
$posts = Post::where('content', 'like', '%'.$keyword.'%')->orderBy('created_at', 'desc')->paginate(10);
$tags = Tag::where('count','>','0')->orderBy('count','desc')->orderBy('updated_at', 'desc')->take(20)->get();
return View::make('frontend.search.search')->with('posts', $posts)->with('tags', $tags);
}
After taking care of the initial issue, you reported that the pagination links are not working as expected - you click on Page 2 and do not have any Post results. If the route for the page where the user inputs a search term is also /search, there is a conflict. Instead, change the route that the search form posts to, perhaps /searchResults (which then loads the results using the search method). You may also want to consider using a GET rather than POST request, allowing users to bookmark their search results or share a link.
Regarding the issue of displaying all of the entries from the posts table, you need to review MySQL raw queries in Laravel. Swing by the documentation and look them up.

Resources