how to pass js value to flask route - javascript

This is my list where i tried to get the value of the of a tag
{% extends 'base.html'%}
{% block body %}
<div onclick="pass()">
{{list1[1]}}
</div>
here i tried to get the value of a tag and have tried to pass info route
<script>
function pass() {
var a = document.getElementsByTagName('a');
var w = console.log(a[0].outerHTML);
window.location = "/info/" + w;
}
</script>
{% endblock %}
but show the following error
Not Found
http://127.0.0.1:5000/info/undefined
this is my info route
#app.route('/info', methods=['GET', 'POST'])
def info():
result = request.get_data
print(result)
return render_template('info.html', result=result)
why it's not displaying any data of within a tag
Thank you in Advance

window.location simply opens an HTML page. window.location = "/info/" + w; creates a route /info/w/ but you've only specified the route /info.
You need to send the a data to the server via a form and use Flask's request object to access it.

Related

use javascript to display django object

I want to implement below using javascript so row click it will get index and display object of this index.
in django template this is working.
<div>{{ project.0.customer_name}}</div>
<div>{{ project.1.customer_name}}</div>
but the below javascript are not working even I get the correct ID.
var cell = row.getElementsByTagName("td")[0];
var id= parseInt(cell.innerHTML);
// not working
document.getElementById('lblname').innerHTML = '{{ project.id.customer_name}}';
// this is also working but what I want is dynamic base on row click
document.getElementById('lblname').innerHTML = '{{ project.1.customer_name}}';
display django object using index in javascript.
You have to understand what is happening with your code:
Templates like this are processed on the server:
'{{ project.id.customer_name}}'
I believe you do not have project.id on your server side, so you get None in the above line, and the moustache tag becomes smth like an empty string, and actual JavaScript code is like this:
document.getElementById('lblname').innerHTML = '';
It is only now that JS code is executed, and you can imagine what it will do.
What you want is processing moustache tags after the id variable has been set in JS, which is not how stuff works (at least, if you don't have some crazy tool chain).
One way of achieving what you want is to provide the whole project object (or array) to JavaScript by doing the following:
<script>
const project = {{ project|safe }};
</script>
A complete Django template could look like this (I used <span>s instead of table cells:
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>django test</title>
</head>
<body>
{% block content %}
{% for item in project %}
<span data-id="{{ forloop.counter }}">{{ forloop.counter }}</span>
{% endfor %}
<div id="output" style="display: flex; flex-direction: column-reverse;">
</div>
<script>
const project = {{ project|safe }};
const spans = document.getElementsByTagName('span');
const output = document.getElementById('output');
const onSpanClick = (event) => {
const id = parseInt(event.target.getAttribute('data-id'), 10) - 1; // forloop.counter is 1-based, JS arrays are 0-based
const div = document.createElement('div');
div.innerHTML = project[id].customer_name;
output.appendChild(div);
}
Array.from(spans).forEach(span => {
span.addEventListener('click', onSpanClick);
})
</script>
{% endblock %}
</body>
</html>
Another way is the AJAX way: you create an API endpoint on your server side, so that an URL like example.com/api/customer_name/?id=999 responds to you with the name of customer id=999 when you click on some element and trigger an XMLHttpRequest with param id=999.

linking JavaScript code to Django database upon clicking on a button

I'm asked to work on a networking website that is like Twitter. I work with HTML,CSS, Javascript for the client-side and Django for the server-side. I'm trying to link between Javascript and Django using JSON and fetch as I want to create a button in each of the users' profile that upon being clicked by the registered user, it makes the registered follow the profile as it is saved in django database as a model containing the follower(follower) and the user followed(following) but upon clicking on follow button (in user.html) it doesn't save any data in the database
in models.py:
class follow(models.Model):
follower = models.ForeignKey("User",on_delete=models.CASCADE, related_name="follower")
following = models.ForeignKey("User",on_delete=models.CASCADE, related_name="following")
in user.html(contains the script):
<html>
<head>
<script>
document.addEventListener('DOMContentLoaded',function(){
document.querySelectorAll('input').forEach(input =>{
input.addEventListener('click', function(){
console.log(input.id);
let follow_username = input.id
fetch('/follow/'+ follow_id, {
method:'PUT',
body: JSON.stringify({
follow: true
})
})
})
}
)
});
</script>
</head>
<body>
<h2>{{x.username}}</h2>
<form>
{% csrf_token %}
<input type="submit" value="follow" name ="follow" id={{x.username}}>
</form>
</body>
</html>
in urls.py:
from django.urls import path
from . import views
urlpatterns = [
path("follow/<str:name>", views.Users, name="follow")
]
in views.py:
def Users(request, name):
x = User.objects.get(username = name)
if request.method == 'PUT':
data = json.loads(request.body)
if data.get('follow') is not None:
user = request.user
anotherr = User.objects.filter(username = name)
another = User.objects.get(username = anotherr).id
follow.objects.create(follower = user, following = another)
return render (request, "network/user.html",{"x":x})
upon clicking on the follow button that present in user.html, no data is created in the database. so what is the problem?
I'll throw my best guesses on what's happening.. Just some improper syntax and undefined variables
View
another / anotherr no, just use x you're already fetching the user at the top of the view
get_or_create will not allow you to have duplicates / follow someone twice (generally a good idea)
Prints are just debugging, remove after you know it's working
def Users(request, name):
x = User.objects.get(username=name)
if request.method == 'PUT':
print('we\'ve hit put')
data = json.loads(request.body)
if data.get('follow') is not None:
print('in follow')
# Note: [User Obj Itself]
# follower = request.user (is: <User Obj>)
# following = x (is: <User Obj>)
followObj, createdBool = follow.objects.get_or_create(follower=request.user, following=x)
print('followObj', followObj)
print('created?', createdBool)
print('past follow')
print('about to render')
return render (request, "network/user.html",{"x":x})
Template
Idk what follow_id is, just use input.id
<html>
<head>
<script>
document.addEventListener('DOMContentLoaded',function(){
document.querySelectorAll('input').forEach(input =>{
input.addEventListener('click', function(){
// this should be true
console.log(input.id == '{{x.username}}');
console.log('Fetch Url:\t' + '/follow/'+ input.id);
fetch('/follow/'+ input.id, {
method:'PUT',
body: JSON.stringify({
follow: true
})
})
})
}
)
});
</script>
</head>
<body>
<h2>{{x.username}}</h2>
<form>
{% csrf_token %}
<input type="submit" value="follow" name ="follow" id={{x.username}}>
</form>
</body>
</html>
If these don't work, tell me what print or console.log got hit or didn't get hit- that'll really help narrow down the issue even more
Edit
Supposedly this, putting a token in a header, will work if you don't want to put a #csrf_exempt decorator (which might be a good idea tbh)
fetch('/follow/'+ input.id, {
method:'PUT',
headers: { 'X-CSRFToken': $('[name=csrfmiddlewaretoken]').val() },
body: JSON.stringify({
follow: true
})
})

Access Django variable from JavaScript variable

First of all, I will like to say this is my first question here! (pardon me if this is redundant or duplicated)
I am having some problems with calling JS scripts from Django template:
{% for suggestion in suggestions %}
<img class="catalogue-poster" src="{{ suggestion.poster }}" alt="Portada" onclick="
document.getElementById('{{form.title.auto_id}}').value = '{{suggestion.title}}'
document.getElementById('{{form.year.auto_id}}').value = '{{suggestion.year}}'
document.getElementById('{{form.director.auto_id}}').value = '{{suggestion.director}}'
document.getElementById('{{form.rating.auto_id}}').value = '{{suggestion.rating}}'
document.getElementById('{{form.poster.auto_id}}').value = '{{suggestion.poster}}'
document.getElementById('{{form.trailer.auto_id}}').value = '{{suggestion.trailer}}'
document.getElementById('{{form.synopsis.auto_id}}').value = '{{suggestion.synopsis}}'
document.getElementById('{{form.cast.auto_id}}').value = '{{suggestion.cast}}'
" />
{% endfor %}
So, first of all, how can I declare a function outside. I'm a C developer, sorry for my ignorance.
I've tried to create a script outside, such as
<script>
function foo() {
console.log('Hey');
});
</script>
And invoke it this way:
<img class="catalogue-poster" src="{{ suggestion.poster }}" alt="Portada" onclick="foo()"/>
But this simple thing that works on pure HTML, with django templates does not seem to work...
On the other hand, the real question was, is there a way to access a Django variable passed in render with a js variable?
Such as:
const jsVariable = 'title';
document.getElementById('{{form.jsVariable.auto_id}}').value = '{{suggestion.jsVariable}}'
I have not found any way to accomplish this, maybe there is another great idea!
I have tried one example. where is send a variable from python script and access its value in JavaScript
1) In views.py
from django.shortcuts import render
def home_view(request):
var_name = 'hello'
return render(request, 'home.html', {'var_name':var_name})
2) In html file(home.html)
<html>
<h1>Home Page</h1>
<input type="button" value="Submit" onclick="fun()">
<script>
function fun(){
console.log('hello world '+ '{{var_name}}' );
}
var temp = '{{var_name}}';
console.log(temp + 20);
</script>
</html>
If i click submit button ( hello world hello ) is printed in console.
I stored value of var_name in temp which can be further used.
From your example, it looks you want to programmatically access a Django model's attribute in Javascript.
The main takeaway is that you first need to expose the data structure you want to access (i.e. the model) in Javascript.
Here's a simple, redacted, proof-of-concept you can try.
import json
def my_view(request):
obj = MyModel.objects.get(1)
obj_dict = {
"foo": obj.foo,
"bar": obj.bar,
}
return render(request, 'my_view.html', context={'obj_json': json.dumps(obj_dict)} )
<script>
var obj = {{obj_json}};
var field = 'foo';
console.log(obj[field]);
Check out Convert Django Model object to dict with all of the fields intact for a run-down on options to serialize Django models into dictionaries.
Well, finally I found a solution for both exposed problems.
First of all, the script function I declared was not working because it seems that there is an attribute called autocomplete (see autocomplete HTML attribute)
So, you can not declare a JavaScript function with this name, my fail.
Uncaught TypeError: autocomplete is not a function
Finally, the simple solution I found was passing an array of dicts to the template:
return render(request, 'example.html', {'form': form, 'suggestions': suggestions })
And then in the template:
{% for suggestion in suggestions %}
<img src="{{ suggestion.poster }}" onclick="autocompleteMovie({{suggestion}});" />
{% endfor %}
<script>
function autocompleteMovie(suggestion){
for (let field in suggestion)
document.getElementById('id_' + field).value = suggestion[field]
}
</script
Which, comparing it with the question, really simplifies the problem.

How to Embed multiple tweets of various users into HTML in django framework?

I am passing a data in the form of a dictionary from views.py to results.html in Django framework. The dictionary has the following format
'tweet': (tweet_analysis, tweet_id)
now in results.html, called by the views.py,
I am trying to Embed all the tweets that are passed to results.html, but the following code only displays one embedded tweet.
dicPositive: This is the dictionary containing all the tweets data
{% for tweet, tweet_feel in dicPositive.items %}
<div id="tweet" tweetID="{{tweet_feel.1}}"></div>
<script sync src="https://platform.twitter.com/widgets.js"></script>
<script>
window.onload = (function(){
var tweet = document.getElementById("tweet");
var id = tweet.getAttribute("tweetID");
twttr.widgets.createTweet(
id, tweet,
{
conversation : 'none', // or all
cards : 'hidden', // or visible
linkColor : '#cc0000', // default is blue
theme : 'light' // or dark
})
.then (function (el) {
el.contentDocument.querySelector(".footer").style.display = "none";
});
});
</script>
<!-- <li>{{tweet}} –> {{tweet_feel.0}} –> {{tweet_feel.1}}</li> -->
{% endfor %}
It is because you have used same id for multiple HTMLElements created while looping.
You must add loop counter to id attribute of div and also when
you are fetching it using getElementById inside script tag
{% for tweet, tweet_feel in dicPositive.items %}
<div id="tweet_{{forloop.counter}}" tweetID="{{tweet_feel.1}}"></div>
<script sync src="https://platform.twitter.com/widgets.js"></script>
<script>
window.onload = (function(){
var tweet = document.getElementById("tweet_{{forloop.counter}}");
# Rest of your code
...
</script>
{% endfor %}

Django template Javascript passing a python variable to a javascript one

I did create a python function called generate_random_number that generate a random number between 1 and 9 and compare it to the id of each video in my database and return the url of the video corresponding to the id matching the random number. Here is the function:
from random import randint
from dash_interface.models import Video
from django import template
register = template.Library()
#register.simple_tag
def random_video():
random_number = randint(1, 9)
all_videos = Video.objects.all()
for video in all_videos:
if video.id == random_number:
random_url = video.video_url
return random_url
I want to pass random_url to a javascript variable in a django template.
My template looks like this:
<video id="videoplayer" controls></video>
<script>
{% load generate_random_number %}
// setup the video element and attach it to the Dash player
function setupVideo() {
var url = " ";
var context = new Dash.di.DashContext();
var player = new MediaPlayer(context);
player.startup();
player.attachView(document.querySelector("#videoplayer"));
player.attachSource(url);
}
</script>
<style>
video {
width: 60%;
height: 40%;
}
</style>
The variable concerned is url.
I did a {% load generate_random_number %}, but I don't know if I can replace the quotation marks in url by {{ random_url }}.
If you want to split the javascript code and html code, you could make something like:
<script arg = {{ somevar }} src = "/path/to/script"></script>
and in the script :
var arg = $("script[src='/path/to/script']").attr("arg");
If you need that the arg will be updated each a concrete period, you need to make an ajax. If you use the database for persist the arg, you could use Django Channels like a more elegance solution.
You should keep the custom template tag definitions in a templatetags folder inside your app. Make sure that __init__.py is present in the templatetags folder. Your folder structure should be similar to:
your_django_app/
__init__.py
models.py
templatetags/
__init__.py
template_tags.py
views.py
And the contents of template_tags.py should be you required tag definition:
from random import randint
from dash_interface.models import Video
from django import template
register = template.Library()
#register.simple_tag
def random_video():
random_number = randint(1, 9)
all_videos = Video.objects.all()
for video in all_videos:
if video.id == random_number:
random_url = video.video_url
return random_url
Note: The templatetags file should contain the variable named register.
After this you can load the template tags in your HTML. Your code will look like:
<video id="videoplayer" controls></video>
{% load template_tags %}
<script>
// setup the video element and attach it to the Dash player
function setupVideo() {
var url = "{% random_video %}";
var context = new Dash.di.DashContext();
var player = new MediaPlayer(context);
player.startup();
player.attachView(document.querySelector("#videoplayer"));
player.attachSource(url);
}
</script>
<style>
video {
width: 60%;
height: 40%;
}
</style>
This is the way I prefer to connect Django templates and JS.
You need to import render function:
views.py file
from django.shortcuts import render
from random import randint
from dash_interface.models import Video
def random_video(request):
random_number = randint(1, 9)
all_videos = Video.objects.all()
for video in all_videos:
if video.id == random_number:
random_url = video.video_url
context = {
"random_url": random_url
}
return render(request, "app/video.html", context)
else:
return render(request, "app/video.html", {})
video.html
<video id="videoplayer" controls></video>
<script>
{% load generate_random_number %}
// setup the video element and attach it to the Dash player
function setupVideo() {
// using the context passed in here.
var url = {{ random_url|safe }};
var context = new Dash.di.DashContext();
var player = new MediaPlayer(context);
player.startup();
player.attachView(document.querySelector("#videoplayer"));
player.attachSource(url);
}
</script>
<style>
video {
width: 60%;
height: 40%;
}
</style>
What I have done is rendered your HTML page in the Django view and passed your variable inside the context dictionary which is later accessible in your HTML tags or script tags.
I also used a |safe parameter in the template tag which removes some unwanted strings.
Cheers and Hope it helps! I have tried this thing in many of my projects and it has always been a success for me.

Categories

Resources