I've got this website: https://coinyep.com/he/ex/ETH-ILS
Inside this URL web page, there is an input element, and its HTML id is: "coinyep-input2".
I need to read its value (= approximately 637.49 ILS) using jQuery in Visual Studio.
So far, I tried everything, no success.
Any help will be appreciated.
For example, in jQuery there is a command :
document.getElementById("coinyep-input2");
==> I need to do the same thing but to do it from the URL page in order to get values in real-time (exchange rates).
Does this help?
$("#coinyep-input2").attr("data-valuta");
or
$("#coinyep-input2").attr("data-value");
or
$("#coinyep-input2").val();
For now, I found solution in C# (server), using it by Razor on the client
[Based on RSS URL]:
public float getExchangeRate_ETH_To_ILS()
{
float exchangeRate;
string[] words;
int indexOfExchangeRate;
using (var client = new WebClient())
{
try
{
var htmlPage = client.DownloadString("https://coinyep.com/he/rss/ETH-ILS.xml");
words = htmlPage.Split(' ');
indexOfExchangeRate = words.IndexOf("ILS");
exchangeRate = (float)Convert.ToDouble(words[indexOfExchangeRate - 1]);
}
catch(Exception e)
{
exchangeRate = -1;
}
}
return exchangeRate;
}
in the client, I use this fucntion via model (Razor):
var cal1 = #Model.getExchangeRate_ETH_To_ILS();
But there is a risk: if the template of the RSS will be changed, we are in trouble.
Related
I am creating a Google Apps Script which takes the data from Google Sheets and renders it to jquery datatable.
CASE 1: (ifUsingSheetAsDB = TRUE) I am able to fetch and render the data successfully by filtering required data to a short Google sheet's table (short table) in a separate sheet from a large table (big table) using Google sheet's Filter formula and then reading that filtered table in my .gs file. This case in the code is wrapped with "ifUsingSheetAsDB"
My final data coming from .gs file to datatable is (in this case)
function userClickedCheck(name, code) {
var ret = validator(name, code); //name-code checker
var range = wsTest.getRange("A2:A").getValues(); //short table is generated in the sheet Test here
if(gInDebug || gAppDebug)
{
Logger.log("ret" + ret); //checking validation
}
if(ret == 1) //success
{
if(ifUsingSheetAsDB) //reading "short table" from G Sheet
{
var rangelen = range.length;
//Logger.log(range.getDisplayValues());
var lastRow = getLastRowSpecial(range); //custom function which finds the last filled row
range = wsTest.getRange("A2:L" + (lastRow + 1)); //last filled row is the table length
range = range.getDisplayValues(); //GSheet API returns string[][]
}
else
{
//TODO without sheet as DB////////////////////////
range = garySelectedRange; //declared as let garySelectedRange = [];
//TODO without sheet as DB end ////////////////////////
}
}
else
{
range = [[]];
}
if(gAppDebug || gInDebug)
{
Logger.log("length of range " + range.length); //Apps Script Point 1
Logger.log(range); //Apps Script Point 2
}
return range;
}
The range is captured in the datatable js as below:
function checkFinished(rangeValues)
{
if ( ! table.data().any() )
{
//alert( 'Empty table' );
}
else
{
table
.clear()
.draw();
}
//var len2D = rangeValues.length;
//alert("Reached inside SubmitFinished " + len2D);
//TODO debug
console.log("printing rangeValues " + rangeValues.length) //console debug
console.table(rangeValues); //console debug
//TODO debug end
table.rows.add( rangeValues )
.draw();
}
This is working real good. No issues here. I have read about range.getDisplayValues(); which returns string[][] according to https://developers.google.com/apps-script/reference/spreadsheet/range
Case 2: (ifUsingSheetAsDB = FALSE) Now I want to replace the data fetch and instead of using G Sheet's integrated Filter functions in the sheet, I am processing the whole "big table" by fetching data to .gs file and using my custom Filter:
function filterAndCreate(name)
{
var inneri = 0;
var innerj = 0;
for (var i in garyRangePO)
{
if(garyRangePO[i][1] == name)
{
garySelectedRange.push(
[
garyRangePO[i][0] + "/2122",
garyRangePO[i][5],
garyRangePO[i][6],
garyRangePO[i][7],
garyRangePO[i][8],
garyRangePO[i][9],
garyRangePO[i][10],
garyRangePO[i][11],
garyRangePO[i][12],
garyRangePO[i][14],
garyRangePO[i][13],
garyRangePO[i][20]
]
);
}
}
if(gInDebug || gAppDebug)
{
Logger.log(garySelectedRange);
}
}
.js side it's the same function.
where garyRangePO is "big table" and garySelectedRange is "short table" and declared as
let garyRangePO = [];
let garySelectedRange = [];
in global scope.
If I debug this in Apps Script, my debug points when success gives me something like this:
CASE 1:
CASE 2:
Everything looks great till now from return value perspective too.
For both the cases Apps Script debugger is showing type as
However, when I actually run my code...
Case 1 console log (where data is properly populated to datatable and works like a charm):
Case 2 console log:
Now here I need help please.
I am new to js and webapp and all. So please pardon me in advance.
Thank you.
First of all, pardon me if my concepts are wrong, but I am yet a starter with all of these.
So basically, it looks like GAS is re-initiating globally scoped vars on the server-side every time before a function in the .gs (server-side code) is executed. Now to solve this issue, one can follow How to define global variable in Google Apps Script
It works but doesn't solve my query, as this [key, value] is same for every connection created to the app. Meaning, if two users are using this app simultaneously, irrespective of the function they are executing at T=t, this value will be same for both. I am not sure how to use this answer if someone is looking for a parallel multi-user app which shares a common DB written in the Sheets. (Maybe check for bind and release and add keys as an array representing each connection?)
Also,
My code is using big sum of global data, and I feared saving that whole matrix in 'myvalue' and creating array for 'mykeys' for each connection,
PropertiesService.getScriptProperties().setProperty('mykey', 'myvalue');
var myvalue = PropertiesService.getScriptProperties().getProperty('mykey');
However, I had re-initiated required data every time when a function is executed for a connection according to the input from client-side js. I think this is not a solution, but this works and takes a bit more time while executing.
FiddlerScript is capable of JSON parsing and modification. For example, the following addition to OnBeforeResponse will sneakily replace Ipify's returned external IP address with 127.0.0.1:
if (oSession.url == "api.ipify.org/?format=json"){
var j = GetResponseJson(oSession);
j["ip"] = "127.0.0.1";
SetResponseJson(oSession, j);
}
where GetResponseJson and SetResponseJson are helper functions I made from Eric's linked answer:
static function GetResponseJson(oSession: Session){
return Fiddler.WebFormats.JSON.JsonDecode(oSession.GetResponseBodyAsString()).JSONObject;
}
static function SetResponseJson(oSession: Session, j){
oSession.utilSetResponseBody(Fiddler.WebFormats.JSON.JsonEncode(j));
}
This is great for modifying JSON payloads intercepted by Fiddler.
My question is:
Is there an equivalent way to parse and modify XML in FiddlerScript?
FiddlerScript uses JScript.NET, and thus can reference .NET assemblies, including System.Xml, which contains the XmlDocument class.
First, in Fiddler > Tools > Fiddler Options > Extensions, add a reference to System.Xml.dll:
Next, at the top of FiddlerScript, reference it:
import System.Xml;
At that point, you can create XmlDocument objects:
var x = new XmlDocument();
To add a custom column from a node in XML in the response, you need to use FiddlerScript.
What is required when you have loaded the System.xml reference, in the FiddlerScript (Rules > Customize Rules), you can add :
public static BindUIColumn("Request")
function testXmlColumn(oSession: Session){
if (oSession.oResponse != null && oSession.oResponse["Content-Type"] == "text/xml; charset=utf-8") {
var doc = new XmlDocument();
doc.LoadXml(oSession.GetResponseBodyAsString());
var xPathString = '/an/XPath/Expression';
var xmlNode = doc.DocumentElement.SelectSingleNode(xPathString);
return xmlNode.InnerText;
}
return "";
}
Obviously, you need to replace /an/XPath/Expression with an XPath expression. This is fairly simple language to match a node.
I have a website that uses AJAX to deliver a JSON formatted string to a HighCharts chart.
You can see this as the middle JSON code part at:
http://jsfiddle.net/1Loag7pv/
$('#container').highcharts(
//JSON Start
{
"plotOptions": {
"series": {"animation": {"duration": 500}}
,"pie": {
"allowPointSelect": true,
"cursor": "pointer",
"dataLabels": {"formatter":function(){return this.point.name+': '+this.percentage.toFixed(1) + '%';}}
}
},
"chart":{"renderTo":"divReportChart"}
,"title":{"text":"Sales Totals"}
,"xAxis":{"title":{"text":"Item"}, "categories":["Taxes","Discounts","NetSalesTotal"], "gridLineWidth":1}
,"yAxis":[{"title":{"text":"Amount"}, "gridLineWidth":1}]
,"series":[{"name":"Amount","type":"pie", "startAngle": -60,"yAxis": 0,"data":[["Taxes",17.8700],["Discounts",36.0000],["NetSalesTotal",377.9500]]}]
}
//JSON end
);
The problem is that the function part...
"dataLabels": {"formatter":function(){return this.point.name+': '+this.percentage.toFixed(1) + '%';}}
is not being transferred via the JSON
All research tells me that there is NO WAY to do this.
IE... Is it valid to define functions in JSON results?
Anybody got an idea on how to get around this limitation?
It is true that you cannot pass functions in JSON. Javascript is a superset of JSON.
A common approach is for the chart to be defined in javascript (e.g. during the page load), and the page then requests just the data via Ajax. When the data is returned it can be added to the chart object, either before it is rendered or afterwards using the highcharts API.
If you really want to pass the formatter function from the server with the chart, send it as a string, and then turn it into a function like this:
var fn = Function(mystring);
and use it in highcharts like:
chart.plotOptions.pie.dataLabels = {"formatter":fn};
I've re-factored your example to show the approach: http://jsfiddle.net/wo7zn0bw/
I had a similar conundrum. I wanted to create the JSON server side (ruby on rails) so I could create images of charts for a web API and also present it on the client web browser with the same code. This is similar to SteveP's answer.
To conform with JSON standards, I changed all formatter functions to strings
{"formatter": "function(){ return this.point.name+':'+this.percentage.toFixed(1) + '%';}"}
On the web side, I navigate the hash looking for formatter keys and replace them with the function using this code (may be a better way!?). javascript:
function HashNavigator(){
this.navigateAndReplace = function(hash, key){
if (!this.isObject(hash)){
//Nice if only navigated hashes and arrays
return;
}
var keys = Object.keys(hash);
for(var i = 0; i< keys.length; i++){
if (keys[i] == key){
//convert string to js function
hash[keys[i]] = this.parseFunction(hash[keys[i]]);
} else if (this.isObject(hash[keys[i]])){
//navigate hash tree
this.navigateAndReplace(hash[keys[i]], key);
} else {
//continue
}
}
};
this.isObject = function(testVar) {
return testVar !== null && typeof testVar === 'object'
}
//http://stackoverflow.com/questions/7650071/is-there-a-way-to-create-a-function-from-a-string-with-javascript
this.parseFunction = function(fstring){
var funcReg = /function *\(([^()]*)\)[ \n\t]*{(.*)}/gmi;
var match = funcReg.exec(fstring.replace(/\n/g, ' '));
if(match) {
return new Function(match[1].split(','), match[2]);
}
return null;
};
}
To use this, would be something similar to this javascript:
hashNavigator = new HashNavigator();
hashNavigator.navigateAndReplace(myHighchartsHash, "formatter")
At that point the hash/js-object is Highcharts ready
Similar idea was used for the web image API.
I was really hoping that hacking at the JSON was not the only solution, but it works!
I used a different approach. I created a JSON like below
{"formatter": "function(){ return this.point.name+':'+this.percentage.toFixed(1) + '%';}"}
When I came to evaluating the expression, I used (assuming that the value of the 'formatter' is formatterValueString)
formatterValueString = formatterValueString.replace('function()', '');
let opts = (new Function(formatterValueString)).call(this);
formatterValue = opts;
The reason to use this approach was it became hard to bind 'this' with the function. The eval() function did not go well with accessing variable this. I am sure there are ways to do it. Just thought this was quick.
I am working on an online shop together with my friend. He set a cookie for me with PHP with the amount of added products to the Cart. The cookie is called "cart", and the variable with the amount of the products is called "items".
And I have to read the cookie and get the value of "cart" back with javascript and print it in the HTML document, but I have no Idea how to use it, can you please help me? I have never worked with cookies or JSON before, but I think it should be done with JSON, can you please explain it to me how it works?
when I do : console.log(document.cookie);
I receive something like this: cart=%7B%22items%22%3A%7B%228%22%3A1%7D%7D;
And I have no idea how to encode it.
Thank you
That is the URL encoded equivalent of {"items":{"8":1}} which is the JSON string you want.
All you have to do is decode it and parse the JSON:
var cart = JSON.parse(decodeURIComponent(document.cookie.cart));
Then logging cart should give you an object with an 'items' property that you can access as needed.
EDIT:
As an example, here's a way to iterate through the items and determine the total number of items and the total of all their quantities.
var items_total = 0,
quantity_total = 0;
for (var prop in cart.items) {
items_total += 1;
quantity_total += cart.items[prop];
}
console.log("Total Items: " + items_total);
console.log("Total Quantities: " + quantity_total);
Looks like you just need to decode it, then you will want to parse/eval it to get a workable object:
var obj, decoded = decodeURIComponent(document.cookie.cart);
if(window.JSON && JSON.parse){
obj = JSON.parse(decoded);
} else {
eval('obj = ' + decoded);
}
// obj == {"items":{"8":1}};
i'm newbie in javascript so, in this example exists the geometrycontrols.js (for global controls) and markercontrol.js (for marker controls)
my problem is identify the arrays where "data" is saved...
at the reference i see a savedata function but i have no idea how work with this function...
on the other side, in test.html if i've the outup on the Glog startup and output "data", and let me thinking that comes from array...
My objective is save the coordinates and other all atributes to mysql database, and when i discover where are "data" is the easy part.
if someone worked with this example (or not) can help me i'm grateful
ps: i'm really a newbie on javascript :P
edit1:
I was out for a time, and now I focus in geometrycontrols.js specially in: GeometryControls.prototype.saveData = function(opts){
var me = this;
if(opts.allData === true){
//me.saveAllData();
} else {
//construct a json data record
var geomInfo = opts.geomInfo, index = opts.geomInfo.index;
var record = geomInfo.storage[index];
var recordJSON = {};
recordJSON.type = record.type;
recordJSON.coordinates = [];
//determine geometry type, and copy geometry appropriately
if(record.type === "point"){
recordJSON.coordinates.push({lat:record.geometry.getLatLng().lat(),lng:record.geometry.getLatLng().lng()});
alert(recordJSON.coordinates);
} else {
alert("is not point");
var vertex;
for(var i=0;i<record.geometry.getVertexCount();i++){
vertex = record.geometry.getVertex(i);
recordJSON.coordinates.push({lat:vertex.lat(),lng:vertex.lng()});
}
}
//add title and description
recordJSON.title = record.title[0];
recordJSON.description = record.description[0];
//TODO add styles
recordJSON.style = ""; //TODO} //TODO Make separate prototype function?function postData(data){
//TODO
me.debug(data);
//alert(recordJSON.coordinates);
//alert(data);
};postData(me.serialize(recordJSON));}; `
When I alert(recordJSON.coordinates), the outupt is [object Object] and i've no idea why, in theory this array contains the coordinates...
Here is some code I have used to send the data to MySQL. It uses a little bit of jQuery to do the ajax magic (the line starting with the dollarsign is jQuery).
function postData(data){
me.debug(data);
var dataString = JSON.stringify(data);
me.debug(dataString);
$.post('storage.php', { data: dataString });
};
postData(recordJSON);
As you can see I've modified the way the 'recordJSON' object gets sent to the postData function a bit too: I've removed the serialise function.
Next, create a PHP file (called 'storage.php' in my case) and put this in it:
<?php
$received = json_decode($_POST['data'], true);
echo "just received " . $received['name'];
?>
You now have an array in PHP that you can do with as you please.
In the examplecode above I've modified the jQuery post function a bit, so if it doesn't work, look there.
The data is stored in JSON format in this file: http://gmaps-utility-library-dev.googlecode.com/svn/trunk/geometrycontrols/examples/data/testdata.js -- it's pretty much self-documenting, just follow the example to set your coordinates.
Note that if you need to find the latitude and longitude for a given address this is a good site: http://itouchmap.com/latlong.html