Eduardo Fuerte
asked on
Could you point how to refresh data at a Laravel view when data to be presented changes ?
Hi Experts
Could you point how to refresh data at a Laravel view when data to be presented changes ?
When the page is initially presented it shows all the images.
Then a filter is applied and the collection to be presented is much smaller. The view is called the same way it was for all the images, but the images presented are not actualized.
If the view is started with the data filtered it's correctly presented.
Thanks in advance.
Could you point how to refresh data at a Laravel view when data to be presented changes ?
When the page is initially presented it shows all the images.
Then a filter is applied and the collection to be presented is much smaller. The view is called the same way it was for all the images, but the images presented are not actualized.
If the view is started with the data filtered it's correctly presented.
Thanks in advance.
ASKER
Hi Chris
Still not considering what you posted about relationships at the precedent question.
Here is the data presented when the user opens the view (all the images)
Then when the user applies the filter, the result of the filtered data showed by info is correct. If I use this right of the start the data presented is OK, indeed just one image.
I guess the AJAX code must to run after the Filter button isn't it?
Still not considering what you posted about relationships at the precedent question.
Here is the data presented when the user opens the view (all the images)
$vitrinesX = Vitrine
::with('user_vitrine')
->ativa()
->aprovada()
->global(Auth::user()->tipoparticipante_id)
->orderBy('id','desc')
->withCount([
'user_vitrine as qtdeCurtiu' => function (Builder $query) { $query->where('curtiu', 1); },
])
->paginate(6);
return view('vitrines.index',compact('vitrinesX', 'vitrine','qtdeCurtiu','qtdeNaoCurtiu','curtiu'));
Then when the user applies the filter, the result of the filtered data showed by info is correct. If I use this right of the start the data presented is OK, indeed just one image.
$vitrinesX = auth()->user()
->vitrines()
->with('user_vitrine')
->ativa()
->aprovada()
->global(Auth::user()->tipoparticipante_id)
->orderBy('id','desc')
->withCount([
'user_vitrine as qtdeCurtiu' => function(Builder $query) { $query->where('curtiu', 1); },
])
->paginate(3);
return view('vitrines.index',compact('vitrinesX', 'vitrine','qtdeCurtiu','qtdeNaoCurtiu','curtiu'));
I guess the AJAX code must to run after the Filter button isn't it?
<div class='col-md-4 pull-right'>
<div class="btn-group" role="group">
<button type="button" class="btn btn-primary" onclick="hotsite.vitrine.novo();">
<i class="fas fa-video" aria-hidden="true"></i> Todas as Fotos
</button>
</div>
</div>
Vitrine.prototype.minhasfotos = function(){
$.ajax({
url: '/vitrine/minhasfotos',
method: "GET",
dataType: "html",
error:function(data){
hotsite.openModalCustom("Erro", "Erro ao carregar vitrine.", "Entendi", "error");
},
success: function(data){
$('#midiaList').html(data);
}
});
}
I can't see a connection between your HTML and you Javascrip. Your HTML is firing a function called novo, but your javascript shows a funcrtion called minhasfotos. What's the connection between the 2.
If you're wanting to update the content after an AJAX call, then your server will need to responsd with only part of the final HTML - not a full page.
If you're wanting to update the content after an AJAX call, then your server will need to responsd with only part of the final HTML - not a full page.
ASKER
Sorry. I had copyed from the worng place. Here it is:
And the controller method that filters the data:
And the page part that must to be actualized:
<div class='col-md-4 pull-right'>
<div class="btn-group" role="group">
<button type="button" class="btn btn-primary" onclick="hotsite.vitrine.minhasfotos();">
<i class="fas fa-video" aria-hidden="true"></i> Minhas Fotos
</button>
</div>
</div>
And the controller method that filters the data:
public function minhasFotos(Request $request){
$curtiu = 0;
$vitrinesX = auth()->user()
->vitrines()
->with('user_vitrine')
->ativa()
->aprovada()
->global(Auth::user()->tipoparticipante_id)
->orderBy('id','desc')
->withCount([
'user_vitrine as qtdeCurtiu' => function(Builder $query) { $query->where('curtiu', 1); },
])
->paginate(3);
info($vitrinesX);
return view('vitrines.index',compact('vitrinesX', 'vitrine','qtdeCurtiu','qtdeNaoCurtiu','curtiu'));
}
And the page part that must to be actualized:
<div class='row'>
<input type="hidden" id="hdnCurtiu" value="{{$curtiu}}">
<div class="col-md-12 col-sm-12">
<section class="row">
@foreach($vitrinesX->chunk(3) as $row)
@foreach($row as $vitrine)
<div class="col-sm-12 col-md-4">
@php
$vitrine->liked_by= $vitrine->user_vitrine->pluck('id');
$currentUserId = auth()->user()->id;
$hasUserVoted = $vitrine->liked_by->contains($currentUserId);
@endphp
<div class="box-noticias">
<a href="javascript:void(0);" onclick='hotsite.vitrine.abrirVitrine({{$vitrine->id}});' >
<img src="{{ $vitrine->url }}">
</a>
</div>
<p id="like" class="likes" @if (!$hasUserVoted ) onclick="hotsite.vitrine.salvarEscolha({{ $vitrine->id }}, 1, this)" @endif>
<i class="fa fa-thumbs-up"></i> <span id="qtdeCurtiu_{{ $vitrine->id }}">{{ $vitrine->qtdeCurtiu }}</span>
</p>
</div>
@endforeach
@endforeach
</section>
<div class='col-md-6 pull-right'>
{{ $vitrinesX->links() }}
</div>
</div>
</div>
OK. You will need to make sure that your controller method is only returning the part that you want to update - already rendered. Currently you've got this:
return view('vitrines.index', ...
You need to make sure that that view you return is only the necessary part of the page and that you call render() on it:
return view('vitrines.index', ...
You need to make sure that that view you return is only the necessary part of the page and that you call render() on it:
return view('partialtemplate',compact('vitrinesX', 'vitrine','qtdeCurtiu','qtdeNaoCurtiu','curtiu'))->render();
ASKER
Hey Eduardo,
It just a standard blade template, the same as any other, but instead of being a full HTML page, it just contains the HTML that you need (i.e it's just returning a partial bit of HTML)
It just a standard blade template, the same as any other, but instead of being a full HTML page, it just contains the HTML that you need (i.e it's just returning a partial bit of HTML)
ASKER
If I well understood...
I must to create under \views\layout\
(where the templates remains at my project)
Another layout with the loop part above at the code - and then extend it at the existent view, isn't it?
I must to create under \views\layout\
(where the templates remains at my project)
Another layout with the loop part above at the code - and then extend it at the existent view, isn't it?
ASKER
I mean
Copy this part of the view:
to a file fotos.blade.php (f.e.)
And then change this code at the actual view with:
@extends('layouts.fotos')
Ans then at the Controller
Is it correct?
Copy this part of the view:
<div class='row'>
<input type="hidden" id="hdnCurtiu" value="{{$curtiu}}">
<div class="col-md-12 col-sm-12">
<section class="row">
@foreach($vitrinesX->chunk(3) as $row)
@foreach($row as $vitrine)
<div class="col-sm-12 col-md-4">
@php
$vitrine->liked_by= $vitrine->user_vitrine->pluck('id');
$currentUserId = auth()->user()->id;
$hasUserVoted = $vitrine->liked_by->contains($currentUserId);
@endphp
<div class="box-noticias">
<a href="javascript:void(0);" onclick='hotsite.vitrine.abrirVitrine({{$vitrine->id}});' >
<img src="{{ $vitrine->url }}">
</a>
</div>
<p id="like" class="likes" @if (!$hasUserVoted ) onclick="hotsite.vitrine.salvarEscolha({{ $vitrine->id }}, 1, this)" @endif>
<i class="fa fa-thumbs-up"></i> <span id="qtdeCurtiu_{{ $vitrine->id }}">{{ $vitrine->qtdeCurtiu }}</span>
</p>
</div>
@endforeach
@endforeach
</section>
<div class='col-md-6 pull-right'>
{{ $vitrinesX->links() }}
</div>
</div>
</div>
to a file fotos.blade.php (f.e.)
And then change this code at the actual view with:
@extends('layouts.fotos')
Ans then at the Controller
return view('fotos',compact('vitrinesX', 'vitrine','qtdeCurtiu','qtdeNaoCurtiu','curtiu'))->render();
Is it correct?
Not quite.
You don't need to extend anything - you just need your AJAX request to return only a PART of your HTML view, so just return the fotos template.
You don't need to extend anything - you just need your AJAX request to return only a PART of your HTML view, so just return the fotos template.
ASKER
Hard to me to follow what you means...
At Controller
How to define this partialtemplate (where remains the HTML photos) at the code?
The AJAX code:
I couldn't link the parts...
At Controller
return view('partialview',compact('vitrinesX', 'vitrine','qtdeCurtiu','qtdeNaoCurtiu','curtiu'))->render();
How to define this partialtemplate (where remains the HTML photos) at the code?
The AJAX code:
Vitrine.prototype.minhasfotos = function(){
$.ajax({
url: '/vitrine/minhasfotos',
method: "GET",
dataType: "html",
error:function(data){
hotsite.openModalCustom("Erro", "Erro ao carregar vitrine.", "Entendi", "error");
},
success: function(data){
$('#midiaList').html(data);
}
});
}
I couldn't link the parts...
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hi Chris
It makes all the sense.
It's just a matter of to use an @include.
I just created another view called: fotos.blade.php with the content of the foreach etc. above.
Then changes on the view:
And at the Controller:
And so... now it's running!
It makes all the sense.
It's just a matter of to use an @include.
I just created another view called: fotos.blade.php with the content of the foreach etc. above.
Then changes on the view:
<div class='row'>
<div id="midiaList">
@include('vitrines.fotos')
</div>
</div>
And at the Controller:
return view('vitrines.fotos',compact('vitrinesX','curtiu'))->render();
And so... now it's running!
Excellent. So now when your page first runs it will include the vitrines.fotos template, and then when your AJAX call is made, it will reload just that template and replace the content on #midiaList.
Good stuff :)
Good stuff :)
ASKER
Chris
Thank you for another very elucidative solution!
My Laravel's knowledge is growing thanks for your help...Sometimes I feel Laravel as "another PHP" inside PHP...
Thank you for another very elucidative solution!
My Laravel's knowledge is growing thanks for your help...Sometimes I feel Laravel as "another PHP" inside PHP...
Haha - I know what you mean. It certainly has some quirks but when it makes sense, it's much easier to develop applications. It uses fairly modern design patterns to do the jon, and these design patterns are often very different from how many developers are used to writing code.
At it's core, it take an Object Oriented Programming (OOP) approach. If you understand how OOP development works, then using Laravel will make much more sense. OOP is not specific to any language - it's just a concept on how to program, so if you have some spare time, it might help to read up a little about the concepts behind OOP.
Good luck with it
At it's core, it take an Object Oriented Programming (OOP) approach. If you understand how OOP development works, then using Laravel will make much more sense. OOP is not specific to any language - it's just a concept on how to program, so if you have some spare time, it might help to read up a little about the concepts behind OOP.
Good luck with it
You have a few choices here, depending on how you've implemented the Filter function.
You could just make another request to the server (effectively re-loading the page). You could make an AJAX call to the server and re-populate the page once you have a response (reduced list of images). You just just use some Javascript to hide the images that don't match the filter.
Will need more info before giving you any specific answers.