I am trying to implement the jQuery autocomplete custom data and display. Right now I'm using just the regular autocomplete. My problem is converting the json array of json objects to an array of javascript objects. Could someone please point me in the right direction. Here is what I currently have for the standard autocomplete.
javascript:
$('input[type=radio][name=transaction]').change(function(){
console.log($('input[type=radio][name=transaction]:checked').val());
$.ajax({
type: "post",
async: false,
url: "/autocomplete",
contenttype: "application/json; charset=utf-8",
datatype: "json",
data: "transaction="+$('input[type=radio][name=transaction]:checked').val(),
success: function (data)
{
if($('input[type=radio][name=transaction]:checked').val() == "sell")
{
theSymbols = JSON.parse(data);
}
else
{
theSymbols = data;
}
},
error: function (bad)
{
alert("Autocomplete failed.");
}
});
if($('input[type=radio][name=transaction]:checked').val() == "sell")
{
$("#symbol").autocomplete(
{
minLength: 0,
source: theSymbols,
focus: function(event, ui) {
$("#symbol").val(ui.item.value);
return false;
},
select: function(event, ui)
{
$("#symbol").val( ui.item.value);
$("#sharesOwn").html( ui.item.shares);
$("#sharesText").show();
return false;
}
})
.autocomplete("instance")._renderItem = function(ul, item)
{
return $("<li>")
.append("<a>" + item.label + "<br><span class='acFormat'>" + item.desc + "</span></a>")
.appendTo(ul);
};
}
else
{
$("#symbol").autocomplete({source: theSymbols});
}
java:
ArrayList<String> symbols = new ArrayList<String>();
ArrayList<Position> positionList = new ArrayList<Position>();
positionList = PositionDB.getPositions(user.getPortfolioID(), "O");
for (Position p : positionList)
{
String data = "";
data = "{";
data += "value: " + p.getSymbol();
data += ", label: " + p.getSymbol();
data += ", desc: " + p.getCompName();
data += ", shares: " + p.getShares();
data += "}";
symbols.add(data);
}
Gson gson = new Gson();
JsonElement syms = gson.toJsonTree(symbols, new TypeToken<List<String>>() {}.getType());
response.setContentType("application/json; charset=UTF-8");
JsonArray jArray = syms.getAsJsonArray();
PrintWriter out = response.getWriter();
System.out.println(jArray);
out.print(jArray);
out.flush();
Stock object has symbol, company name and price.
I'm having problems creating the JSON array or objects to pass to my javascript. Right now it outputs as if it were a js array of objects but keys are showing up in the textbox, along with the values so the autocomplete must be seeing it as a string, which means that I can't build it as a string in java so I need a different way. Ideas?
Thank you.
Related
I am making an ajax request to an endpoint to make CSV file from ResultSet. I am doing below code to do that.
val statement = dbCon.createStatement()
val rs = statement.executeQuery(exportQuery)
val csvWriter = new PrintWriter(new File("D:\\wdd.csv"))
val meta: ResultSetMetaData = rs.getMetaData()
val numberOfColumns = meta.getColumnCount()
var dataHeaders = "\"" + meta.getColumnLabel(1) + "\""
for (i <- 2 to numberOfColumns) {
dataHeaders += ",\"" + meta.getColumnLabel(i) + "\""
}
csvWriter.println(dataHeaders)
while (rs.next()) {
var row = "\"" + rs.getString(1) + "\""
for (i <- 2 to numberOfColumns) {
row += ",\"" + rs.getString(i) + "\""
}
csvWriter.println(row)
}
csvWriter.close()
But the problem is that it is actually writing to a file in the server side. I don't want that to write a file in the server side instead i what i want is that when client will fire this endpoint, the file will automatically be downloaded in the client side.
This is my Ajax request.
exportDataAsCSVFile: function (schemaName, params) {
var deferred = can.Deferred();
$.ajax({
url: '/adhoc-matching/export-csv/' + schemaName,
type: 'POST',
contentType: "application/json",
dataType: 'json',
async: true,
data: JSON.stringify(params),
success: function (data) {
deferred.resolve(data);
},
error: function (xhr, settings, exception) {
deferred.reject(xhr, settings, exception);
}
});
return deferred.promise();
}
How can i make CSV in memory as stream and send the stream to the client to automatically download as a file??
I am using Scala Ok(write(resp)) to send the response. What needs to be changed to the request headers to send the stream?
EDIT:
I could make the stream into an string. But what should i write in the ajax request to download the file in client side. I have tried to give dataType as "text/csv" or "text" and also added below headers.
$.ajax({
headers: {
Accept : "text/csv; charset=utf-8",
"Content-Type": "text/csv; charset=utf-8"
}
But the file is not downloading in the client side though the response has the text. Below what i tried out to make CSV:
val csvWriter: StringWriter = new StringWriter
try {
val statement = dbCon.createStatement()
val rs = statement.executeQuery(exportQuery)
val meta: ResultSetMetaData = rs.getMetaData()
val numberOfColumns = meta.getColumnCount()
var dataHeaders = "\"" + meta.getColumnLabel(1) + "\""
for (i <- 2 to numberOfColumns) {
dataHeaders += ",\"" + meta.getColumnLabel(i) + "\""
}
csvWriter.write(dataHeaders + "\n")
while (rs.next()) {
var row = "\"" + rs.getString(1) + "\""
for (i <- 2 to numberOfColumns) {
row += ",\"" + rs.getString(i) + "\""
}
csvWriter.write(row + "\n")
//csvWriter.println(row)
}
csvWriter.flush()
}
catch {
case e: Exception =>
}
finally {
dbCon.close()
csvWriter.close()
}
val fileName = "untitled.csv"
val csvData = csvWriter.toString
Ok(csvData).as("text/csv; charset=utf-8").withHeaders(
CONTENT_DISPOSITION -> s"attachment; filename=$fileName",
CONTENT_LENGTH -> csvData.length.toString
)
Your server side code should look like this:
#RequestMapping(method = RequestMethod.GET, value = "csv",
produces = { AdditionalMediaTypes.TEXT_CSV_UTF8, AdditionalMediaTypes.APPLICATION_CSV_UTF8 })
public void getCsvFile(HttpServletRequest request, HttpServletResponse response) throws Exception {
csvWriter.writeCsvToResponse(request, response);
}
When called a csv file would download to the client.
public void writeCsvToResponse(HttpServletRequest request,
HttpServletResponse response) throws IOException {
methodToWriteYourThingAsCsv.writeToStream(yourListOfObjectsYouWantToWrite, response.getOutputStream());
}
So I have a program that basically allows two users two chat back and forth and do other things via websocket with javascript and java server endpoints. When one of the users presses a button I have a listener that fires off a message to the other user which invokes a function. During this function I want to be able to call an AJAX POST with JQuery to update my database but this is causing a java.util.concurrent.TimeoutException. Any idea why this occurs? I imagine it has something to do with the fact that the websocket connection doesn't stay open long enough for the ajax call to go through.
So I've done the research and I've seen that websocket and AJAX are not exactly something that should be mixed (I think). However I can't seem to figure out an alternative even to update my database. There is a lot of code for this so I will try and only post the important parts.
Here is the part of the code for when the button is pressed (it is an agree button so both users must have pressed it hence the '**' and '--' characters).
fAgree.addEventListener("click", function() {
// selects this button
if (aStr == "**" && (yStr == "**" || oStr == "**")) {
if (fStr == "--") {
fStr = "*-";
//redirect to another page
} else if (fStr == "-*") {
fStr = "**";
if(secondTransaction == false) {
var firstCoordUpload = document.getElementById("yourPos").innerHTML;
var secondCoordUpload = document.getElementById("othersPos").innerHTML;
var firstLatUpload = parseFloat(firstCoordUpload.split(",")[0]);
var firstLonUpload = parseFloat(firstCoordUpload.split(",")[1]);
$.ajax({
url: "../../309/T11/setSaleData/" + getURLParameter("saleID") + "/" + firstLatUpload + "/" + firstLonUpload + "/" + firstCoordUpload + "/" + secondCoordUpload + "/" + secondSeller,
type: "POST",
headers: {
"Authorization" : getCredentials(),
},
success: function (result) {
window.location.href = '../../frontEnd/profilePage/index.html?username='+ getUsername();
console.log(result);
},
error: function (dc, status, err) {
console.log(err);
console.log(status);
}
});
}
}
agreeBut.socket.send("a,f");
htmlChange(fStr, fStar);
}
});
Here is the part of the code that is called at the end of the code above (the agreeBut.socket.send()).
agreeBut.socket.onmessage = function(message) {
// check [0]: a for agree buttons,
// m for map,
// l of location buttons,
// t for trade
var mess = message.data.split(",");
if (mess[0] == "a") {
// second a shows the agree button was pressed, changes aStr
// accordingly and displays
if (mess[1] == "a") {
if (aStr == "--") {
aStr = "-*";
} else if (aStr == "*-") {
aStr = "**";
}
htmlChange(aStr, aStar);
// shows the final agree button has been pressed, changes fStr
// accordingly and displays
} else if (mess[1] == "f") {
if (fStr == "--") {
fStr = "-*";
//redirect
} else if (fStr == "*-") {
fStr = "**";
alert("on this");
if(secondTransaction == true) {
alert("doing it");
var firstCoordUpload = document.getElementById("yourPos").innerHTML;
var secondCoordUpload = document.getElementById("othersPos").innerHTML;
var firstLatUpload = parseFloat(firstCoordUpload.split(",")[0]);
var firstLonUpload = parseFloat(firstCoordUpload.split(",")[1]);
$.ajax({
url: "../../309/T11/setSaleData/" + getURLParameter("saleID") + "/" + firstLatUpload + "/" + firstLonUpload + "/" + firstCoordUpload + "/" + secondCoordUpload + "/" + secondSeller,
type: "POST",
headers: {
"Authorization" : getCredentials(),
},
success: function (result) {
console.log(result);
alert("Got it");
window.location.href = '../../frontEnd/profilePage/index.html?username='+ getUsername();
},
error: function (dc, status, err) {
console.log(err);
console.log(status);
}
});
}
//window.location.href = '../../frontEnd/profilePage/index.html?username='+ getUsername();
}
htmlChange(fStr, fStar);
}
}
};
It turns out I was getting this problem because of the timeout that was set on my java ServerEndpoint. In the class I used the setMaxIdleTimeout(0) function on the session variable to have no idle timeout. This seemed to solve my problem (however I feel like this is really just a workaround for poor websocket and ajax implementation on my end).
what i wanted to do is use jquery to get data from the databases and show it in the jsp pages.
In my jsp:
<input onclick="getPlatform('${item.string1}')"type="radio" id="${item.string1}" name="tab-group-1" checked>
in my .js:
$.ajax({
type: "POST",
url: "Controller?operation=GetPlatforms",
data: dataString,
dataType: "json",
//if received a response from the server
success: function(data, textStatus, jqXHR) {
//our platform was correct so we have some information to display
if (data.success) {
$.each(data.PlatformInfo, function() {
$("#ajaxResponsePlatforms").html("");
$("#ajaxResponsePlatforms").append("value: " + data.PlatformInfo.name);
});
}
//display error message
else {
$("#ajaxResponsePlatforms").html("<div><b>Country code is Invalid!</b></div>");
}
},
the server output is:
value of JsonElement: [{"name":"PC"},{"name":"Servers"}]
value of myObj: {"success":true,"PlatformInfo":[{"name":"PC"},{"name":"Servers"}]}
and the result in my JSP pages is:
value: undefined
Code to build Json response:
String technology = request.getParameter("technology");
System.out.println("Test " + technology);
PrintWriter out = response.getWriter();
response.setContentType("text/html");
response.setHeader("Cache-control", "no-cache, no-store");
response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", "-1");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST");
response.setHeader("Access-Control-Allow-Headers", "Content-Type");
response.setHeader("Access-Control-Max-Age", "86400");
Gson gson = new Gson();
JsonObject myObj = new JsonObject();
BACENGQueryDatabases PlatformData = new BACENGQueryDatabases();
ArrayList PlatformInfo = PlatformData.GetPlatform(technology);
JsonElement platformObj = gson.toJsonTree(PlatformInfo);
System.out.println("JsonElement: " + platformObj);
if (PlatformInfo.isEmpty()) {
myObj.addProperty("success", false);
System.out.println("Array empty");
} else {
myObj.addProperty("success", true);
System.out.println("Array full");
}
System.out.println("value json " + platformObj);
myObj.add("PlatformInfo", platformObj);
out.println(myObj.toString());
System.out.println(" myObj: " + myObj.toString());
out.close();
It's happenign since I want to do get the result as ArraList form, however if instead Array I use a single String object it is working fine.
how can use ArayList and jquery.apped method?
if you use $.each on data.PlatformInfo you shoud use what's iterated on inside the callback, not data.PlatformInfo which is a list (and has no .name), something like this:
$.each(data.PlatformInfo, function(i, e) { // i = index, e = element
// are you sure you want to: $("#ajaxResponsePlatforms").html("");
$("#ajaxResponsePlatforms").append("value: " + e.name);
});
Also note that setting html content to "" inside the loop is probably not what you want, you probably want that before the $.each.
Demo: JSFiddle
I have the unenviable task of editing a 2000 line javascript file inorder to maintain and add some new feature to a web app written in JSP, Json-RPC, jQuery and Java. I do not possess any deeper knowledge of jQuery and Json-RPC except basic Javascript knowledge and the original developer is not there anymore.
There is a JS function which accepts a few params, and calls a Json-RPC and here I am getting the error
arg 1 could not unmarshal
Can someone please tell me what this error means?
Here is my code
function distributeQuantityNew(pReportId, pDecimalPlaces, pRun) {
try {
alert('distributeQuantityNew: ' + pReportId + ', ' + pDecimalPlaces + ', ' + pRun);
var fieldValue = $("#distribution_quantity_" + pReportId).val();
if (fieldValue.length == 0) {
showErrorDialog(resourceBundleMap["error.no.distribution.quantity"]);
return;
} else {
$("#distribution_quantity_" + pReportId).val("");
}
var affectedRowIds = [];
var rows = $("#tableBody_" + pReportId + " tr:visible").has("input[type=text]").filter(function(index) {
var voucherType = this.cells[getVoucherColumnIndex()].innerHTML;
if ((voucherType == 'TRANSFER_CS') || (voucherType == 'PAYOUT_CS') || (voucherType == 'SOURCE_BON') || (voucherType == 'PAYOUT_BON')) {
return false;
}
affectedRowIds.push(parseInt(this.id.split("_")[3]));
return true;
}
);
var affectedReportRows = $.extend(true, {}, foreignReportMap[pReportId]);
$.each(affectedReportRows.map, function(i, row) {
if ($.inArray(row.partnerReportBillNr, affectedRowIds) == -1) {
delete affectedReportRows.map["row_" + row.partnerReportBillNr];
}
});
var report = getLoadedReportByRunId(pReportId);
var productType = report.partnerProductType;
SessionManager.extend();
var resultRows = jsonrpc.foreignReportObject.distributeQuantity(affectedReportRows, fieldValue, pDecimalPlaces, pRun);
alert('back after RPC');
$.each(resultRows.map, function(i, row) {
foreignReportMap[pReportId].map["row_" + row.partnerReportBillNr] = row;
updateForeignReportRow(row, true, productType);
});
updateSummaryRow(pReportId);
toggleApproveAllLink(pReportId);
sortForeignReportTable(pReportId, true);
} catch (e) {
handleError("Failed to distribute quantity: ", e);
}
}
I have peppered it with alerts so that I know whether RPC call was succesful, but I get the error arg 1 could not unmarshal before that from the catch block. Thanks for any hints
OK, got it solved. The first parameter to the remote function is expecting a list of Map<String, SomeBO>. SomeBO is a bean with several BigDecimals. I had another JS function which had set the values passed into the Map. This function was setting a BigNumber where I had a setter of String only. I wish the error I had gotten back from JSON unmarshaller was a bit more descriptive...Below is the code where I added .toString() to solve the issue
foreignReportMap[pReportId].map["row_" + pRowId].clientQuantity = clientQuantity.toString();
foreignReportMap[pReportId].map["row_" + pRowId].totalClientQuantity = totalClientQuantity.toString();
I think (actually I KNOW!) I'm doing something wrong here I am trying to populate some values into HashMap and add each hasmap to a list which will be added to a JSON object:
JSONObject json = new JSONObject();
try
{
Map address;
List addresses = new ArrayList();
int count = 15;
for (int i=0 ; i<count ; i++)
{
address = new HashMap();
address.put("CustomerName" , "Decepticons" + i);
address.put("AccountId" , "1999" + i);
address.put("SiteId" , "1888" + i);
address.put("Number" , "7" + i);
address.put("Building" , "StarScream Skyscraper" + i);
address.put("Street" , "Devestator Avenue" + i);
address.put("City" , "Megatron City" + i);
address.put("ZipCode" , "ZZ00 XX1" + i);
address.put("Country" , "CyberTron" + i);
addresses.add(address);
}
json.put("Addresses", addresses);
}
catch (JSONException jse)
{
}
response.setContentType("application/json");
response.getWriter().write(json.toString());
My problem is I know this is returning a string, which I cannot seem to parse (which is the problem). My question is how do I return the actual JSON encoded string (or even should I be doing this?) or what is the best method of attack for this type of problem. The JavaScript I am using for this is below:
function getReadyStateHandler(req)
{
// Return an anonymous function that listens to the
// XMLHttpRequest instance
return function ()
{
// If the request's status is "complete"
if (req.readyState == 4)
{
// Check that a successful server response was received
if (req.status == 200)
{
msgBox("JSON Response recieved...");
populateDatagrid(req.responseText.toJSON());
}
else
{
// An HTTP problem has occurred
alert("HTTP error: " + req.status);
}
}
}
}
Note the JSON Response comes back fine, but its a string. Any advice is greatly appreciated. I am also opening to using googles Gson, but don't have too much knowledge on that.
Got it working! I should have been building a JSONArray of JSONObjects and then add the array to a final "Addresses" JSONObject. Observe the following:
JSONObject json = new JSONObject();
JSONArray addresses = new JSONArray();
JSONObject address;
try
{
int count = 15;
for (int i=0 ; i<count ; i++)
{
address = new JSONObject();
address.put("CustomerName" , "Decepticons" + i);
address.put("AccountId" , "1999" + i);
address.put("SiteId" , "1888" + i);
address.put("Number" , "7" + i);
address.put("Building" , "StarScream Skyscraper" + i);
address.put("Street" , "Devestator Avenue" + i);
address.put("City" , "Megatron City" + i);
address.put("ZipCode" , "ZZ00 XX1" + i);
address.put("Country" , "CyberTron" + i);
addresses.add(address);
}
json.put("Addresses", addresses);
}
catch (JSONException jse)
{
}
response.setContentType("application/json");
response.getWriter().write(json.toString());
This worked and returned valid and parse-able JSON. Hopefully this helps someone else in the future. Thanks for your help Marcel
I used JSONObject as shown below in Servlet.
JSONObject jsonReturn = new JSONObject();
NhAdminTree = AdminTasks.GetNeighborhoodTreeForNhAdministrator( connection, bwcon, userName);
map = new HashMap<String, String>();
map.put("Status", "Success");
map.put("FailureReason", "None");
map.put("DataElements", "2");
jsonReturn = new JSONObject();
jsonReturn.accumulate("Header", map);
List<String> list = new ArrayList<String>();
list.add(NhAdminTree);
list.add(userName);
jsonReturn.accumulate("Elements", list);
The Servlet returns this JSON object as shown below:
response.setContentType("application/json");
response.getWriter().write(jsonReturn.toString());
This Servlet is called from Browser using AngularJs as below
$scope.GetNeighborhoodTreeUsingPost = function(){
alert("Clicked GetNeighborhoodTreeUsingPost : " + $scope.userName );
$http({
method: 'POST',
url : 'http://localhost:8080/EPortal/xlEPortalService',
headers: {
'Content-Type': 'application/json'
},
data : {
'action': 64,
'userName' : $scope.userName
}
}).success(function(data, status, headers, config){
alert("DATA.header.status : " + data.Header.Status);
alert("DATA.header.FailureReason : " + data.Header.FailureReason);
alert("DATA.header.DataElements : " + data.Header.DataElements);
alert("DATA.elements : " + data.Elements);
}).error(function(data, status, headers, config) {
alert(data + " : " + status + " : " + headers + " : " + config);
});
};
This code worked and it is showing correct data in alert dialog box:
Data.header.status : Success
Data.header.FailureReason : None
Data.header.DetailElements : 2
Data.Elements : Coma seperated string values i.e. NhAdminTree, userName
I think that what you want to do is turn the JSON string back into an object when it arrives back in your XMLHttpRequest - correct?
If so, you need to eval the string to turn it into a JavaScript object - note that this can be unsafe as you're trusting that the JSON string isn't malicious and therefore executing it. Preferably you could use jQuery's parseJSON