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).
I want to implement some functionality which is when I enter some text in
<input path="tags" id="input-search"/>
there should appear a list of suggested tags just like
after making ajax call. I have database query
public interface TagRepository extends JpaRepository<Tag, Integer> {
#Query("SELECT t FROM Tag t WHERE name LIKE CONCAT('%', :name, '%')")
List<Tag> findTagByName(#Param("name") String name);
}
and the controller code is
#RequestMapping(value = "/getTags", method = RequestMethod.POST, produces = "application/json")
public #ResponseBody List<Tag> getTags(#RequestBody Tag tag, HttpServletResponse response) {
System.out.println("Found " + String.valueOf(tagService.findTagByName(tag.getName()).size()));
return tagService.findTagByName(tag.getName());
}
javascript for ajax is
$(document).ready(function() {
$("#tag-search").autocomplete({
source: function(request, response) {
$.ajax({
url: "/app/getTags/",
type: "POST",
data: JSON.stringify({tag : request.term}),
dataType: "json",
success: function(data) {
response($.map(data, function(v,i){
console.log();
return {
label: v.empName,
value: v.empName
};
}));
}
});
}
});
});
<div class="col-md-10 col-md-push-1">
<label class="floating-label" for="login-username">Tags</label>
<form:input path="tags" cssClass="form-control" id="tag-search"/>
</div>
when I run the app I see this javaScript error in Developers Tools
Important
I'm using Daemonite/material for my front-end & jQuery-Autocomplete, finally a good thing is that the latest version of App is on GitHub
can any one tell me how can I get rid of that error any response is welcome.
for the problem above i mostly use select2 jquery plugin. it's has a lot of build in feature, so no need of reinventing the wheel. check this link out for a demo - http://select2.github.io/select2/#infinite
screen shot:
code sample:
$("#e7").select2({
placeholder: "Search for a repository",
minimumInputLength: 3,
ajax: {
url: "https://api.github.com/search/repositories",
dataType: 'json',
quietMillis: 250,
data: function (term, page) { // page is the one-based page number tracked by Select2
return {
q: term, //search term
page: page // page number
};
},
results: function (data, page) {
var more = (page * 30) < data.total_count; // whether or not there are more results available
// notice we return the value of more so Select2 knows if more results can be loaded
return { results: data.items, more: more };
}
},
formatResult: repoFormatResult, // omitted for brevity, see the source of this page
formatSelection: repoFormatSelection, // omitted for brevity, see the source of this page
dropdownCssClass: "bigdrop", // apply css that makes the dropdown taller
escapeMarkup: function (m) { return m; } // we do not want to escape markup since we are displaying html in results
});
now layout is not exactly same as screenshot you provided, but check if this layout work for you.
Update:
function repoFormatResult(repo) {
var markup = '<div class="row-fluid">' +
'<div class="span2"><img src="' + repo.owner.avatar_url + '" /></div>' +
'<div class="span10">' +
'<div class="row-fluid">' +
'<div class="span6">' + repo.full_name + '</div>' +
'<div class="span3"><i class="fa fa-code-fork"></i> ' + repo.forks_count + '</div>' +
'<div class="span3"><i class="fa fa-star"></i> ' + repo.stargazers_count + '</div>' +
'</div>';
if (repo.description) {
markup += '<div>' + repo.description + '</div>';
}
markup += '</div></div>';
return markup;
}
function repoFormatSelection(repo) {
return repo.full_name;
}
Another approach:
Hi if above solution not fit for your problem then you can use this one instead. it's called typeahead.js a JavaScript library provide by twitter. you can find examples here.
Check jquery vendor library is loaded properly or not.
To cross check:
<script>
if (window.jQuery) {
alert('jQuery is loaded');
} else {
alert('jQuery is not loaded');
}
</script>
It simply means that you are getting HTML instead of JSON in response.
"Unexpected <" is referring to the first character of your request's response.
in chrome console you can go to network tab and click on your request and in the right side see what exactly your server is returning back to client.
You missed jquery.js. Add it and you'll get it working.
I am adding the codes here so that it would be better readable;
Write a new method to parse json on Java side before returning to jquery. Current code returns Java list as output for Ajax and this would possibly throw Uncaught syntax error : Unexpected token.
public static String toJSON(Object object)
{
if ( object == null ){
return "{}";
}
try {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(object);
}
catch (Exception e) {
e.printStackTrace();
}
return "{}";
}
for the above piece of code you need to include 3 jars jackson-core-2.2.3.jar, jackson-annotations-2.2.3.jar and jackson-databind-2.2.3.jar.
Change you controller as following;
#RequestMapping(value = "/getTags", method = RequestMethod.POST, produces = "application/json")
public #ResponseBody String getTags(#RequestBody Tag tag, HttpServletResponse response) {
System.out.println("Found " + String.valueOf(tagService.findTagByName(tag.getName()).size()));
return toJSON(tagService.findTagByName(tag.getName()));
}
$(document).ready(function() {
var autoCompleteResult = '';
$("#tag-search").autocomplete({
source: function(request, response) {
$.ajax({
url: "/app/getTags/",
type: "POST",
data: JSON.stringify({tag : request.term}),
dataType: "json",
success: function(data) {
autoCompleteResult = jQuery.parseJSON(data);
response($.map(autoCompleteResult, function(v,i){
console.log();
return {
label: v.empName,
value: v.empName
};
}));
}
});
}
});
});
Please share your results after trying this.
Try this:
https://github.com/tanwaniniranjan/autosuggest
It's a plugin made for the same purpose. very less documentation, but i hope to put up the documentation soon.
Yu can read the comments in the js file to get an idea on the usage
Edit:
I now read your question more carefully,
what is happening is:
the response that you are getting from the server side is giving an error.
the error will usually start like sorry bro, 404
since you are trying to map the data, jQuery just cant parse it, and it gives you the error.
check your server side first. use the postman plugin to make requests, verify your response and then implement jQuery: https://chrome.google.com/webstore/detail/postman-launcher/igofndmniooofoabmmpfonmdnhgchoka?hl=en
As i see there could be a issue of 500 internal server error because you have a dataType: "json", in your ajax while at your controller you aren't returning any json.
#RequestMapping(value = "/getTags", method = RequestMethod.POST, produces = "application/json")
public #ResponseBody List<Tag> getTags(#RequestBody Tag tag, HttpServletResponse response) {
System.out.println("Found " + String.valueOf(tagService.findTagByName(tag.getName()).size()));
return tagService.findTagByName(tag.getName());
}
Here at your conroller this: produces = "application/json" says it will return json as output and with this: return tagService.findTagByName(tag.getName()); you can producing any json.
Just add below tag to your ajax call
contentType: 'application/json; charset=utf-8',
This is the type for requested data,in your case it simply text format that you type in text box
And remove below line from your ajax call if your response data is not json type
dataType: 'json',
This may remove Json Parsing Error in your code
Change your JavaScript as the below
$(document).ready(function() {
$("#tag-search").autocomplete({
source: function(request, response) {
$.ajax({
contentType: 'application/json; charset=utf-8',
url: "/app/getTags/",
type: "POST",
data: JSON.stringify({'tag' : "'"+request.term+"'"}),
dataType: "json",
success: function(data) {
response($.map(data, function(v,i){
console.log();
return {
label: v.empName,
value: v.empName
};
}));
}
});
}
});
});
I have created a webmethod and the method just send a Excel file as webresponse.When i run only the webmethod it works fine as want
My webmethod is following:
public void Export_ex(string elem)
{
string elements = elem;
HttpContext.Current.Response.ContentType = "data:application/vnd.ms-excel";
HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=Print.xls");
HttpContext.Current.Response.Write("<html xmlns:x=\"urn:schemas-microsoft-com:office:excel\">");
HttpContext.Current.Response.Write("<head>");
HttpContext.Current.Response.Write("<div>");
HttpContext.Current.Response.Write("<META http-equiv=\"Content-Type\" content=\"text/html; charset=utf- 8\">");
HttpContext.Current.Response.Write("<!--[if gte mso 9]><xml>");
HttpContext.Current.Response.Write("<x:ExcelWorkbook>");
HttpContext.Current.Response.Write("<x:ExcelWorksheets>");
HttpContext.Current.Response.Write("<x:ExcelWorksheet>");
HttpContext.Current.Response.Write("<x:Name>Report Data</x:Name>");
HttpContext.Current.Response.Write("<x:WorksheetOptions>");
HttpContext.Current.Response.Write("<x:ValidPrinterInfo/>");
HttpContext.Current.Response.Write("</x:Print>");
HttpContext.Current.Response.Write("</x:WorksheetOptions>");
HttpContext.Current.Response.Write("</x:ExcelWorksheet>");
HttpContext.Current.Response.Write("</x:ExcelWorksheets>");
HttpContext.Current.Response.Write("</x:ExcelWorkbook>");
HttpContext.Current.Response.Write("</xml>");
HttpContext.Current.Response.Write("<![endif]--> ");
HttpContext.Current.Response.Write("</head>");
HttpContext.Current.Response.Write(elements);
HttpContext.Current.Response.Flush();
// HttpContext.Current.Response.End();
}
but when i call it from javascript function by ajax calling nothing happened. My ajax method is following :
var str = "something"
var data = { elem: str };
$.ajax({
type: 'POST',
url: "ImageSaving.asmx/Export_ex",
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
mimeType: 'application/vnd.ms-excel',
success: function (response) {
var show = response.d;
},
failure: function (msg) {
alert("Error occur, could not load the service.");
}
});
I could not understand where i am getting wrong?? Any suggestion regarding this?
For security reasons, you cannot download file from client side. I advice to use a hidden button server side and simulate the click from another button client side.
Regards.
The reading works.
However I got a syntax error in the firefox console (which is tiresome when I read 30 files).
The files are annotation files like (time \t value) with no headers like :
0.0 5.2
0.5 5.6
1.0 6.3
...
This is the ajax code :
function getdatafromfile(filename) {
// Read annotation file. Example : %timeinstant \t %value \n
// Return an array of string
var arraydata
$.ajax({
type: "GET",
url: filename,
dataType: "text",
async: false,
success: function(csv) {arraydata = $.csv.toArrays(csv,{separator:'\t'}); }
});
return arraydata}
And with d3:
d3.text(filename, function(text) {
var data = d3.tsv.parseRows(text).map(function(row) {
return row.map(function(value) {
return +value;
});
});
console.log(data);
});
}
It seems that I could use one of those code, but I got a syntax error in both cases (with firefox 33.1).
A file reader could work like the code below.
In the example I've added a flag to use the content of the variable instead of a file. That's just for the demo and can be removed. The same code is here as jsFiddle.
Maybe you could add some validation before or after the $.csv method. So you know that the file was a csv/tsv file.
If you need to open the file with-out user interaction, you have to look for something different because JS is not allowed to open a file with-out the user choosing the file (security concerns, see this SO question).
You could add your data to a database and read it from there. e.g. Firebase or MongoDB or use a JSON file. The code of my other answer should work for a JSON file that you host with your webpage.
var demoTxt = "0.0 5.2\
0.5 5.6\
1.0 6.3";
var flag_usedemofile = true; //if true var demoTxt will be used
function doOpen(evt) {
var files = evt.target.files,
reader = new FileReader();
reader.onload = function() {
if ( !flag_usedemofile) {
var arraydata = $.csv.toArrays(this.result,{separator:' '});
showout.value = arraydata; //this.result;
} else {
var arraydata = $.csv.toArrays(demoTxt,{separator:' '});
showout.value = arraydata;
console.log(arraydata);
}
};
reader.readAsText(files[0]);
}
var openbtn = document.getElementById("openselect"),
showout = document.getElementById("showresult");
openselect.addEventListener("change", doOpen, false);
#showresult {
width:98%;
height: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery-csv/0.71/jquery.csv-0.71.min.js"></script>
<input type="file" id="openselect" />
<textarea id="showresult"></textarea>
I'm not exactly sure what syntax error you are getting. But I think the error have something to do with the mime type of your json request.
I think the best way is to wrap your data in json and then use JSONP. (I have also tried to get it working with text/plain, but with-out success.)
Please check the following example for details. You can also find the same example on
jsFiddle.
(function ($) {
var url = 'http://www.mocky.io/v2/547c5e31501c337b019a63b0'; // dummy url
var jsonCallback = function (csv) {
var arraydata;
console.log(data);
$('#data').html(JSON.stringify(csv, null, 2));
arraydata = $.csv.toArrays(csv.data,{separator:'\t'});
console.log(arraydata);
};
$.ajax({
type: 'GET',
url: url,
contentType: "application/json",
dataType: 'jsonp'
}).done(jsonCallback)
.fail(function (xhr) {
alert("error" + xhr.responseText);
});
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre id='data'></pre>
I am trying to upload a zip file on server unzip it there and return names of file to client.
Code:
<form id="frmUpload" action="UploadHandler.ashx" method="post">
<input id="fileUpload" name="fileToUpload" type="file" accept=".zip"/>
<input id="btnUpload" type="submit" value="Submit" />
</form>
Server Code:
public void ProcessRequest (HttpContext context)
{
var uploadedFile=context.Request.Files["fileToUpload"];
//uploadedFile is then unzipped, filenames are extracted and put in a string
// filenames="a,b,c";
context.Response.Write(filenames);
}
I want to have a callback function at client where I can access this.
I tried a second approach:
$("#frmUpload").submit(function (evt) {
// evt.preventDefault();
//var data = $("#frmUpload")[0].serialize(); // returning empty string
var form = $("#frmUpload")[0];
var file = form["fileToUpload"].value;
$.ajax({
type: "POST",
url: "UploadHandler.ashx",
data: "file="+file,
success: function (result, status, respObj) {
alert(result);
}
});
})
In this case success callback is getting executed however, at server i don't have file object as the data passed to server is only the path of zip file. How can I pass file object to server?
Thanks
You cannot pass the file object to the server. Instead, you should upload the file to the server and then the server unzips the file and sets a flag in session or database indicating that file has been processed.
Meanwhile you can loop an ajax request to the server requesting for file status.
Something like this
var i=0;
for(;;){
if(i==1) return;
$.ajax({
type: "POST",
url: "UploadHandler.ashx",
data: "file="+file,
success: function (result, status, respObj) {
if(result){
alert(result);
i = 1;
}
}
});
}