I have a Django template that contains some Django templating blocks. I have another template that contains some JavaScript that does an Ajax request to pull this Django template in. It looks something like this:
$.ajax({
url: '/page/',
method: 'GET',
success: function (data) {
console.log($(data).find(".wrapper"));
}
});
/page.html/ contains the following:
{% extends 'core/base.html' %}
{% block content %}
<div class="example">
..some..content..
</div>
{% endblock %}
page.html extends base.html which has a wrapper <div class="wrapper"></div> however, when I run the Ajax code, the console does not find the wrapper class. Is there a way to get the full template page?
Example of raw data to console output
<!DOCTYPE html>
<html lang="en">
<head>
<link href="/static/core/patterns.css?1587877907" rel="stylesheet" type="text/css">
</head>
<body>
<div class="wrapper">
<div class="jumbotron jumbotron-gray">
<article class="post" data-key="294" data-slug="example">
<div class="post__details">Example</div>
</article>
</div>
</div>
<script src="/static/core/base.js?1587877907"></script>
</body>
</html>
Related
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}}.
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 I can not apply css file when render part of template?
I have studied render page with model after ajax post
, for now I know I can return part of html file into specific div which is in certain html
My problem, example:
There are 2 html file names
father.html and children.html, I want to fill children.html into a div tag in father.html, its OK for me! But why tags in children.html couldn't apply css(setup on father.css)
father.html has its own external file father.css and father.js
For father.html:
<html>
<head>
<link rel="stylesheet" href="{{ url_for('static', filename='css/father.css') }}">
<script src="{{ url_for('static', filename='js/father.js') }}"></script>
</head>
<body>
<div id="container">
<!-- ### children.html here!! Using AJAX ### -->
</div>
</body>
</html>
For father.js
$.ajax({
url: '/returnChildrenTemplate',
success: function(data) {
$('#container').html(data); // return template into container
}
})
For father.css
canvas {
width: 100px;
height: 100px;
}
For children.html:
<table>
{% for r in data %}
<tr>
<td> {{ r.id }} </td>
<td>
<canvas class="demo" style="background-color: {{r.color }} "></canvas>
</td>
</tr>
{% endfor %}
</table>
For back-end flask script:
#app.router('/returnChildrenTemplate')
def returnChildrenTemplate():
result = ... # query from Database
return render_template('children.html', data=result)
It doesn't work for children.html, its canvas tag is still its original size.
It works if I set canvas style into children.html. ( It quite stupid)
<head>
<style>
canvas {
height: 100px;
width: 100px;
}
</style>
</head>
<table>
...
(( the same as above ))
...
</table>
What is this issue? Is there any method to solve this ?
BTW, father.js has the same problem.
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.
I have a base.html and an index.html that extends base.html and fills out a {% block content %}{% endblock %}. However, for some reason, the javascript that I have in the block that deals with initiating a Google Map doesn't create the map - the page is blank. Without extending the base.html (i.e. just by typing everything in base.html out in index.html explicitly), the map works fine. The code:
base.html
<!DOCTYPE html>
{% load static %}
<html>
<head>
<title>Title</title>
<link rel="stylesheet" type="text/css" href='{% static "mh_app/style.css" %}' />
</head>
<body>
<header id="header">
<div class="header-cont">
<h1>
Title
</h1>
<nav id="nav">
<ul>
<li>
Home
</li>
<li>
Download
</li>
<li>
About
</li>
</ul>
</nav>
</div>
</header>
{% block content %}{% endblock %}
</body>
</html>
index.html
{% block content %}
<div id='map'></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script type='text/javascript'>
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 38.3499047, lng: -100.0770253},
zoom: 4
});
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=<my_api_key>&callback=initMap" async defer></script>
{% endblock %}
I've tried sticking some console.log statements inside initMap(), and they run just fine, so I have no idea why the map is not appearing.
EDIT
style.css
#map {
height: 90%;
width: 100%;
}
Do you have styles for the map div ?
Add height and width for the map div, try changing <div id="map"></div> to something like <div id="map" style="width: 500px; height: 500px;"></div>