Laravel download xls file with AJAX - javascript

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');

Related

how to get url value from arduino using ajax and laravel?

this is my url value from arduino
request_string = "http://127.0.0.1:8000/monitoring/x/?x=1";
i have problem when try to catching the value using url in ajax
$.ajax({
type:'get',
url:'http://127.0.0.1:8000/monitoring/x/',
dataType: "json",
success:function(response){
if (response.data==0) {
var img = document.getElementById("kursi7");
img.src="{{asset('/assets/images/kursi.jpg')}}";
document.getElementById('lokasi'+1).innerHTML=("TIDAK ADA ORANG");
}else {
// location.reload();
var img = document.getElementById("kursi7");
img.src="{{asset('/assets/images/kursi_booked.jpg')}}";
document.getElementById('lokasi'+1).innerHTML=("ADA ORANG");
}
}
});
and processing in php (laravel)
i have some error undefined variable x when try to get the data $_GET['x'] from passing value url in arduino
public function data(Request $req, $x)
{
$x=$_GET['x'];
return response()->json($x);
}
i hope someone can help and give me an information abt this.
thanks a lot mate
For the PHP side of things you should be doing something like this instead:
public function data(Request $request)
{
$x = $request->input('x')
return response()->json($x);
}
As per https://laravel.com/docs/8.x/requests#accessing-the-request

Passing two parameters in yii2 ajax request using jquery to a controller

I have a link when pressed it requests a page from a controller via render ajax, Previously i used to pass only the id but now i would like to pass an extra parameter to the controller, how do i achieve this,
This is what i have tried
This is the link' which only passes a single parameter to the controller
Html::a('click me', ['#'],
['value' => Url::to('checktruck?id='.$model->id), //this is where the param is passed
'id' => 'perform']);
This is the controller code expecting 2 parameters:
public function actionChecktruck($id,$category) //it expects 2 parameters from above link
{
$truckdetails = Truck::find()->where(['id' =>$id])->one();
if (Yii::$app->request->post()) {
$checklistperform = new TodoTruckChecklist();
$truck = Truck::find()->where(['id'=>$id])->one();
$checklistperform->truck_id=$id;
$checklistperform->registered_by=Yii::$app->user->identity->id;
$checklistperform->save();
$truck->update();
var_dump($checklistperform->getErrors());
//var_dump($truck->getErrors());
}
else {
$truckcategory = Checklist::find()->where(['truck_category'=>$truckdetails->truck_category])->andWhere(['checklist_category'=>$category])->all();
return $this->renderAjax('truckyard/_checklistform', [
'truckcategory' => $truckcategory,'truckvalue'=>$id,
]);
}
}
This is my jquery code of another button that depends on the above controller during post request
$("#postbutn").click(function(e) {
$.post("checktruck?id="+truckid, //here i would like to pass 2 params
{checked:checked,unchecked:unchecked,truckid:truckid}
)
}
This is the jquery code when there is no post
How can i pass an extra parameter in the link or even the $.post request for the controller
First of all, as you are using JQuery ajax to submit the form, there is no need to set value for the link
Html::a('click me', ['#'],['id' => 'perform']);
using this id you can submit the request as follows
$this->registerJs("$('#perform').click(function(event){
event.preventDefault(); // to avoid default click event of anchor tag
$.ajax({
url: '".yii\helpers\Url::to(["your url here","id"=>$id,"param2"=>param2])."',
success: function (data) {
// you response here
},
});
});");
There is no need to mention method attribute as 'POST', you want to send through GET method
And finally in your controller, you need to accept parameters as follows
public function actionChecktruck() //it expects 2 parameters from above link
{
$id = Yii::$app->request->queryParams['id'];
$param2 = Yii::$app->request->queryParams['param2'];
$truckdetails = Truck::find()->where(['id' =>$id])->one();
if (Yii::$app->request->post()) {
$checklistperform = new TodoTruckChecklist();
$truck = Truck::find()->where(['id'=>$id])->one();
$checklistperform->truck_id=$id;
$checklistperform->registered_by=Yii::$app->user->identity->id;
$checklistperform->save();
$truck->update();
var_dump($checklistperform->getErrors());
//var_dump($truck->getErrors());
}
else {
$truckcategory = Checklist::find()->where(['truck_category'=>$truckdetails->truck_category])->andWhere(['checklist_category'=>$category])->all();
return $this->renderAjax('truckyard/_checklistform', [
'truckcategory' => $truckcategory,'truckvalue'=>$id,
]);
}
}
Try this one,
In View file
$this->registerJs("$('#postbutn').click(function(){
$.ajax({
url: '".yii\helpers\Url::to(["u r URL"])."',
method: 'POST',
data: {id:id, truckid:truckid },
success: function (data) {
},
});
});");

Web API controller downloads csv but doesn't work with jQuery

I have a simple web api controller which I can navigate to through the url and it will download the .csv file. Now I am trying to write some jQuery where if you click the button it will download it but I am missing something.
public HttpStatusCode Get(string id)
{
var reportString = AskWebBusiness.Reports.GenerationQuestionReport(id);
var response = HttpContext.Current.Response;
response.ContentType = "text/csv";
response.AppendHeader("Content-Disposition", "attachment;filename=" + "Questions Report.csv");
response.Write(reportString);
return HttpStatusCode.OK;
}
This code definitely works and I can go to the URL to prompt the download.
$('.js-btn-download-content').click(function (event) {
var currentLanguage = getCulture();
var url = baseUrl + 'report/get/' + currentLanguage;
event.preventDefault();
$('.loadingContent-download').fadeIn(200);
$.ajax({
headers: {
Accept : "text/csv; charset=utf-8",
"Content-Type": "text/csv; charset=utf-8"
},
url: url,
dataType: "text/csv",
success: function (data) {
$('.loadingContent-download').fadeOut(200);
// Not sure about code below
//var xmlDoc = $.parseXML(data);
//var $xml = $(xmlDoc);
//var $title = $xml.find("200");
//if ($title) {
//$('.contentDownloaded-download p').html('Content donwloaded!');
//$('.contentDownloaded-download').show();
//} else {
//$('.contentDownloaded-download p').html('Download failed! Please try again.');
//$('.contentDownloaded-download').show();
//
}
});
$('.js-btn-confirm').click(function () {
$('.contentDownloaded-download').fadeOut(200);
});
});
As you can see, here is some javaScript that I've been using in the app to handle an OK being returned. However the browser won't download the file when this script fires. Any ideas?
In your Get(string id) method, return the HttpResponseMessage instead of just the HttpStatusCode. Also, ASP.net Web API does not ensure the state of HttpContext.Current.Response (without some wizardry code). You can do something like, change the signature to Get(HttpRequestMessage request, string id) and then call request.CreateResponse(statusCode, data).

Passing values from view to controller and again from controller to view?

I have a controller suppose a and it has a function suppose index() where i passed data from my view suppose b using javascript like this:
var formURL = "<?php echo base_url();?>a/index/"+ $("#someid").val();
$.post(formURL).done(function(data){$("#something").html(data);
now i am receiving it in my controller like this:
public function index($somevalue= ""){
....
....
}
now after execution from the controller a i am again passing array values to the view b like this:
public function index($somevalue= ""){
....
....
$data['value1'] = $value1;
$data['value2'] = $value2;
$this->load->view('b', $data);
}
now when i am accessing the data in the view b like this:
<?php if (isset($value1)) {
echo $value1;
}?>
i am not getting the value of value1. what did i do wrong in this case???
It would be a lot lot better if you use AJAX. This is what it precisely does.
AJAX request to controller i.e (sending datas to controller)
Get the AJAX result i.e (sending datas back to views)
and from client side you can update it.
You can get the form values like
var formDatas = $('#form').serialize();
Then make an ajax request like
$.ajax({
type : 'POST',
url : 'url',
data : {formdata : formDatas },
success: function(result){
//update the view with the result
}
}

Jquery ajax call in Cake PHP 3.0

Hi,
I'm trying to make a ajax request to the view A from the controller B like this :
In the view A :
var tab = new Array();
function updateResult(){
$.ajax({
type:"POST",
url:"<?php echo Router::url(array('controller'=>'B','action'=>'viewresult'));?>",
dataType: 'text',
async:false,
success: function(tab){
alert('success');
},
error: function (tab) {
alert('error');
}
});
}
In the controller B:
public function viewresult()
{
echo 'SUCCESS';
}
The problem is that in the 'response' of ajax, I've 'SUCCESS' but also the entire view A, I don't understand why...
I want only 'SUCCESS'...
Thanks in advance !
Detect if its ajax as per following code in cakephp way :
if($this->request->is('Ajax')) //Ajax Detection
{
$this->autoRender = false; // Set Render False
$this->response->body('Success');
return $this->response;
}
Check here for more detectors - http://book.cakephp.org/3.0/en/controllers/request-response.html#Cake\Network\Request::addDetector
You can also use $this->Url->build instead of including Router for creating links in view.
echo $this->Url->build(['action'=>'index']);
The easiest way to achieve it is adding die() at the end of your function so it prevents to load whole layout:
public function viewresult()
{
echo 'SUCCESS';
die;
}
OR
public function viewresult()
{
die('SUCCESS');
}
But more conventional way is using JSONView. Your action should look as follows:
public function viewresult()
{
$this->set('text', 'SUCCESS');
$this->set('_serialize', ['text']);
}
You also have to load RequestHandler component in initialize() method in your controller:
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler');
}
You need to set allowed extensions for all routes connected later in routes.php:
Router::extensions('json', 'xml');
Now you can access your action adding extension .json at the end of it's URL, so you need to modify ajax call url:
url:"<?php echo Router::url(array('controller'=>'Main','action'=>'viewresult', '_ext' => 'json'));?>"
That's all, but keep in mind that this solution force you to handle JSON array in response. In this example output will be looks as follows:
{"text": "SUCCESS"}

Categories