Can not trigger onclick function using Django, Python and JavaScript - javascript

I have an issue. I could not trigger the onclick event on the link using Django and Python. I am providing my code below.
base.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
{% load static %}
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
var query='';
function pageTransition(){
var full_url = window.location.search;
var url = full_url.replace("?", '');
query=url.file;
console.log('query',query);
var url="'"+query+"'";
$.getScript(url,function(){
$('a').velocity("scroll", { duration: 1000 });
})
}
</script>
</head>
<body>
<header>
<h1>Nuclear Reactor</h1>
{% if count > 0 %}
<b>Hi, {{ user.username }}</b>
Home
View Reactor status
logout
{% else %}
login / signup
{% endif %}
<hr>
</header>
<main>
{% block content %}
{% endblock %}
</main>
</body>
</html>
home.html:
{% extends 'base.html' %}
{% block content %}
<center><h1>Welcome</h1>
<p>This App allow to control the life cycle of the Nuclear Reactor and Retrive the status report </p>
<p>Status reportControl panel</p>
</center>
{% endblock %}
total html generated output after click on home link:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
var query='';
function pageTransition(){
var full_url = window.location.search;
var url = full_url.replace("?", '');
query=url.file;
console.log('query',query);
var url="'"+query+"'";
$.getScript(url,function(){
$('a').velocity("scroll", { duration: 1000 });
})
}
</script>
</head>
<body>
<header>
<h1>Nuclear Reactor</h1>
<b>Hi, </b>
Home
View Reactor status
logout
<hr>
</header>
<main>
<center><h1>Welcome</h1>
<p>This App allow to control the life cycle of the Nuclear Reactor and Retrive the status report </p>
<p>Status reportControl panel</p>
</center>
</main>
</body>
</html>
Here I need to get that query string value and include it inside that JavaScript function but the JavaScript function is not called at all.

Related

Flask Stripe Checkout dynamic prices SessionID error

I've been using https://stripe.com/docs/payments/checkout/migrating-prices#server-side-code-for-inline-items and https://stripe.com/docs/payments/checkout/accept-a-payment as well as other guides/SO posts as a guide.
The checkout button in payments.html page doesn't work; nothing happens on the page.
In the Flask's /payment function, I have been able to print out the session/session.id fine.
I have tried passing the session and the session.id to the payments.html page, but neither has worked. The {{price}} on payments.html works fine.
What am I overlooking/messing up here to get the Checkout page working?
base.html
<!DOCTYPE html>
<html>
<head>
<title>Stripe Checkout</title>
<link rel="stylesheet" href="{{ url_for('static', filename='main.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='bootstrap.min.css') }}">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<meta name="mobile-web-app-capable" content="yes">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
</head>
<body>
<div class="container">
{% block content %}
{% endblock %}
</div>
{% block scripts %}
{% endblock %}
</body>
</html>
Payments.html
{% extends "base.html" %}
{% block content %}
<div>
<h1>Cost</h1>
<h2>Pay ${{price}}</h2>
<button type="button" class="btn btn-primary" id="checkout">Pay with Card</button>
<button type="button" class="btn btn-primary" id="back">Back</button>
</div>
<div id="status">
<br>
<div class="alert alert-primary" id="alert" role="alert"></div>
</div>
{% endblock %}
{% block scripts %}
<script src="https://js.stripe.com/v3"></script>
<script>
var stripe = Stripe('pk_test_...');
var checkoutButton = document.querySelector('#checkout');
checkoutButton.addEventListener('click', function () {
stripe.redirectToCheckout({
sessionId: {{sessionID}}
});
});
</script>
{% endblock %}
Flask's /payment function
#app.route("/payment")
def payment():
price = "50"
session = session.Session().getSession(int(price)*100)
sessionID = session.id
print("SessionID:", sessionID)
return render_template("payment.html", sessionID=sessionID, price=price)
Python Stripe file
import stripe
stripe.api_key = 'sk_test_...'
class Session:
def __init__(self):
pass
def getSession(self, price):
session = stripe.checkout.Session.create(
payment_method_types=['card'],
line_items=[{
'price_data': {
'currency': 'usd',
'product_data': {
'name': 'blah',
},
'unit_amount': price,
},
'quantity': 1,
}],
mode='payment',
success_url='https://example.com/success',
cancel_url='https://example.com/cancel',
)
return session
Thanks to #floatingLomas, I didn't think to use the browser's console. Yeah, I figured it out, I have to use the session.id and have quotes around {{sessionID}}.

Use twig variables into ajax function

i have a personal mvc architecture and i want to use variables passed from the controller to the twig template into an included js file.
There are my files, All about the variable $server_ID :
DashboardController.php who send the $server_ID variable to the template
class DashboardController extends Controller {
public function get($id = null) {
$serverModel = $this->model('ServerModel');
$server_ID = $serverModel->findById($id);
$this->view('dashboard/get', ['server_ID' => $server_ID]);
}
public function ajax_getstats($server_ID) {
$return = ServerModel::getStats($server_ID);
echo json_encode($return);
exit;
}
}
Twig template main.html that make the layout
<!DOCTYPE html>
<html>
<head>
{% include 'head.html' %}
</head>
<body>
{% include 'header.html' %}
<div class="content">
{% block content %}{% endblock %}
</div>
{% include 'scripts.html' %}
</body>
</html>
scripts.html that include specific js files
<!-- Optional JavaScript -->
<script src="{{ ASSET_ROOT }}/assets/vendor/jquery/jquery-3.3.1.min.js"></script>
<script src="{{ ASSET_ROOT }}/assets/vendor/bootstrap/js/bootstrap.bundle.js"></script>
<script src="{{ ASSET_ROOT }}/assets/js/dashboard.js"></script>
And finaly dashboard.js where what i want to use the variable $server_ID
function getStats() {
var rStart = Date.now();
$.getJSON("http://localhost/site/public/dashboard/ajax_getstats/" + {{ server_ID }}, function(data)
{
// treatment here
});
}
$(document).ready(function()
{
getStats();
});
You can create a hidden input type in the main.html page which contains the value of server_ID, and then grab it in the JavaScript file.
main.html:
<!DOCTYPE html>
<html>
<head>
{% include 'head.html' %}
</head>
<body>
<input type="hidden" id="server-id" value="{{ server_ID }}"> <!-- This echos the server_ID variable to become the value for this input. -->
{% include 'header.html' %}
<div class="content">
{% block content %}{% endblock %}
</div>
{% include 'scripts.html' %}
</body>
</html>
dashboard.js:
let serverID = $("#server-id").val(); // This variable is now equal to $server_ID.
function getStats() {
var rStart = Date.now();
$.getJSON("http://localhost/site/public/dashboard/ajax_getstats/" + {{ server_ID }}, function(data)
{
// treatment here
});
}
$(document).ready(function()
{
getStats();
});

Materialize CSS (with django) dropdown form not working

I'm trying to create a form in which the user choices an instance of model object (Invoice) already saved in the database and submits. I've tried to initialize the JS, but have little experience working with JS in html so I'm not totally sure I'm doing it right.
Right now the below code does not render anything besides the submit button in the form. I have tried adding a random input field (worked) and tried unpacking and rendering the "invoices" context as raw text on the same page (also worked) so I think I've narrowed the issue down to it being the form choices.
header.html
<head>
{% load static %}
<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<!-- Compiled and minified CSS -->
<meta name = "viewport" content = "width = device-width, initial-scale = 1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link rel = "stylesheet"
href = "https://fonts.googleapis.com/icon?family=Material+Icons">
<script type = "text/javascript"
src = "https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script>
$(document).ready(function(){
$('select').formSelect();
});
</script>
</head>
<body>
<nav>
<div class="nav-wrapper">
Elb
<ul id="nav-mobile" class="right hide-on-med-and-down">
<li>Invoice Upload</li>
<li>Inventory Upload</li>
</ul>
</div>
</nav>
{% block content %}
{% endblock %}
</body>
form.html
{% extends 'main/header.html' %}
<body>
{% block content %}
<br>
<br>
<form method="POST">
{% csrf_token %}
<label for="invoice">Invoice</label>
<select id="invoice" name="invoice">
<option class=browser-default value="" disabled selected>Choose invoice</option>
{% for invoice in invoices %}
<option class=browser-default value="{{ invoice }}">{{ invoice }}</option>
{% endfor %}
</select>
<br><br>
<input type="submit" value="Save" />
</form>
{% endblock content %}
</body>
views.py
def inventory_upload(request):
if request.user.username == 'admin': # Check that user is authorized
if request.method == 'POST': # Render HTML of results page returned to user
...do something and return to user...
else: # Initial html display to user
invoices = Invoice.objects.all()
inventory = get_inventory_from_sheet()
form = BulkInventoryUpload
return render(request=request,
template_name='form.html',
context={'invoices': invoices, 'inventory': inventory, 'form': form})
else: # Bounce user back to homepage if not authorized
return redirect('main:homepage')
forms.py
from django import forms
from django.forms import formset_factory
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .models import Invoice
class BulkInventoryUpload(forms.Form):
invoice = forms.CharField(label='invoice', max_length=150)
def get_invoice(self, commit=True):
invoice = self.cleaned_data['invoice']
return invoice
For anyone else running into the same issue (credit to Sean Doherty in comments above for the answer):
JQuery needs to be loaded before CSS (and from my testing it looks like before the JS as well)
The below order got it working for me:
<head>
{% load static %}
<!-- Compiled and minified JavaScript -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script>
$(document).ready(function(){
$('select').formSelect();
});
</script>
<!-- Compiled and minified CSS -->
<meta name = "viewport" content = "width = device-width, initial-scale = 1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link rel = "stylesheet"
href = "https://fonts.googleapis.com/icon?family=Material+Icons">
</head>

Using a Jinja2 for loop with a javascript alert

I've been trying to create a webpage where after receiving user input, it would display the history of all user input after pressing submit, however this is working as intended. However I wanted to implement an alert box which would show additional information. However as everything else is printed correctly, since the alert box uses an onclick event, it would only output the very last sample of user input.
<!doctype html>
<html>
<head>
<title>Enrolment page</title>
</head>
<body>
{% if all_users %}
{% for user in all_users %}
<h1> Hi, {{ user[0] }}) </h1>
<button onclick="myFunction()">Details</button>
<script>
function myFunction() {
alert("{{ user[1] }}, {{ user[2] }}");
}
</script>
{% endfor %}
{%else%}
No users to show
{% endif %}
</body>
</html>
In my code, all_users is the information from a csv file, however that is working fine. My only problem is the alert is not showing the information I want. Is there a way to store each set of user details in each script to print out each button since it is only displaying the last set of user details.
You can bind the user[0] and user[1] in the myFunction() call like:
{% for user in all_users %}
<h1> Hi, {{ user[0] }}) </h1>
<button onclick="myFunction('{{user[1]}}, {{user[2]}}')">
Detail
</button>
{% endfor %}
Then change the function to:
function myFunction(users) {
alert(users);
}
To work this in Jinja2, you might try using a string variable and appending each value as in (code not tested):
<!doctype html>
<html>
<head>
<title>Enrolment page</title>
</head>
<body>
{% if all_users %}
{% set AllUserList = "" %}
{% for user in all_users %}
{% set AllUserList = AllUserList + user[1] + ", " + user[2] + "\n" %}
<h1> Hi, {{ user[0] }}) </h1>
<button onclick="myFunction()">Details</button>
<script>
function myFunction() {
alert("{{ AllUserList }}");
}
</script>
{% endfor %}
{%else%}
No users to show
{% endif %}
</body>
</html>

Multiple JQuery countdowns in a loop with Django

I'm creating a sport app with django. I would like to display a list of matches with a countdown for each match.
For now, I only have one countdown. I use this Jquery countdown: http://keith-wood.name/countdown.html (that goes to the new year). I have a loop to display my matches. So the question is how can I insert the countdown into the loop and make it go to the DateTime of my objects "match"?
Here is my template:
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<style type="text/css">#import "/Users/marc-a antoine.lacroix/Desktop/Jquery/jquery.countdown.package-1.6.0/jquery.countdown.css";</style>
<script type="text/javascript" src="http://keith-wood.name/js/jquery.countdown.js"> </script>
<script language="javascript">
$(document).ready(function(){
var newYear = new Date();
newYear = new Date(newYear.getFullYear() + 1, 1 - 1, 1);
$('#defaultCountdown').countdown({until: newYear});
});
</script>
</head>
<body>
<div style="float:left">
{% for match in matches %}
<div>
<p>{{ match }}</p>
<p> {{match.real_start}} <p>
Go
</div>
{% endfor %}
</div>
<div id="defaultCountdown"> </div>
</body>
"matches" is the list containing every matches. "real_start" is the DateTime of my objects "match"
My views.py is simply:
def page(request):
matches = Match.live_matches.all()
return render_to_response('myhtml.html', {'matches': matches}, context_instance=RequestContext(request))
So I don't know how to import my "real_start" DateTime into the countdown and how to insert this countdown into the loop.
Here is my current code:
<script language="javascript">
$(function(){
$('.match_wrap').each(function(){
var match_start=$(this).data('match_start');
$(this).find('.matchTimer').countdown({until: match_start});
});
})
</script>
</head>
<body>
<div style="float:left">
{% for match in matches %}
</br></br>
<div class="match_wrap" data-match_start="{{ match.real_start|date:"M j, Y" }}">
<p>{{ match }}</p>
<p> {{match.real_start}} <p>
<div>
<ul>
{% for team in match.teams %}
<li>
<img src="{{ team.logo.url }}">
</li>
{% endfor %}
</ul>
</div>
Go
<div class="matchTimer"> </div>
</div>
{% endfor %}
</div>
</br></br>
I also tried:
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript" src="http://keith-wood.name/js/jquery.countdown.js"></script>
<script language="javascript">
$('.match_countdown').each(function() {
var self = $(this),
date_string = self.attr('data-date'),
date = new Date.parse(date_string);
self.countdown({until: date});
});
</script>
</head>
<body>
<div style="float:left">
{% for match in matches %}
</br></br>
<div class="match_countdown" data-date="{{ match.real_start|date:'M j, Y' }}"></div>
<p>{{ match }}</p>
<p> {{match.real_start}} <p>
<div>
<ul>
{% for team in match.teams %}
<li>
<img src="{{ team.logo.url }}">
</li>
{% endfor %}
</ul>
</div>
Go
</div>
{% endfor %}
</div>
Similar to charlietfl's answer but js parses the correct date.
{# template #}
{% for match in matches %}
<div>
<p>{{ match }}</p>
<p> {{match.real_start}} <p>
Go
<div class="match_countdown" data-date="{{ match.real_start|date:'M j, Y' }}"></div>
</div>
{% endfor %}
and then the js:
$('.match_countdown').each(function() {
var self = $(this),
date_string = self.attr('data-date'),
date = new Date(date_string);
self.countdown({until: date});
});
Here (http://jsfiddle.net/miki725/MQcYw/1/) js jsfiddle which illustrates the solution.
WHenever you need to invoke a plugin on many elements that requires different data for each instance is often easiest to loop over the elements involved and call each instance from within the loop.
Something like this should be easy to implement:
HTML
{% for match in matches %}
<div class="match_wrap" data-match_start="{{match.startFormattedToCountDownPlugin}}">
<p>{{ match }}</p>
<p> {{match.real_start}} <p>
Go
</div>
<div class="matchTimer"> </div>
</div>
{% endfor %}
JS
$(function(){
$('.match_wrap').each(function(){
var match_start=new Date.parse($(this).data('match_start'));
$(this).find('.matchTimer').countdown({until: match_start});
});
})

Categories