Google Appscript has the ability to pass things from the server side scripting, to client side html.
eg
appscript.gs
var htmlServ = HtmlService.createTemplateFromFile("addDetailsBookingForm");
let order_id = getSheetOrderID(sheet); //let order_id = "98";
htmlServ.order = pullOrderStore(order_id) // let's say this is an array
const html = htmlServ.evaluate();
html.setWidth(850).setHeight(450);
const ui = SpreadsheetApp.getUi();
ui.showModalDialog(html, "form");
What I'd like to do is pass JSON across using this interface. However, objects are not supported from what I can understand. I can send strings, arrays but not objects.
However, it seems to me that I could turn a JSON object into a string, before sending it, and then parse it client side and turn it back into an object again.
Taking some inspiration from here, I was wondering if one could do something like
var htmlServ = HtmlService.createTemplateFromFile("addDetailsBookingForm");
let order_id = "98";
orderDetailsObject = pullFromWordPressOrder(order_id)
htmlServ.orderDetailsObject = JSON.stringify(orderDetailsObject)
Logger.log(htmlServ.orderDetailsObject)
<etc>
displayjsonfile.html
<script>
// this will output orderDetailsObject from the server side into orderDetailsObject on the client side. Despite the name, they're totally different variables.
var orderDetailsObject = <?=orderDetailsObject?>;
var product_object = JSON.parse(orderDetailsObject);
console.log(product_object)
var order_id = product_object.id //ToTest
example JSON
{"id":98,"parent_id":0,"status":"pending","currency":"GBP","version":"6.5.1","prices_include_tax":false,"date_created":"2022-08-11T20:12:58","date_modified":"2022-08-12T13:07:32","discount_total":"0.00","discount_tax":"0.00","shipping_total":"0.00","shipping_tax":"0.00","cart_tax":"0.00","total":"30.00","total_tax":"0.00","customer_id":17,"order_key":"wc_order_f368FMstESsXn","billing":{"first_name":"Freddie","last_name":"Flintoff","company":"","address_1":"a place","address_2":"","city":"a town","state":"derby","postcode":"sk13 7rx","country":"","email":"freddie#example.com","phone":"01234123123"},"shipping":{"first_name":"Freddie","last_name":"Flintoff","company":"","address_1":"a place","address_2":"","city":"a town","state":"derby","postcode":"sk13 7rx","country":"","phone":""},"payment_method":"","payment_method_title":"","transaction_id":"","customer_ip_address":"94.118.139.237","customer_user_agent":"","created_via":"admin","customer_note":"","date_completed":null,"date_paid":"2022-08-11T20:13:46","cart_hash":"","number":"98","meta_data":[{"id":1441,"key":"_new_order_email_sent","value":"true"},{"id":1442,"key":"_automatewoo_order_created","value":"1"}],"line_items":[{"id":50,"name":"Tim's Bike shed","product_id":75,"variation_id":0,"quantity":1,"tax_class":"","subtotal":"30.00","subtotal_tax":"0.00","total":"30.00","total_tax":"0.00","taxes":[],"meta_data":[],"sku":"","price":30,"parent_name":null}],"tax_lines":[],"shipping_lines":[],"fee_lines":[],"coupon_lines":[],"refunds":[],"payment_url":"https://dev1.example.com/checkout/order-pay/98/?pay_for_order=true&key=wc_order_f368FMstESsXn","date_created_gmt":"2022-08-11T20:12:58","date_modified_gmt":"2022-08-12T13:07:32","date_completed_gmt":null,"date_paid_gmt":"2022-08-11T20:13:46","currency_symbol":"£","_links":{"self":[{"href":"https://dev1.example.com/wp-json/wc/v3/orders/98"}],"collection":[{"href":"https://dev1.example.com/wp-json/wc/v3/orders"}],"customer":[{"href":"https://dev1.example.com/wp-json/wc/v3/customers/17"}]}}
Currently the JSON object outputs in the html as
var orderDetailsObject = '{\x22id\x22:98,\x22parent_id\x22:0,\x22status\x22:\x22pending\x22,\x22currency\x22:\x22GBP\x22,\x22version\x22:\x226.5.1\x22,\x22prices_include_tax\x22:false,\x22date_created\x22:\x222022-08-11T20:12:58\x22,\x22date_modified\x22:\x222022-08-12T13:07:32\x22,\x22discount_total\x22:\x220.00\x22,\x22discount_tax\x22:\x220.00\x22,\x22shipping_total\x22:\x220.00\x22,\x22shipping_tax\x22:\x220.00\x22,\x22cart_tax\x22:\x220.00\x22,\x22total\x22:\x2230.00\x22,\x22total_tax\x22:\x220.00\x22,\x22customer_id\x22:17,\x22order_key\x22:\x22wc_order_f368FMstESsXn\x22,\x22billing\x22:{\x22first_name\x22:\x22Freddie\x22,\x22last_name\x22:\x22Flintoff\x22,\x22company\x22:\x22\x22,\x22address_1\x22:\x22a place\x22,\x22address_2\x22:\x22\x22,\x22city\x22:\x22a town\x22,\x22state\x22:\x22derby\x22,\x22postcode\x22:\x22sk13 7rx\x22,\x22country\x22:\x22\x22,\x22email\x22:\x22freddie#example.com\x22,\x22phone\x22:\x2201234123123\x22},\x22shipping\x22:{\x22first_name\x22:\x22Freddie\x22,\x22last_name\x22:\x22Flintoff\x22,\x22company\x22:\x22\x22,\x22address_1\x22:\x22a place\x22,\x22address_2\x22:\x22\x22,\x22city\x22:\x22a town\x22,\x22state\x22:\x22derby\x22,\x22postcode\x22:\x22sk13 7rx\x22,\x22country\x22:\x22\x22,\x22phone\x22:\x22\x22},\x22payment_method\x22:\x22\x22,\x22payment_method_title\x22:\x22\x22,\x22transaction_id\x22:\x22\x22,\x22customer_ip_address\x22:\x2294.118.139.237\x22,\x22customer_user_agent\x22:\x22\x22,\x22created_via\x22:\x22admin\x22,\x22customer_note\x22:\x22\x22,\x22date_completed\x22:null,\x22date_paid\x22:\x222022-08-11T20:13:46\x22,\x22cart_hash\x22:\x22\x22,\x22number\x22:\x2298\x22,\x22meta_data\x22:[{\x22id\x22:1441,\x22key\x22:\x22_new_order_email_sent\x22,\x22value\x22:\x22true\x22},{\x22id\x22:1442,\x22key\x22:\x22_automatewoo_order_created\x22,\x22value\x22:\x221\x22}],\x22line_items\x22:[{\x22id\x22:50,\x22name\x22:\x22Tim\x27s Bike shed\x22,\x22product_id\x22:75,\x22variation_id\x22:0,\x22quantity\x22:1,\x22tax_class\x22:\x22\x22,\x22subtotal\x22:\x2230.00\x22,\x22subtotal_tax\x22:\x220.00\x22,\x22total\x22:\x2230.00\x22,\x22total_tax\x22:\x220.00\x22,\x22taxes\x22:[],\x22meta_data\x22:[],\x22sku\x22:\x22\x22,\x22price\x22:30,\x22parent_name\x22:null}],\x22tax_lines\x22:[],\x22shipping_lines\x22:[],\x22fee_lines\x22:[],\x22coupon_lines\x22:[],\x22refunds\x22:[],\x22payment_url\x22:\x22https:\/\/dev1.example.com\/checkout\/order-pay\/98\/?pay_for_order=true\x26key=wc_order_f368FMstESsXn\x22,\x22date_created_gmt\x22:\x222022-08-11T20:12:58\x22,\x22date_modified_gmt\x22:\x222022-08-12T13:07:32\x22,\x22date_completed_gmt\x22:null,\x22date_paid_gmt\x22:\x222022-08-11T20:13:46\x22,\x22currency_symbol\x22:\x22£\x22,\x22_links\x22:{\x22self\x22:[{\x22href\x22:\x22https:\/\/dev1.example.com\/wp-json\/wc\/v3\/orders\/98\x22}],\x22collection\x22:[{\x22href\x22:\x22https:\/\/dev1.example.com\/wp-json\/wc\/v3\/orders\x22}],\x22customer\x22:[{\x22href\x22:\x22https:\/\/dev1.example.com\/wp-json\/wc\/v3\/customers\/17\x22}]}}';
Clearly - it's being encoded/decoded poorly - specifically speech marks are coming out encoded.
Is this expected - or is there a better way to do this?
To be clear - it works, but it feels like it isn't pretty... not to mention not best practice.
Here is an example of how to pass a JSON object to the client.
Code.gs
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename)
.getContent();
}
function showTest() {
var myObject = { name: "MyTest", value: 100 };
var html = HtmlService.createTemplateFromFile("HTML_Test");
html.myObject = JSON.stringify(myObject);
SpreadsheetApp.getUi().showModalDialog(html.evaluate(),"Test");
}
HTML_Test.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<input id="name" type="text">
<br>
<input id="value" type="text">
<script>
var myObject = <?= myObject ?>;
(function() {
myObject = JSON.parse(myObject);
document.getElementById("name").value = myObject.name;
document.getElementById("value").value = myObject.value;
})();
</script>
</body>
</html>
Screenshot
Here's a reference the parameters and return values that can cause problem where passing objects with google.script.run.
The date has got me in the past. If you have a date in a cell and the cell is formatted to display it as a string, the use getDisplayValues() and pass it as a string and then use new Date() constructor to return it back to a date on the server side.
Other than that pretty much any object will work that can be stringified.
I want to send arbitrarily complex array data to a Java servlet, but have no idea how to read it on the servlet side. Here is the client side:
var data = {
name : 'Jack',
age : 30,
info : [ [1,2] , [3,4] , [5,6] ],
info2: [1,2,3]
}
$.ajax({
url: someURL,
data: data,
success: function(resp) { console.log(resp); }
});
I know I can use JSON.stringify and then parse it out on the server side, but for the sake of this question, I can't change the front end code. How do I read the "info" variable on the server side using the HttpServletRequest object? I also know you can do something like this for single arrays:
String[] info2 = request.getParameterValues("info2[]");
But this doesn't work with 2D arrays or more complicated arrays.
Any ideas?
If info is known to be a fixed-length array
private static final int INFO_LEN = 3;
You can collect its values inside your servlet as
String[][] info = new String[INFO_LEN][];
for (int i = 0; i < info.length; i++) {
info[i] = request.getParameterValues("info["+i+"][]");
}
If the length is not known beforehand, collect the values in a loop until you get a null.
How can I create a Perl array from a JavaScript array that is passed via AJAX?
Perl Access:
#searchType = $cgi->param('searchType');
print #searchType[0];
Output:
employee,admin,users,accounts
It seems that the Perl array sets the first value (#searchType[0]) as a string of all the passed JavaScript array objects.
It is an old question, so I am not sure whether that is still interesting for you but maybe someone else is interested in this question, too.
As already suggested in the comments above, one way to pass a javascript array to Perl via ajax is to convert this array first to an JSON object - using "JSON.stringify(jsArray);" - which is then decoded in the Perl script. I added a very simple example below where the first item of your array is returned through an alert.
index.html:
<!DOCTYPE html>
<html>
<head>
<title>Testing ajax</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$("#test").click(function(){
var jsArray = ["employee", "admin", "users", "accounts"];
var jsArrayJson = JSON.stringify(jsArray);
$.ajax({
type: 'POST',
url: '/cgi-bin/ajax/stackCGI/processJsArray.pl', //change the path
data: { 'searchType': jsArrayJson},
success: function(res) {alert(res);},
error: function() {alert("did not work");}
});
})
})
</script>
</head>
<body>
<button id="test" >Push</button>
</body>
</html>
processJsArray.pl
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
use JSON;
my $q = CGI->new;
my #myJsArray = #{decode_json($q->param('searchType'))}; #read the json object in as an array
print $q->header('text/plain;charset=UTF-8');
print "first item:"."\n";
print $myJsArray[0]."\n";
You need to express it in the form of key=value&key=other-value.
var searchType = ["employee", "admin", "users", "accounts"];
var keyName = "searchType";
for (var i = 0; i < searchType.length; i++) {
searchType[i] = encodeURIComponent(keyName) + "=" + encodeURIComponent(searchType[i]);
}
var queryString = searchType.join("&");
Then you use the queryString as part of your URL or post data as normal.
Im trying to get autocomplete-rails.js working in Rails with Ajax,
i Have the following function
<script type="text/javascript">
function reply_click(clicked_id)
{
var x = "work";
var y = "monday"
alert(y)
$.ajax({
type : 'POST',
url : "/whens",
data: { y : x},
success : function(data) {
alert(data);
},
});
}
</script>
The problem im getting is that this returns
"y"=>"work"
and i want it to return the value of y instead
"monday"=>"work"
Also, if i do the following
<script type="text/javascript">
function reply_click(clicked_id)
{
var x = "work";
var y = "monday"
var data = {};
data[x] = y;
$.ajax({
type : 'POST',
url : "/whens",
data,
success : function(data) {
alert(data);
},
});
}
</script>
it seems to return The problem im getting is that this returns
"term"=>"work"
Any idea how i can get it returning the contents of y
If a key doesn't have quotes, that doesn't mean it's using a variable.
The correct way of doing it, as you mention is
var data = {};
data[y] = x;
$.ajax({
type : 'POST',
url : "/whens",
data : data,
success : function(data) {
alert(data);
},
});
Note I changed it to data[y] = x;
if u want to load some data using ajax which in return can be used for auto-complete then load the array of strings by ajax.
eg.
in controller do-
def get_characteristics
unless ['Threads', 'Note'].include?(params[:name])
#characteristics = Category.all.collect(&:characteristic)
respond_to do |format|
format.js{}
end
end
in get_characteristics.js.haml (eg is in haml)
var characteristics = #{#characteristics.to_json};
$('#characteristic').autocomplete( //the id of the text fields where u want autocomplete
source: characteristics //the array of string that u want for autocomplete
)
for additional info http://jqueryui.com/demos/autocomplete/
variable as index in an associative array - Javascript
> var x = "work"
> var y = "monday"
> data= {}
{}
> data[x]=y
'monday'
> data
{ work: 'monday' }
You can't, the second snippet (data[y] =) is the only way. Here's why:
An object literal, like all things in JS is an object (duh) and has properties. All variables declared in the global scope are properties of the global (nameless) object. The only (semi-)true variables you have are the ones you declare in a closure scope. So looking at it from that viewpoint, it stands to reason that properties should not be quoted when constructing an object literal. I'd even go as far as to say that allowing quoted properties in the declaration of an object literal should be considered wrong, or it should -at the very least- be discouraged.
JS is a wonderful language, covered up by a pile of inconsistencies, quirks and bad ideas. Sadly, if all you know is the gunk (almost everybody knows the gunk, few know the actual language and where it gets its power) the rare features that are consistent and good look like an obstacle at first. Thankfully, you have tons of constructs that enable you to do just what you want, and do it well.
In this case, you could just write it all out data[a] = b; data[c] = d;... OR you could use a power-constructor (google it)
An other option is just a very small loop, assuming your data object will be filled using the arguments passed to the function:
var data = {};
var argArray = Array.prototype.slice.apply(arguments,[0]);//returns array of arguments
var duo;
while(duo = argArray.splice(0,2))
{
data[duo[0]] = duo[1];
if (argArray.length < 2)
{
break;
}
}
just to give an example. I'd recommend you (and everyone else) to look into crockfords constructions when it comes to objects, and what a function call entails in JS: a function isn't just called, a call-object is created.
I am grabbing data from a Google spreadsheet through the Google API using cURL in PHP. Using a AJAX HTTP request (via jQuery) I can pull all the data in and get it into an array, but since the <content> tag looks like dirty JSON I'm a little stuck.
I would like to be able to reference the data as a JS object, like so:
alert(xml.feed.content.name);
Example Code:
$.ajax({
type: "GET",
url: GtargetURL,
dataType: "xml",
success: function parseMyXML(xml){
var Entries = new Array;
var i = 0;
$(xml).find("entry").each(function(){
var content = $(this).find("content").text();
Entries[i]=content;
i++;
});
var myArray= new Array();
myArray= Entries[1].split(",");
alert (myArray[1]); // Result: "test2"
}
});
Example XML:
<feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:gsx=
<entry>
<content type='text'>relativeid: 4, name: test2, type: teset3, multiples: yes, cat: yes</content>
</entry>
<entry>many more entries...</entry>
</feed>
Thanks for any help you can offer.
For what it's worth, I am using this URL format for the Google api call:
https://spreadsheets.google.com/feeds/list/KEY-ID-HERE/1/public/basic
I know that I can do a "cell" call instead of a "list" call, but this suits my purposes better.
You could do something like this: http://jsfiddle.net/GVUnF/ http://jsfiddle.net/rMMkD/1/ in your loop.
var jsonLikeString = "name:red, type:blue, multiples:green, cat:brown";
var jsObject = {};
var stringWithoutSpaces = jsonLikeString.split(' ').join('');
var splitStrings = stringWithoutSpaces.split(",");
var kvPairArray = [];
for(var i in splitStrings){
if(splitStrings.hasOwnProperty(i)){
var kvPair = splitStrings[i];
kvPairArray = kvPair.split(":");
jsObject[kvPairArray[0]] = kvPairArray[1];
}
}
alert(jsObject.cat);
Please note that
var foo = new Array;
is not exactly idiomatic in javascript.
You should use
var foo = [];
instead.
Also, for appending to an array you should use
foo.push('something');
instead of having a variable i and incrementing it every loop.
There are two parts to your question:
How to turn XML into JSON
How to turn some text in XML that is almost JSON into JSON
To make XML into JSON you can use a library like http://www.thomasfrank.se/xml_to_json.html
It turns
<animals>
<dog>
<name>Rufus</name>
<breed>labrador</breed>
</dog>
<dog>
<name>Marty</name>
<breed>whippet</breed>
</dog>
<cat name="Matilda"/>
</animals>
Into
{"animals":
{"dog":[
{"name":"Rufus",
"breed":"labrador"},
{"name":"Marty",
"breed":"whippet"}],
"cat":
{"name":"Matilda"}}}
Then you can follow the suggestion from TheShellfishMeme to turn
relativeid: 4, name: test2, type: teset3, multiples: yes, cat: yes
Into a JSON object