I know how to pass data with a jinja template from python into javascript, but I want to pass a javascript variable into python. I'd like to do it without reloading the page. Is that possible?
Yes, like monkut said--I believe you want to use JSON and Javascript/jQuery.
This will let allow communication from client to server and back again.
The most applicable example I found was in the Flask snippets/patterns: http://flask.pocoo.org/docs/patterns/jquery/
I did a similar kind of work in my project and would like to share my code here. I need to find out which post is selected and I was setting the selected post as a global variable at server side, so that I may use it for later comparison. This is how I pass my selected post into Javascript.
<a class="label label-primary" onclick="myFunction({{very.id}})" > Compare</a>
Now from Javascript to Flask.
function myFunction(x) {
$.getJSON($SCRIPT_ROOT + '/check_selected', {
post: x
}, function(data) {
var response = data.result;
console.log(response);
}
});
}
This is how I return the result from flask by using JSON.
import json
#main.route('/check_selected', methods=['GET','POST'])
def check_selected():
global selected
post = request.args.get('post', 0, type=int)
return json.dumps({'selected post': str(post)});
As mentioned here, we need to include Google AJAX API in order to load jquery:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="{{
url_for('static', filename='jquery.js') }}">\x3C/script>')</script>
Create a JSON string from your view code say, jsonData and in your Jinja Template, write something like
<script type="text/javascript">
var data = {{ jsonData }};
</script>
Related
I have this JSON file I generate in the server I want to make accessible on the client as the page is viewable. Basically what I want to achieve is:
I have the following tag declared in my html document:
<script id="test" type="application/json" src="http://myresources/stuf.json">
The file referred in its source has JSON data. As I've seen, data has been downloaded, just like it happens with the scripts.
Now, how do I access it in Javascript? I've tried accessing the script tag, with and without jQuery, using a multitude of methods to try to get my JSON data, but somehow this doesn't work. Getting its innerHTML would have worked had the json data been written inline in the script. Which it wasn't and isn't what I'm trying to achieve.
Remote JSON Request after page loads is also not an option, in case you want to suggest that.
You can't load JSON like that, sorry.
I know you're thinking "why I can't I just use src here? I've seen stuff like this...":
<script id="myJson" type="application/json">
{
name: 'Foo'
}
</script>
<script type="text/javascript">
$(function() {
var x = JSON.parse($('#myJson').html());
alert(x.name); //Foo
});
</script>
... well to put it simply, that was just the script tag being "abused" as a data holder. You can do that with all sorts of data. For example, a lot of templating engines leverage script tags to hold templates.
You have a short list of options to load your JSON from a remote file:
Use $.get('your.json') or some other such AJAX method.
Write a file that sets a global variable to your json. (seems hokey).
Pull it into an invisible iframe, then scrape the contents of that after it's loaded (I call this "1997 mode")
Consult a voodoo priest.
Final point:
Remote JSON Request after page loads is also not an option, in case you want to suggest that.
... that doesn't make sense. The difference between an AJAX request and a request sent by the browser while processing your <script src=""> is essentially nothing. They'll both be doing a GET on the resource. HTTP doesn't care if it's done because of a script tag or an AJAX call, and neither will your server.
Another solution would be to make use of a server-side scripting language and to simply include json-data inline. Here's an example that uses PHP:
<script id="data" type="application/json"><?php include('stuff.json'); ?></script>
<script>
var jsonData = JSON.parse(document.getElementById('data').textContent)
</script>
The above example uses an extra script tag with type application/json. An even simpler solution is to include the JSON directly into the JavaScript:
<script>var jsonData = <?php include('stuff.json');?>;</script>
The advantage of the solution with the extra tag is that JavaScript code and JSON data are kept separated from each other.
It would appear this is not possible, or at least not supported.
From the HTML5 specification:
When used to include data blocks (as opposed to scripts), the data must be embedded inline, the format of the data must be given using the type attribute, the src attribute must not be specified, and the contents of the script element must conform to the requirements defined for the format used.
While it's not currently possible with the script tag, it is possible with an iframe if it's from the same domain.
<iframe
id="mySpecialId"
src="/my/link/to/some.json"
onload="(()=>{if(!window.jsonData){window.jsonData={}}try{window.jsonData[this.id]=JSON.parse(this.contentWindow.document.body.textContent.trim())}catch(e){console.warn(e)}this.remove();})();"
onerror="((err)=>console.warn(err))();"
style="display: none;"
></iframe>
To use the above, simply replace the id and src attribute with what you need. The id (which we'll assume in this situation is equal to mySpecialId) will be used to store the data in window.jsonData["mySpecialId"].
In other words, for every iframe that has an id and uses the onload script will have that data synchronously loaded into the window.jsonData object under the id specified.
I did this for fun and to show that it's "possible' but I do not recommend that it be used.
Here is an alternative that uses a callback instead.
<script>
function someCallback(data){
/** do something with data */
console.log(data);
}
function jsonOnLoad(callback){
const raw = this.contentWindow.document.body.textContent.trim();
try {
const data = JSON.parse(raw);
/** do something with data */
callback(data);
}catch(e){
console.warn(e.message);
}
this.remove();
}
</script>
<!-- I frame with src pointing to json file on server, onload we apply "this" to have the iframe context, display none as we don't want to show the iframe -->
<iframe src="your/link/to/some.json" onload="jsonOnLoad.apply(this, someCallback)" style="display: none;"></iframe>
Tested in chrome and should work in firefox. Unsure about IE or Safari.
I agree with Ben. You cannot load/import the simple JSON file.
But if you absolutely want to do that and have flexibility to update json file, you can
my-json.js
var myJSON = {
id: "12ws",
name: "smith"
}
index.html
<head>
<script src="my-json.js"></script>
</head>
<body onload="document.getElementById('json-holder').innerHTML = JSON.stringify(myJSON);">
<div id="json-holder"></div>
</body>
place something like this in your script file json-content.js
var mainjson = { your json data}
then call it from script tag
<script src="json-content.js"></script>
then you can use it in next script
<script>
console.log(mainjson)
</script>
Check this answer: https://stackoverflow.com/a/7346598/1764509
$.getJSON("test.json", function(json) {
console.log(json); // this will show the info it in firebug console
});
If you need to load JSON from another domain:
http://en.wikipedia.org/wiki/JSONP
However be aware of potential XSSI attacks:
https://www.scip.ch/en/?labs.20160414
If it's the same domain so just use Ajax.
Another alternative to use the exact json within javascript. As it is Javascript Object Notation you can just create your object directly with the json notation. If you store this in a .js file you can use the object in your application. This was a useful option for me when I had some static json data that I wanted to cache in a file separately from the rest of my app.
//Just hard code json directly within JS
//here I create an object CLC that represents the json!
$scope.CLC = {
"ContentLayouts": [
{
"ContentLayoutID": 1,
"ContentLayoutTitle": "Right",
"ContentLayoutImageUrl": "/Wasabi/Common/gfx/layout/right.png",
"ContentLayoutIndex": 0,
"IsDefault": true
},
{
"ContentLayoutID": 2,
"ContentLayoutTitle": "Bottom",
"ContentLayoutImageUrl": "/Wasabi/Common/gfx/layout/bottom.png",
"ContentLayoutIndex": 1,
"IsDefault": false
},
{
"ContentLayoutID": 3,
"ContentLayoutTitle": "Top",
"ContentLayoutImageUrl": "/Wasabi/Common/gfx/layout/top.png",
"ContentLayoutIndex": 2,
"IsDefault": false
}
]
};
While not being supported, there is an common alternative to get json into javascript. You state that "remote json request" it is not an option but you may want to consider it since it may be the best solution there is.
If the src attribute was supported, it would be doing a remote json request, so I don't see why you would want to avoid that while actively seeking to do it in an almost same fashion.
Solution :
<script>
async function loadJson(){
const res = await fetch('content.json');
const json = await res.json();
}
loadJson();
</script>
Advantages
allows caching, make sure your hosting/server sets that up properly
on chrome, after profiling using the performance tab, I noticed that it has the smallest CPU footprint compared to : inline JS, inline JSON, external JS.
I'm working on a laravel project and am trying to pass an array from a controller to javascript. The following code is from my controller.
$dicomfilearray = $dicom->pluck('filename')->toArray();
return view('xray.view')->withDicomfilearray($dicomfilearray);
And below is the Javascript in that's in the blade file I'm trying to pass it to.
var dicomarray = '{{ json_encode($dicomfilearray) }}';
console.log(dicomarray);
And the following is a log result from the Javascript.
["storage/uploads/storeid1/27/10/dicom/c4p4Oco3rU.dcm","storage/uploads/storeid1/27/10/dicom/RNil0NPPzQ.dcm"]
I would like to get a list from this array. Any advice or guidance on this would be greatly appreciated, Thanks.
You can make ajax call in frotend, and backend do like this
$dicomfilearray = json_encode($dicom->pluck('filename'))->toArray());
return view('xray.view')->withDicomfilearray($dicomfilearray);
when you working in javascript and need data in javascript then why you need view part. Actually, I just read your comment.
If in Ajax
so I suggest send array with json_encode and populate that data into view with javascript.
simply right below in controller
response()->json(['status'=>200,'data'=>$dicomfilearray])
Update
So ,you not sending ajax request so, simply. do like below.
controller:-
$data = json_encode($dicomfilearray);
return view('your-view',compact('data'));
javascript
var dicomarray = '{{ $data }}';
You can do something like this and this even works if you want to pass the variable to external javascript file. All you have to do is to call the init function with passed parameters.
<script>
$(function () {
init({{ json_encode($dicomfilearray) }} });
function init(dicomfilearray){
//use your variable here
}
</script>
I need to get the data of productSkus[ using python but I don't know how to access it. the javascript comes from http://www.ulta.com/lid-lingerie-eye-tint?productId=xlsImpprod15361061 .
This is how it looks like.
<script type="text/javascript">
var currentSkuId = '2502111';
var currentProductId = 'xlsImpprod15361061';
var productSkus = new Object();
productSkus[2502111] =
{"displayName":"Fame & Fortune","id":"2502111","imgUrl":"http://images.ulta.com/is/image/Ulta/2502111?$detail$","largeImgUrl":"http://images.ulta.com/is/image/Ulta/2502111?$lg$","swatchImgUrl":"http://images.ulta.com/is/image/Ulta/2502111sw?$50px$","swatchHoverImgUrl":"http://images.ulta.com/is/image/Ulta/2502111sm?$md$","skuSize":"0.13","skuSizeUOM":"oz"};........
Can anyone help me with this?
If you want to use productSkus on the server side, then you need to use AJAX to send the JS variable to the server.
As Django template is compiled server side. It is then sent to the client where their browser executes the JavaScript. Nothing that is changed by the JavaScript executing on the client browser can have an affect on the template. It's too late at that point.
However the JavaScript could do something like make another request from the server for more information. Or you could just pre-compute the value on the server before you send it to the client.
You can of course use Django templates to set JavaScript variables.
<script>
var myVar = '{{ py_var }}';
</script>
use html form to submit the data to server, or across api
How do I extract the data below. I only want to print out the value number after "networkdiff" in this API.
This is the URL for the API from a different website:
http://21.luckyminers.com/index.php?page=api&action=getpoolstatus&api_key=8dba7050f9fea1e6a554bbcf4c3de5096795b253b45525c53562b72938771c41
I want the code to automatically retrieve the data from the URL above, and display the value after "networkdiff" to display on my other webpage.
Here's my code so far that I will put in my own webpage:
<HTML>
<body>
<script>
I don't know what I should put in this script part.
</script>
</body>
</html>
Below is the data the URL showed up as:
{
"getpoolstatus":{
"version":"1.0.0",
"runtime":10.684967041016,
"data":{
"pool_name":"21 Coin Pool # Luckyminers.com",
"hashrate":0,
"efficiency":97.79,
"workers":0,
"currentnetworkblock":0,
"nextnetworkblock":1,
"lastblock":40544,
"networkdiff":1,
"esttime":0,
"estshares":4096,
"timesincelast":1240429,
"nethashrate":0
}
}
}
Since the data is coming from an external domain, you can't use Ajax to get the data, unless the server enabled CORS. This doesn't seem to be the case, but it seems to support JSONP:
<script>
function processResponse(data) {
console.log(data);
}
</script>
<script src="http://21.luckyminers.com/index.php?page=api&...&callback=processResponse></script>
The callback=parseResponse makes the server return JS consisting of a function call to processResponse. How to access the information you actually want is explained in Access / process (nested) objects, arrays or JSON.
You need to include JSON.js in your web page to use JSON function in javascript. Here is the URL for download
https://github.com/douglascrockford/JSON-js
And then you can use beloe code to parse the JOSN string into javascript object.
var objectJSON = JSON.parse(jsonStr);
You can alse used stringify fucntion to the viceversa.
In which way you call the JSON?
You can call it with a callback function (working example), including it as a script:
updateResult=function()
{
var s=document.createElement('script');
s.src=domain+"/index.php?page=api&callback=showResult&action=getpoolstatus&api_key="+api_key;
document.body.appendChild(s);
}
You must have the callback defined like:
showResult=function(data)
{
document.getElementById('result').innerText=data.getpoolstatus.data.networkdiff;
}
If you call it with JQuery and get the JSON object, you can define the callback in the argument like the following example, but you must have same-origin (your script must run with the same domain (21.luckyminers.com in this case):
$.getJSON(
domain+"/index.php?page=api&action=getpoolstatus&api_key="+api_key,
function(data)
{
document.getElementById('result').innerText=data.getpoolstatus.data.networkdiff;
}
);
But in any case, be careful. Where did you get the API key? If you put it on a client-side script (like JavaScript) anybody can read the key, and with that key maybe do some damageā¦ :S
In my Django web application I've got a python script which generates an xml string. I can access this script by the help of Django so that the url 'my_python_script_file/' reference to the script (I do this so that I can dynamically generate it). My question is then simply, how do I pass this XML off to a variable in my javascript code, so that it would look like something like this?
var myXML = magic_function('my_python_script_file');
If you absolutely must reference the resulting XML from a URL, I would suggest getting it using the requests library:
import requests
from django.core.urlresolvers import reverse
from django.shortcuts import render
def my_view(request):
response = requests.get(reverse('your_url_name'))
xml = response.text
return render(request, 'your-template.html', {'xml': xml})
You can inject server-side values from Django into JavaScript like you would any other value, but you would need to do this in a <script> tag that is in your template, not in an external reference:
# your-template.html
<script type="text/javascript">
var xml = "{{ xml }}";
</script>