send ajax request to laravel controller to download a pdf - javascript

I have table with a column for checkbox, When a certain button is clicked i send checked checkboxs with ajax request to a controller to download a pdf file after it has been made ,but unfortunately it doesn't fire the download box .i hope you help me out.
My Ajax :
<script>
$(document).ready(function()
{
$(document).on('click', '#minvoice', function(event)
{
//var alert = confirm('Are You Sure?');
var checkedValues = $('#chkbx:checked').map(function() {
return this.value;
}).get();
$.post('{{route('payments.multiple_invoices')}}', {'checkboxs' : checkedValues, '_token' : $('input[name=_token]').val() }, function(data){
console.log(data);
});
});
});
</script>
My Controller :
public function multiple_invoices(Request $request)
{
if ($request->isMethod('post'))
{
//export invoice
$requestData[] = $request->checkboxs;
$filenamepdf = public_path().'/export/invoices/multiple_invoices.pdf';
$data = self::getMulInvoiceData($requestData);
PDFHelper::export($data, $filenamepdf, true);
return Response::download($filenamepdf, 'Multiple_invoice_'.date('Y-m-d').'_'. time().'.pdf', []);
}
}
public static function getMulInvoiceData($requestData)
{
$payments = UnitPayment::whereIn('id', $requestData)->get();
return View::make('payments.mulInvoice', compact('payments'));
}
My Views:
<td><input id="chkbx" type="checkbox" value="{{ $payment->id }}" /></td>
MulInovices.blade.php :
#foreach($payments as $payment)
<div align="left" style="text-align: left;"><b>payment : {{$payment->id}} </b></div>
#endforeach
My Route:
Route::any('payments/multiple_invoices', ['uses' => 'PaymentsController#multiple_invoices','as' => 'payments.multiple_invoices']);
i hope you tell me how to get this to work . thanks

Try changing
return Response::download($filenamepdf, 'Multiple_invoice_'.date('Y-m-d').'_'. time().'.pdf', []);
to
return Response::download($filenamepdf, 'Multiple_invoice_'.date('Y-m-d').'_'. time().'.pdf', ['Content-Type' => 'application/pdf']);
(Difference is code below is added in to third parameter [] of Response::download)
'Content-Type' => 'application/pdf'
If you are using Laravel 5+ you can use code below
response()->($filenamepdf, 'Multiple_invoice_'.date('Y-m-d').'_'. time().'.pdf', ['Content-Type' => 'application/pdf']);
What we did is add headers to recognise response as a pdf file.

Related

Send array to controller by Ajax call, then controller return another View with that array in Laravel

I am passing array to controller by ajax. Controller is accessing array and return response successfully. But I want that when controller get array it return different view(suppose A.blade.php) and I can use that array in A.blade.php.
I have seen many replies like use window.location="url" in success:function(){} but it will only go to view without array.
Only purpose is to pass array to controller and controller return another view with array and i don't need of response.
AJAX function
$(function(){
$('#but').click(function() {
alert("Button Click");
;
$.ajax({
type: 'get',
url: '/suck',
data: {arr},
success: function( data ) {
document.getElementById("p").innerHTML =data;
},
error: function(xhr, status, error) {
alert(error);
},
dataType: 'text'
});
});
});
Controller
public function getAjax(Request $req)
{
$input=$req->all();
// Here I want when controller access array it return another view with array and no need of response
return response()->json($input);
}
Routes.web.php
Route::get('/suck',[ajaxcontroller::class,'getAjax']);
Based on your comments, you could dynamically create a form and add the array you want to a hidden element. Then submit the form.
Untested code:
$(function()
{
$('#but').click (
function()
{
var myArray = [];
var myJson = JSON.stringify(myArray);
var myForm = $(document.createElement('form'));
$(myForm).attr("action", "/url/to/controller");
$(myForm).attr("method", "POST");
var input = $("<input>").attr("type", "hidden").attr("name", "myArray").val(myJson);
$(form).append($(input));
$(form).submit();
}
);
}
);
To send an array from view to controller and from controller to other view:
First create a form and use onsubmit attribute
<form id="myid" action="/go" method="post" onsubmit="submitForm(event)">
#csrf
<input type="submit" value="submit">
</form>
Then write function for onsubmit
<script type="text/JavaScript">
function submitForm(event){
var arr=["Tile","Desk","Door"]; // Array which has to pass to controller
var i;
for(i=0;i<arr.length;i++){ // create and append arr.length times
var input = $("<input>").attr("type", "hidden").attr("name", "myArray["+i+"]").val(arr[i]);
$(myid).append($(input)); // append to form
}
this.submit();
}
</script>
Routes
Route::post('/go',[subcontroller::class,'getArray']);
In Controller
class subcontroller extends Controller
{
public function getArray(Request $req)
{
$arr=$req->get('myArray');
return view('viewName',['set'=>$arr]);
}
}
In blade.view, access array as
#foreach($set as $item)
<div>{{$item}}</div>
#endforeach
It worked for me.

Laravel download xls file with AJAX

I can't download my XLS file via Ajax
function downloadFile(response) {
var blob = new Blob([response], {type: 'application/vnd.ms-excel'})
var url = URL.createObjectURL(blob);
location.assign(url);
}
$('#export').click(function () {
$.ajax({
type: 'POST',
url : 'factures/engagements/selected/export',
headers: {'X-CSRF-TOKEN': '{{ csrf_token() }}' },
dataType: "json",
data : {
checkboxes : checkboxValues
}
}).done(downloadFile);
});
my controller :
public function exportFacturesEngagementSelected(Request $request){
$checkboxes = $request->input('checkboxes');
$collection = collect($checkboxes);
$engagements = EngagementOrder::whereIn('id' , $collection)->get();
$date = Carbon::now('Europe/Paris')->format('d-m-Y H:i:s');
$output = Excel::create('factures_engagements' . $date. '', function($excel) use ($engagements) {
$excel->sheet('Excel', function($sheet) use ($engagements) {
$sheet->loadView('engagements.exportExcelSelected')->with("engagements", $engagements);
});
})->export('xls');
return $output;
}
I only get the output preview of the file in my console network, but nothing happens in my browser; no file is downloaded. What am I doing wrong?
UPDATE #matticustard solution :
my checkboxValues is a json for exemple the result is
{920: "920", 927: "927", 931: "931", 939: "939"}
when i console log query i get :
undefinedcheckboxes=920&checkboxes=927&checkboxes=931&checkboxes=939&
When i try to get the values to my controller i made a $request->all() and i get :
array:2 [
"undefinedcheckboxes" => "920"
"checkboxes" => "939"
]
why i get undefinedcheckboxes and why i don't get the other ids ?
Try this
if your ajax success
location.href = path/to/file/property_title.xls
change this line
->export($type);
with
->store($type, 'public/reports/', true);
These days I've used this package
(my recommendation) for converting my model's collections to XLS and export that.
As I understand, you want to download the file via AJAX. I didn't got you at all, but I just can share my experience for helping you. This working with a normal POST request, but it will not refresh your page anyway.
So this is a working example:
In Controller
public function export(Request $request)
{
$data = $request->get('data'); // get incoming data field
return \Excel::download(new ExcelService($data), "custom-file-name-with-extension.xls");
}
In Service (or you can implement this in controller too)
namespace App\Services;
use App\Models\Item;
use Maatwebsite\Excel\Concerns\FromCollection;
class ExcelService implements FromCollection
{
protected $data = null;
public function __construct($data)
{
$this->data = $data;
}
public function collection()
{
$items = Item::where('data', $data)->get(); // some query using incoming $data
return $items;
}
}
Route
Route::post('export', 'ItemController#export')->name('export');
There's really no reason to use AJAX or store the file. You can pass the checkbox data as parameters in the URL with a GET request and use an <iframe> to download the file. I guessed at the controller name, so adjust as necessary.
web.php
Change the route to GET.
Route::get('factures/engagements/selected/export', 'FactureController#exportFacturesEngagementSelected')->name('export');
JavaScript function and handler
Serialize the data as expected by your controller and make the request.
I guessed that checkboxValues was an array of values based on the actions taken in your controller. But you could serialize the form directly var query = $('form').serialize(); and adjust the controller to match the input.
function downloadFile() {
var query;
$.each(checkboxValues, function(index,value) {
query += 'checkboxes=' + value + '&';
});
$('<iframe />')
.attr('src', '/factures/engagements/selected/export?' + query)
.hide()
.appendTo('body');
}
$('#export').click(function () {
downloadFile();
});
FactureController.php
And use the download method in your controller.
// ...
->download('xls');

Datepicker is not a function after ajax request

I'm writing simple search engine in Lumen framework.
I have a list of status for example. The user can get one of status from the list and after click search button then in the page, I need to load data with chosen status.
One of the element is datepicker. And this datepicker work great when I refresh the page or go to the page by GET method. But I have a problem when I go on the page by POST method from my click "SEARCH". There is some code from my view where I get status from the list and pass to my controller action:
<script type="text/javascript">
jQuery(document).ready(function ($) {
var clientId = null;
var status = null;
$("[name='deadline']").datepicker(); //there I have this error comunicat
$('#clients').on('change', function () {
clientId = $(this).val();
});
$('#statuses').on('change', function () {
status = $(this).val();
});
$('#searchForPremium').on('click', function () {
$.ajax({
type: 'POST',
url: '/admin/clients/premium',
data: {client_id: clientId, status: status},
success: function (data) {
$('body').empty().html(data);
$('#clients').val(clientId);
$('#statuses').val(status);
}
});
})
});
</script>
And there is controlelr action:
public function clientsPremium()
{
$premiumTexts = NULL;
$premiumClients = \App\Text::getPremiumClients();
$premiumTexts = \App\Text::getPremiumTexts();
$statuses = \App\Text::getStatus();
if (Request::isMethod('get')) {
$premiumTexts = $premiumTexts->orderBy(DB::raw('ISNULL(deadline), deadline'), 'ASC');
$premiumTexts = $premiumTexts->get();
return view('admin.clients-premium', ['statuses' => $statuses, 'clients' => $premiumClients, 'texts' => $premiumTexts]);
}
if (Request::isMethod('post')) {
$clientID = Request::get('client_id');
$statusName = Request::get('status');
if ($clientID != NULL) {
$premiumTexts = $premiumTexts->where('text.client_id', $clientID);
}
if ($statusName != NULL) {
$premiumTexts = $premiumTexts->where('text.status', $statusName);
}
$premiumTexts = $premiumTexts->orderBy(DB::raw('ISNULL(deadline), deadline'), 'ASC');
$premiumTexts = $premiumTexts->get();
return response()->json(view('admin.clients-premium', ['statuses' => $statuses, 'clients' => $premiumClients, 'texts' => $premiumTexts])->render());
}
}
Then I have error "Uncaught TypeError: $(...).datepicker is not a function...". I cant understand how it is work and why I got this message. It appear only when I click to search button.
It is $('body').empty().html(data); or my controller action:
return response()->json(view('admin.clients-premium', ['copywriters' => $copywriters, 'statuses' => $statuses, 'positioners' => $positioners, 'clients' => $premiumClients, 'texts' => $premiumTexts, 'allowedTemplates' => $allowedTemplates, 'section' => 'clients.premium'])->render());
I tried to use $.noConflict(); but there is no effect for me. Can anyone look at my code and try to help me what should I change? I think my return "response()->json(view..." reload all page and get my jquery-ui multiple time. But I can wrong. Can anyone help me?
Reinitialize it after you change content from ajax response.
$.ajax({
type: 'POST',
url: '/admin/clients/premium',
data: {client_id: clientId, status: status},
success: function (data) {
$('body').empty().html(data);
$("[name='deadline']").datepicker();
$('#clients').val(clientId);
$('#statuses').val(status);
}
});
After ajax success destroy the datepicker and reinitialize it as below:
$('body').empty().html(data);
$("[name='deadline']").datepicker("destroy");
$("[name='deadline']").datepicker();
you clear entire body so may be possible you include js css in body so please add and remove this div instead of entire body and if you add dynamic datepicker to any text box please use
$("[name='deadline']").datepicker(); on ajax response .

Select onChange Table blade view

UPDATE : now when i change the poule_id i get a blank table with nothing inside , when i go directly to the url like :
https://mydomaine.eu/go/public/competition/search/equipes?poule_id=2
i get :
table "\n\n\n\n\n"
I try to make a function who change the result of my blade table who display equipes(teams) with a select box but nothing happen at the moment i don't know where i did a mistake , it's maybe in the javascript code
Hope someone could help to fix that , thanks a lot in advance
I try to change my table depending on poule_id with a select box like this :
<select id="poule">
#foreach($select_poules as $select_poule)
<option value="{{$select_poule->id}}">{{$select_poule->lb_poule}}</option>
#endforeach
</select>
My table contain the teams who depend on a poule_id :
#foreach($equipes as $equipe)
<tr>
<td>
{{$equipe->equipe->structure->nom_structure}}
</td>
<td>
{{$equipe->equipe->lb_equipe}}
</td>
<td>
{!! Form::text('nb_bonus') !!}
</td>
</tr>
#endforeach
Here my controller :
public function searchEquipes(Request $request)
{
if ($request->has('poule_id')) {
$equipes = EquipePoule::where('poule_id' , $request->poule_id)->get();
$competition = Compet::where('id' , 1)->first();
$categorie_compet = CategorieCompet::pluck('lb_categorie_compet' , 'id');
$categorie_age = CatgEquipe::pluck('lb_catg_equipe' , 'id');
$structure_rattachement = Structure::select('num_structure', 'nom_structure' , 'id')
->where('type_structure_id' , '1')
->orWhere('type_structure_id' , '2')
->orWhere('type_structure_id' , '3')
->get()
->mapWithKeys(function($i) {
return [$i->id => $i->num_structure.' - '.$i->nom_structure];
});
$poules = Poule::where(['compet_id' => $competition->id])->get();
$rencontres = Rencontre::where(['compet_id' => $competition->id])->orderBy('dt_rencontre' , 'DESC')->get();
$designations = RencontreOfficiel::where(['compet_id' => $competition->id])->get();
$classements = Classement::where(['compet_id' => $competition->id])->orderBy('nb_point_classement' , 'DESC')->get();
$equipe_to_select = Equipe::select('lb_equipe', 'structure_id' , 'catg_equipe_id' ,'id')
->get()
->mapWithKeys(function($i) {
return [$i->id => $i->lb_equipe.' - '.$i->structure->nom_structure.' - ' .$i->catg_equipe->lb_catg_equipe];
});
$stade = Stade::select('lb_nom', 'ville_stade' , 'cd_post_stade' , 'id')
->get()
->mapWithKeys(function($i) {
return [$i->id => $i->lb_nom.' - '.$i->ville_stade.' - '.$i->cd_post_stade];
});
$find_equipes = $competition->equipes;
$domicile = $find_equipes->mapWithKeys(function ($i) {
return [$i->id => $i->lb_equipe.' - '.$i->structure->nom_structure.' - ' .$i->catg_equipe->lb_catg_equipe];
});
//ON AFFICHE QUE LES EQUIPES ENREGSITRER DANS LE COMPETITION
$find_equipes = $competition->equipes;
$visiteur = $find_equipes->mapWithKeys(function ($i) {
return [$i->id => $i->lb_equipe.' - '.$i->structure->nom_structure.' - ' .$i->catg_equipe->lb_catg_equipe];
});
$select_poules = Poule::where('compet_id' , 1)->get();
$journees = Journee::where('compet_id' , 1)->get();
$journee_to_select = Journee::where('compet_id' , 1)->pluck('nm_journee' , 'id');
return response()->json([
'table' => view("competitions/show", compact('equipes' , 'competition' , 'categorie_age' , 'categorie_compet' , 'classements' , 'equipe_to_select' , 'structure_rattachement' , 'poules' , 'select_poules' , 'journee_to_select' , 'journees' , 'rencontres', 'designations' , 'stade', 'domicile' , 'visiteur'))->render(),
]);
}else {
echo 'on trouve rien ';
}
Here my javascript :
<script>
$('#poule').change(function () {
$.ajax({
type: 'GET',
dataType: "json",
url : 'search/equipes/',
data : {
poule_id : document.getElementById('poule').value
},
success:function(data){
$('#equipes').html(data.table);
},
});
});
</script>
Getting no error feedback is quite weird, but I would start by changing the dataType you expect in the ajax function to html, because is unnecessary to cast to json and cast it back to html once in javascript. So it would look like this:
Your controller:
public function searchEquipes(Request $request)
{
if ($request->has('poule_id')) {
$equipes = $equipes = EquipePoule::wherePouleId($request->poule_id)->get();
return view("competitions/show", compact('equipes'))->render();
}
}
Your ajax:
<script>
$('#poule').change(function () {
$.ajax({
type: 'GET',
dataType: "html",
url : 'search/equipes/',
data : {
poule_id : document.getElementById('poule').value
},
success:function(data){
$('#equipes').html(data);
}
});
});
</script>
Then I would follow some steps to check where the fail is:
Is the event reaching the ajax?
Is the ajax reaching the server?
Is the server routing that call to the controller?
Is the controller returning the view correctly?
Is the ajax updating the dom container?
Tell me the point where it fails and I will edit with more info.

Pass view as data to js in symfony

I am tryng to implement a search function in my index page using java script. I hav got a form to enter the name and when apply serach, the index page will get updated and load the new index page with the search results
Here is the form in my index page
<div id="content">
<form id="myForm" action="{{path('index_search')}}" method="POST" >
Write your name here:
<input type="text" name="name" id="name_id" value="" /><br />
<input type="submit" value="Send" />
</form>
</div>
<div id="output">#current index</div>
Here is the action exexcuted
public function searchAction()
{
$request = $this->get('request');
$name=$request->request->get('formName');
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('SystemVmsBundle:VisitorsDetails')->findOneByfirstname($name);
$view = $this->render('SystemVmsBundle:VisitorsDetails:index.html.twig',array(
'entities' => $entities,
));
$return=array("responseCode"=>200, "view"=>$view);
$return=json_encode($return);//jscon encode the array
return new Response($return,200,array('Content-Type'=>'application/json'));
}
Here is the js
$(document).ready(function() {
//listen for the form beeing submitted
$("#myForm").submit(function(){
//get the url for the form
var url=$("#myForm").attr("action");
$.post(url,{
formName:$("#name_id").val(),
other:"attributes"
},function(data){
//the response is in the data variable
if(data.responseCode==200 ){
$('#output').html(data.view);
$('#output').css("color","red");
}
else{
alert("An unexpeded error occured.");
}
});
return false;
});
});
However my js is working,but can not pass data as view to the js.How to pass the view 'index.html.twig' to the js?
When inspects with firebug,i got like
{"responseCode":200,"view":{"headers":{}}}
Any ideas?Thanks in advance!
Try to specify the dataType on your $.post function, like this:
$.post(url, {formName: $("#name_id").val(), other: "attributes"},
function(data) {
if(data.responseCode == 200){
$('#output')
.html(data.view)
.css("color","red");
} else {
alert("An unexpeded error occured.");
}
}, 'json');
But If you only need the html, not other data inside the json, you should change the logic, render a normal template and use dataType 'html'. goes like this:
// ...Controller.php
$view = $this->render('SystemVmsBundle:VisitorsDetails:index.html.twig',array(
'entities' => $entities,
));
return new Response($view);
// index.html.twig
$.ajax({
url: url,
dataType: 'html',
type: 'POST',
data: {formName: $("#name_id").val(), other:"attributes"},
success: function (data) {
$('#output').html(data).css("color","red");
}
});

Categories