How to pass dictionary from Jinja2 (using Python) to Javascript? - javascript

How to pass dictionary from Jinja2 (using Python) to Javascript ?
I have dictionary in Python and when I render template I need to use that dictionary with Javascript, I passed from Python
template = JINJA_ENVIRONMENT.get_template('sm.html')
self.response.write(template.render(values=values))
but how to store them in Javascript variable inside html page.

Use the json module to turn the Python data into JSON data; JSON is a subset of JavaScript * and does fine as a JavaScript literal:
import json
js_value = json.dumps(python_value)
and render the js_value in the template.
If you need the JSON data to be HTML safe too, you'll need to add some replacements:
js_value = (json.dumps(python_value)
.replace(u'<', u'\\u003c')
.replace(u'>', u'\\u003e')
.replace(u'&', u'\\u0026')
.replace(u"'", u'\\u0027'))
*JSON allows for U+2028 and U+2029 characters which JavaScript literals can't contain, but the json.dumps() function escapes all non-ASCII codepoints by default, so provided you don't disable ensure_ascii you are fine.

You want to store it as Json. This is javascript's native format, so you can pass that directly to a variable.

Related

JSON encoding Flask to Javascript [duplicate]

This question already has answers here:
JavaScript raises SyntaxError with data rendered in Jinja template
(3 answers)
Closed 6 years ago.
I am sitting on a Flask based webapplication. In theory I want to load a JSON file from disk and give it to javascript on the website.
def getData():
check_for_update()
with open(LOCAL_file,"rb") as myfile:
data = json.load(myfile)
udate = data["today"]
return (udate, data)
then I send it to the page with
return render_template('./index2.html', udate = thisdata[0], data = json.dumps(thisdata[1]))
Now on the page I simply try
<script>
var myjson = JSON.parse({{data}})
</script>
which then results in something like this
This can't not be parsed.When I copy and paste it it works fine, and python does not complain either.
data is HTML escaped, because Jinja2 by default escapes everything to be safe to embed in an HTML page.
It's much better to not encode to JSON in the view, do this in the template instead, and use the Flask tojson and safe filters.
So in the view pass in thisdata[1] unencoded:
return render_template(
'./index2.html', udate=thisdata[0], data=thisdata[1])
and in the view:
<script>
var myjson = {{ data|tojson|safe }};
</script>
tojson produces JSON data that is also HTML-safe (albeit with " quotes, so it is not suitable for embedding in a HTML tag attribute), and the safe filter can be used to switch off the HTML-encoding. There is no need to use JSON.parse() here, the resulting JSON produced by tojson is a strict JavaScript subset.
See the JSON Support section in the API documentation:
The htmlsafe_dumps() function of this json module is also available as filter called |tojson in Jinja2. Note that inside script tags no escaping must take place, so make sure to disable escaping with |safe if you intend to use it inside script tags[.]
and the Standard Filters section of the Flask Templates documentation:
tojson()
This function converts the given object into JSON representation. This is for example very helpful if you try to generate JavaScript on the fly.

Save a JSON String which is generated by Javascript as a file: web2py

[Log] {"image":"/SAS/default/download/uploads.image.85f2588e34848596.30362d32353033392e746966.tif","filename":"/SAS/default/download/06-25039.tif","start":1437444049436,"width":1080,"height":734,"events":[{"colour":"#0000ff","width":3,"erased":false,"points":[{"x":795,"y":256,"time":1437444050332},{"x":754,"y":260,"time":1437444050338},{"x":642,"y":271,"time":1437444050355},{"x":466,"y":291,"time":1437444050372},{"x":268,"y":318,"time":1437444050389},{"x":148,"y":344,"time":1437444050406},{"x":101,"y":359,"time":1437444050423},{"x":92,"y":369,"time":1437444050441},{"x":104,"y":377,"time":1437444050458},{"x":161,"y":381,"time":1437444050475},{"x":268,"y":381,"time":1437444050492},{"x":405,"y":366,"time":1437444050509},{"x":513,"y":346,"time":1437444050527},{"x":557,"y":328,"time":1437444050544},{"x":554,"y":315,"time":1437444050562},{"x":529,"y":305,"time":1437444050579},{"x":484,"y":301,"time":1437444050596},{"x":435,"y":304,"time":1437444050613},{"x":401,"y":316,"time":1437444050630},{"x":388,"y":329,"time":1437444050648},{"x":389,"y":342,"time":1437444050665},{"x":406,"y":356,"time":1437444050682},{"x":430,"y":367,"time":1437444050699},{"x":449,"y":370,"time":1437444050716},{"x":457,"y":370,"time":1437444050733},{"x":458,"y":370,"time":1437444050751},{"x":457,"y":368,"time":1437444050769}]}],"end":1437444051345,"elapsed":1909} (experiment, line 164)
This is the String which I need to save.I have to perform two tasks:
Save the string on the system and display it as a View(as it is)
Display a specific argument only. Such as "elapsed" in this string as a View.
How do I do this?
Thanks for the help! :)
Depending on what/how you want to display your JSON string, you have some different options. If you want to display the raw JSON string stored in variable strJSON, you can just inject it into the view at the appropriate location with {{ =strJSON }}. web2py has a built-in method BEAUTIFY which makes injected variable outputs look nicer, i.e. you'd call {{ =strJSON }} to take advantage of this.
If you want to only print certain elements &/or manually format it yourself, as in your second question, I'd recommend converting the JSON string back into a Python object. web2py has a module called SimpleJSON which does all the JSON encoding/decoding magic for you. It's located at gluon.contrib.simplejson. To convert a JSON string to an object, you would use the function 'loads'. For converting a Python object into a JSON string, use 'dumps'. So, for example:
{{ import gluon.contrib.simplejson as sjson }}
{{ myObj = sjson.loads(strJSON) }}
{{ strJSON = sjson.dumps(myObj) }}
Now that your JSON string is stored as an object, you can access elements like you normally would in Python based on whether your object is a list, dictionary, etc. So, for example, if we turn the JSON from your screenshot into an object, we can access the image name as so in Python:
imgname = myObj["image"]
Similarily, you can access the first event via:
my_events = myObj["events"][0]
Which is a dictionary of 'colour', 'width', etc.

What is the right way to store JavaScript source code in a json object?

I want to edit JavaScript in a textarea and store it back into a JavaScript object. For example I have this object:
var item1 = {
'id' : 1,
'title':'title',
'sourcecode' : "alert('hallo')"
};
If I would change the content to alert("hallo") or a even more complex example does this break my object?
I would think there is some escape function like this https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/escape. But it is marked as deprecated.
So if this is deprecated what would be the right way for storing complex JavaScript code into a JavaScript object?
Should I use stringify ?
https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
The JSON.stringify() method converts a JavaScript value to a JSON
string, optionally replacing values if a replacer function is
specified, or optionally including only the specified properties if a
replacer array is specified.
This does not read like there is an automated escape build in.
If you need to send the data to a server, I'd say you should encodeURI your sourceCode, and then JSON.stringify the entire object. When retreiving data from the server, you should decodeURI the sourceCode

Html in json - how to make it valid (with javascript)?

I'm using json.net to automatically deserialize my json objects into .net objects. As long as the json is valid, it works a treat.
But I'm having trouble with html in the json...the special characters and quotes are making the json invalid.
How do I encode or escape the html reliably so it's valid json? I need a way to do it with just javascript because it's the client side sending to the server side.
Edit
Just to give an example of my use case, I have a WYSIWYG in my app and I need the input from that included as part of a json object to be posted to my server.
Just to give an example of my use case, I have a WYSIWYG in my app
and I need the input from that included as part of a json object to be
posted to my server.
Assuming you have the user input in a string variable:
var userInput = 'Any crap with HTML you can imagine';
You can simply JSON encode this in order to transport it as a valid JSON string:
var json = JSON.stringify({ value = userInput });
Now the resulting object will look like this:
{
"value": "Any crap with HTML you can imagine"
}
and on your server simply map this to a POCO with a plain Value string property. The JSON.stringify method will ensure to properly serialize any input to a valid JSON string.
This being said, I don't quite understand your need of wrapping the user input in a JSOn string and then deserializing it back on the server with JSON.NET. I would rather send the raw input as-is. This way you would get exactly the same value on the server without the overhead of JSON serialization.

How to assign javascript variable with a django template variable that consist of multiple lines?

I'm fetching data from mysql longtext field. And it can contain new lines.
This data is passed to the template where I assigns this longtext data to a javascript variable. The problem I get now is that it will complain about unterminated string literal.
Which is because it tries to assign data in this way
$("#id_review").val("kokokoeoarkgeorkgeorkgeorkg
er
g
gerag
earg
ea
gae
gr
er
gea
g
ear
ge
gae
rg
eagr
kok")
I tried to write a custom filter that will add "+ to the end of each line, but it didn't work out too well. So I wonder can this problem be fixed somehow?
My attempt on a filter
#register.filter
def escapenewline(value):
return value.replace('\n', '\"+')
Use a JSON encoder to create a valid string which you can use in your JavaScript code.
From a quick search Django doesn't seem to have a template filter for this but it shouldn't be too hard to add. Assuming your json filter is called tojson the code in the template would look like this:
$("#id_review").val({{ whatever|tojson }});
Here's how the filter could look like:
import json
#register.filter
def tojson(value):
return json.dumps(value)

Categories

Resources