Flask Stripe Checkout dynamic prices SessionID error - javascript

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}}.

Related

Front Matter Data in Layouts is not working Eleventy

I'm having troubles using front matter in my layouts. It simply displays out the front matter to the page without creating the data needed for my layout.
Here goes the code:
/src/_includes/layouts/base.html
---
rightLinks : [
{
"icon": "mail_outline",
"href": "https://google.com"
}
]
---
<!DOCTYPE html>
<html lang="es-AR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:ital,wght#0,300;0,400;0,600;0,700;0,900;1,300;1,400;1,600;1,700;1,900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/css/global.css">
</head>
<body>
<!-- top-nav try to use rightLinks data from this layout -->
{% include "partials/top-nav.html" %}
{% include "partials/main-nav.html" %}
<main tabindex="-1" id="main-content">{% block content %}{% endblock %}</main>
</body>
</html>
/src/_includes/layouts/home.html
{% extends "layouts/base.html" %}
{% block content %}
<section class="hero is-black is-fullheight-with-navbar hero-home">
<div class="hero-body">
<div class="container">
<div>
<h1 class="title text-black text-huge">
Nexus Materiales Eléctricos
</h1>
<h2 class="subtitle is-4">
Somos mayoristas en insúmos eléctricos de calidad.
</h2>
</div>
<div class="mt-6">
<a href="/marcas" class="button is-rounded is-large is-dark is-uppercase text-semi-black">
ver marcas
</a>
</div>
</div>
</div>
</section>
<section class="section has-background-white">
<h2 class="title">Nuestras marcas destacadas</h2>
<h3 class="subtitle">Calidad y seguridad</h3>
</section>
{% endblock %}
/src/index.md
---
title: 'Hello World!'
layout: 'layouts/home'
---
I get as a visual result the actual string at the top:
It seems to me that Eleventy, for some reason, is skipping the front matter.
Here is my Eleventy configuration file:
module.exports = function(config) {
config.addWatchTarget("./src/sass/");
config.addPassthroughCopy('./src/images')
// Return your Object options:
return {
dir: {
input: "src",
output: "dist"
},
markdownTemplateEngine: 'njk',
dataTemplateEngine: 'njk',
htmlTemplateEngine: 'njk',
}
};
Someone can explain to me why is this happening, and how can I solve this? Thanks
Front-matter data is only available in layout files that are directly referenced by pages with the layout: front matter key, not with Nunjucks {% extends %}. Front matter data in directly referenced layout files are merged with other data as part of 11ty's data cascade. (11ty docs: front matter in layouts)
For example:
<!-- index.md -->
---
layout: layouts/content
---
# some content here
{# layouts/base.njk #}
---
hello: "world"
---
{# ^ the above will be printed as plain text and isn't available #}
{# layouts/content.njk #}
---
someKey: "something"
---
{% extends "layouts/base.njk" %}
{{ someKey }}
{# ^ this will render "something" as expected #}
This is likely because {% extends %} is a feature of Nunjucks, and Eleventy is not aware of which other Nunjucks files are being referenced.
For your situation, you have a couple of options. First, you could place your front matter data in layouts/home, since that's what you're referencing in your index.md. Another option is to just use Nunjuck's set tag.
{% set links = [
{
"icon": "mail_outline",
"href": "https://google.com"
}
] %}
{% for link in links %}
{{ link.icon }}
{{ link.href }}
{% endfor %}

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>

Why is my jquery in Django app not working?

I am implemening a dependent-dropdown form with JQuery and Django. However, I still have no idea why this jquery does not work.
My template:
{% block style %}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" media="screen" href="{% static 'css/style.css' %}"/>
{% endblock %}
{% block script %}
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type='text/javascript' src="{% static 'js/ajax_load_rooms.js' %}"></script>
{% endblock %}
{% block content %}
<div class="container-">
<div class="wrapper">
<form id='selectForm' method="post" data-rooms-url="{% url 'ajax_load_rooms' %}">
{% csrf_token %}
<div class="building">
<label for="building">Nhà học</label>
{{ form.building }}
</div>
<div class="room">
<label for="room">Phòng học</label>
{{ form.room }}
</div>
<button class="show-list btn btn-primary" >Thoi gian bieu</button>
</form>
</div>
</div>
{% endblock %}
dropdown_room_list.html
<option value="">-------</option>
{% for room in rooms %}
<option value="{{ room.pk }}">{{ room.room }}</option>
{% endfor %}
My jquery:
$("#id_building").change(function () {
var url = $("#selectForm").attr("data-rooms-url");
var buildingId = $(this).val();
$.ajax({
url: url,
data: {
'building': buildingId,
},
success: function (data) {
$("#id_room").html(data);
}
});
});
My view:
def load_rooms(request):
building = request.GET.get('building')
room_list = Room.objects.filter(building__bid=building, availability=True)
return render(request, 'dropdown-room-list.html', {'rooms': room_list})
My urls:
from django.urls import path
from django.contrib.auth import views as auth_views
from .forms import LoginForm
from .views import *
urlpatterns = [
path('accounts/login/', auth_views.LoginView.as_view(authentication_form=LoginForm, redirect_authenticated_user=True), name='login'),
path('accounts/logout/', auth_views.logout_then_login, name='logout'),
path('booking/list/', BookingListView.as_view(), name='booking_list'),
path('booking/add/', BookingCreateView.as_view(), name='booking_add'),
path('booking/<int:pk>/delete', BookingDeleteView.as_view(), name='booking_delete'),
path('timetable/select/', TimetableSelectView.as_view(), name='select'),
path('timetable/<str:building>/<str:room>/<int:year>/<int:week>', TimetableRoomView.as_view(), name='room_timetable'),
path('ajax/load_rooms', load_rooms, name='ajax_load_rooms')
]
Rendered HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Tim phong</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" media="screen" href="/static/css/style.css"/>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type='text/javascript' src="/static/js/ajax_load_rooms.js"></script>
</head>
<body>
<header>
<nav class="nav-bar">
<ul class="left list">
<li>Quản lý</li>
<li>Đặt phòng</li>
</ul>
<ul class="right list">
<li>Đăng xuất</li>
</ul>
</nav>
</header>
<div class="container-">
<div class="wrapper">
<form id='selectForm' method="post" data-rooms-url="/ajax/load_rooms">
<input type='hidden' name='csrfmiddlewaretoken' value='qvLwYOC9fKVkADkklqhL29UWNduOqJjwAlFYdLd6t03qWZ9z30z0BCsSElGoRsla' />
<div class="building">
<label for="building">Nhà học</label>
<select name="building" class="form-control form-control-sm" required id="id_building">
<option value="" selected>---------</option>
<option value="B1">Lecture Hall B1</option>
</select>
</div>
<div class="room">
<label for="room">Phòng học</label>
<select name="room" class="form-control form-control-sm" required id="id_room">
<option value="" selected>---------</option>
<option value="3">B1/101</option>
</select>
</div>
<button class="show-list btn btn-primary" >Thời gian biểu</button>
</form>
</div>
</div>
</body>
Note that my javascript static path is right, the template is rendered nicely and I can see the javascript path to the right code. But the dependent-dropdown functionality is seems to be not working.
Okay, As I find two things missing in your code -
Not able to find id_building id in your template.
in ajax request type (method) is missing, which is post as you sending the data.
For only building selection change, you want to update its room. If this is the case, you can use only ajax query on building selection-
$("#id_building").change(function () {
$.ajax({
url: "/ajax/load_rooms",
method: "GET",
async' false,
data: {
building : $(this).val(),
},
success: function (data) {
//check your data
console.log(data);
// if data in id->room name format, it will work
// if not change as per result data
$.each(data, function(key, value) {
htmlOption += '<option value="' + itemsMarque[key].id + '">'+ itemsMarque[key].name + '</option>';
});
$("#id_room").html(data);
}
});

Can not trigger onclick function using Django, Python and 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.

Need jquery to search data on all pages and display rather than data only on page

my issue when I search on my site using jquery it is only searching on the page that is displayed at the moment and I would like it to search all of my data and then display on the page accordingly, which is about 2.6 M entries. I am using the core django paginator for my pagination and using simple jquery and ajax for my search tool. Please help!
heres my view:
def tissues(request):
contact_list = TissueTable.objects.all()
paginator = Paginator(contact_list, 100) # Show 25 contacts per page
page = request.GET.get('page')
try:
contacts = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer, deliver first page.
contacts = paginator.page(1)
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
contacts = paginator.page(paginator.num_pages)
return render(request, '.html', {'contacts': contacts})
heres my two templates, base and home,
base.html:
<html>
<head>
<title>Animal NGS DATA</font></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css">
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$('a[rel="external"]').attr('target', '_blank');
</script>
<style>
th
{
border-bottom: 1px solid #d6d6d6;
}
tr:nth-child(even)
{
background:#e9e9e9;
}
</style>
</head>
<body>
<div data-role="page" id="pageone">
<div data-role="header">
<h1 left>NGS CUFFLINK'S DATA</h1>
</div>
<div data-role="main" class="ui-content">
<form>
<input id="filterTable-input" data-type="search" placeholder="Search Tissue Data...">
</form>
<table data-role="table" data-mode="columntoggle" class="ui-responsive ui-shadow" id="myTable" data-filter="true" data-input="#filterTable-input">
</head>
<body>
<map title="Navigation Bar">
<P>
NGS Data
Genes
Experiment
Organisms
Tissue Data
</P>
</map>
<h1><font color='red'>Tissue Data</font></h1>
{% block content %}
{% endblock %}
</body>
{% load staticfiles %}
<link rel="stylesheet" type="text/css" href="{% static 'myapp/style.css' %}" />
</html>
and my home.html
{% extends "tissues/base.html" %}
{% block content %}
<!--<table id='table' data-mode="columntoggle" border = '10' bordercolor = 'mahogany'>-->
<div class="pagination">
<span class="step-links">
{% if contacts.has_previous %}
previous
{% endif %}
<span class="current">
Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.
</span>
{% if contacts.has_next %}
next
{% endif %}
</span>
</div>
<table data-role="table" id="myTable" class="ui-responsive ui-shadow" data-filter="true" data-input="#filterTable-input" bgcolor = 'cyan'>
<thead>
<tr bgcolor = 'pink'>
<th>Tissue ID</th>
<th>Tissue Term</th>
<th>Definition</th>
</tr>
<thead>
<tbody>
{% for b in contacts.object_list%}
<tr>
<td>{{b.tissue_id}}</td>
<td>{{b.tissue_term}}</td>
<td>{{b.definition}}</td>
</tr>
{% endfor %}
</table>
<div class="pagination">
<span class="step-links">
{% if contacts.has_previous %}
previous
{% endif %}
<span class="current">
Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.
</span>
{% if contacts.has_next %}
next
{% endif %}
</span>
</div>
{% endblock %}
Looks like you need separate view function, and deliver it results separately via ajax. May be something like this one:
def ajax_activity_objects_search(request):
search_phrase = request.GET.get('q')
matched = ActivityObject.objects.filter(
address__icontains=search_phrase,
)
response = ''
for act_object in matched:
response += '<option value="' + str(act_object.id) + '">' \
+ act_object.address + '</option>'
return HttpResponse(response)

Categories