Load data from flask into html when pressing a button - javascript

I am trying to load a variable into a HTML page when pressing a button. The problem is that I already have a function to load the initial page, and the new data shall be loaded on the same page, without redirecting.
This is the code i have by now:
.py file:
#app.route('/')
def index():
return render_template('index.html')
def get_documents():
documents = {'asd': 'as', 'def':'de'}
return render_template('index.html', documents=json.dumps(documents))
index.html file
<div>
<button onclick="Start()" id="StartButton" >Start</button>
</div>
<div id = "feed" style="display: none;">
</div>
<script>
var d = JSON.parse('{{documents | tojson | safe}}');
document.getElementById('feed').innerHTML = d.asd;
</script>
.js file:
function Start()
{
var feed_div = document.getElementById("feed");
feed_div.style.display = "block";
}
I would like that when i press the Start button, the content in the documents structure would appear in the .feed section. How could i do this?
Also, documents will be a list, but here i used a json because i wanted to try some examples i've found.

You can create div element inside the feed element, this element will contain all of your document data and will be hidden
<div id="document" style="display: hidden">
{% for item in documents %}
<div>{{ item }}</div>
{% endfor %}
</div>
and then in javascript change the display of the document element:
function start() {
document.getElementById("document").style.display = "block";
}

Related

Hide and show elements inside Django HTML template

I have 2 buttons orders, and suppliers., and want to show data in a Django web app when the corresponding button is clicked. To do this my home.html looks like
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
$(document).ready(function(){
$(".button_order").click(function(){
$(".myorders").show();
$(".mysupplier").hide();
});
$(".button_supplier").click(function(){
$(".myorders").hide();
$(".mysupplier").show();
});
});
</script>
syle.css looks like;
.myorders,
.mysupplier{
font-size: 25px;
display: none;
}
This works perfectly fine until I use normal data like;
<body>
{%block content %}
<button class="button_order" >ORDERS</button>
<button class="button_supplier" >SUPPLIER</button>
<p class="myorders" >
This is my order
</p>
<p class="mysupplier">
my supplier is cool
</p>
</body>
But when I try to use data into <p class="mysupplier"> or <p class="myorders" > from my databases, the hide property no longer works, like below part.
<p class="myorders">
{% for element in orders %}
{% for key,val in element.items %}
<ul><li>{{key}}:{{val}}</li></ul>
{% endfor %}
<hr class="new1">
{% endfor %}
</p>
I should get Order data from database only when ORDER button is clicked, but my server shows all data from before without even clicking the button. How to maintain hide and show the property of my data.
my views.py looks like
from django.shortcuts import render
client = MongoClient("mongodb://localhost:27017/")
db=client.inventory_data
def home(request):
collection_data_1 = db['orders']
orders = list(collection_data_1.find())
collection_data_2= db['suppliers']
suppliers = list(collection_data_2.find())
return render(request,'home.html',{'orders': orders,'suppliers':suppliers})
The loop in template is executed when rendering template. You pass all your data from view to template. if you just want to hide it from display add to your js:
<script>
$(document).ready(function(){
$(".mysupplier").hide();
$(".myorders").hide();
$(".button_order").click(function(){
$(".myorders").show();
$(".mysupplier").hide();
});
$(".button_supplier").click(function(){
$(".myorders").hide();
$(".mysupplier").show();
});
});
</script>
but if you would like to dynamicly fetch current data from db by pressing button i recommend use htmx (htmx.org)

Transferring a JS Array to Python using AJAX & Flask - not working

I am experiencing some problems with my code. My data loader to python isn't working. Here is my HTML site (using Jinja syntax from a base.html):
{% extends 'base.html' %}
{% block head %}
<title>PPO Count</title>
{% endblock %}
{% block body %}
<!-- Header -->
<div class="header">
<h2 class='title'>Prototype 1: Pet Owner Viz</h2>
</div>
<!-- Button Panel-->
<!-- Vis Box -->
<div class='canvas'>
<div class="container">
<div class='button-box'>
<button id='Bx' type="button" onclick='toggleClickedBuz("Bx", "Bx")'>Bx</button>
<button id='By' type="button" onclick='toggleClickedBuz("By", "By")'>By</button>
<button id='Bz' type="button" onclick='toggleClickedBuz("Bz", "Bz")'>Bz</button>
<button id='loadData'>Load Data</button>
</div>
<div class='viz-box'>
</div>
</div>
</div>
<!-- Scripts -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script type="text/javascript"></script>
<script src="https://code.jquery.com/jquery-3.4.1.slim.js"></script>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="/static/js/main.js"></script>
{% endblock %}
Notice the buttons? What occurs is that onclick, it goes into an array using JS. In sum this function deletes duplicate entries and changes the colour of the buttons on screen to highlight their selection.
const vizBox = d3.select('.viz-box');
const svg = vizBox.append('svg');
// Create button click array
var clickedBusinesses = [];
function toggle(business) {
clickedBusinesses[business] = !clickedBusinesses[business];
};
function getClickedBusinesses() {
return Object.keys(clickedBusinesses).filter(key => clickedBusinesses[key]);
};
// Update array and change button colour to reflect selection
function toggleClickedBuz( bizStr , id ) {
if(clickedBusinesses.includes(bizStr)){
// removing duplicate element from that array, dependant on button pressed
clickedBusinesses = clickedBusinesses.filter( cb => cb !== bizStr );
document.getElementById( id ).style.backgroundColor='white';
}else{
// else push it to the array
clickedBusinesses.push(bizStr)
document.getElementById( id ).style.backgroundColor='red';
}
var json_string = JSON.stringify(clickedBusinesses)
console.log(json_string)
};
window.onload = function() {
d3.select('loadData').onclick = function() {
doWork()
};
}
function doWork() {
$.post('receiver', json_string, function() {
});
event.preventDefault();
}
button id='loadData' isn't working, I can't get my jsonified JS array into python. Any thoughts?
d3.select does not return a native DOM node, it returns a so called d3-selection that doesn't know anything about onclick. Instead, you should use the .on method of a d3-selection to register event listeners as described here: https://github.com/d3/d3-selection#handling-events
Alternatives:
Instead of using d3 to select elements, use the native .querySelector method: document.querySelector('#loadData').onclick = ....
Or use jQuery for it: $('#loadData').on('click', ...).

How to add on click to list of products in html and get the item clicked to firestore

I'm trying to make a simple shopping cart using Django and Firebase Admin SDK, I have queried the Firestore data in a list and displayed them in HTML, now I want to add a click listener to the list of items and get the item clicked into a Firestore collection using javascript.
Now, when I click on an item other than the first item nothing happens, that is, when I click on the first item displayed on the page everything works out fine, but the other does not.
python view.py to display the items
def home(request):
collection_ref = db.collection(u'products').get()
documents = list(doc.to_dict() for doc in collection_ref)
return render (request,'store/home.html',{'product':documents})
home.html
{% block content %}
{% for doc in product %}
<div class="jumbotron">
<div class="col-sm-4">
<div class="card" >
<div class="card-body">
<a href="#" class="img-prod"><img class="img-fluid" id="productUrl" src="{{doc.productImage}}" alt="{{doc.productName}}">
<h1 class="card-title" id="productName">{{doc.name}}</h1>
<p class="card-subtitle mb-2 text-muted" id="productPrice">{{doc.price}}</p>
<p class="card-text" id="productDescription">{{doc.description}}</p>
<button type="button" id="addtocart">Add to cart</button>
</div>
</div>
</div>
</div>
{% endfor %}
{% endblock content %}
js code
firebase.initializeApp(firebaseConfig);
var db = firebase.firestore();
var addToCart=document.getElementById('addtocart');
addToCart.addEventListener('click', (event) =>{
var image=document.getElementById('productUrl').src;
var productName = document.getElementById('productName').innerHTML;
var productPrice= document.getElementById('productPrice').innerHTML;
db.collection("orders").add({
pName: productName,
price: productPrice,
url:image
})
.then(function(docRef) {
console.log("Document written with ID: ", docRef.id);
})
.catch(function(error) {
console.error("Error adding document: ", error);
});
})
You should always try to keep ids unique throughout the whole document. findElementById only returns the first element that it finds, so you add a listener to the first list item only when you run
var addToCart=document.getElementById('addtocart');
addToCart.addEventListener('click', (event) =>{...
You should define an add_to_cart function in your javascript that takes parameters and then in your for loop in the html you can have something like
<button onclick="add_to_cart({{doc.name}},{{doc.price}})>Add to cart</button>"

Django Template Value Passed to Javascript

I am working on a turn-based game where players can, but don't have to, gain ownership of certain spaces on the game board. My detail view in shows the spaces owned by each player, and I use a loop to display all owned spaces:
<small class="text-muted">Spaces Owned</small>
<div class="list-group list-group-flush">
{% for space in player.space_set.all %}
<a class="list-group-item" data-toggle="modal" data-target="#spaceModal" id="modalButton">
{{ space.name }}
</a>
{% endfor %}
</div>
I want to be able to populate a modal with all detailed information about whichever space is clicked on (hence why I'm using the anchor tag instead of a div, though I guess it might not matter as much). The modal would look something like this, though the goal is to populate it using appropriate IDs, etc using the response from the AJAX call instead of the template variables currently used as placeholders:
<div class="modal fade" id="spaceModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body">
<div class="wrapper">
<div class="box">
<h2>{{ space.name }}</h2>
<div class="float-left">{{ space.location }}</div>
<div class="float-right">{{ space.defense_points }}</div>
<br />
<div class="float-right">{{ space.attack_points }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
What I want to be able to do is use an AJAX call to populate the modal for each space as it is clicked. I have the server-side function set up okay and it is correctly returning the JSON needed when I process a simple get request (I'm using the following url pattern):
from django.urls import path
urlpatterns = [
path('<int:game>/space_data/<int:space>', get_space_data, name = 'get_space_data'),
]
with my views.py defined as:
def get_space_data(request,game,space):
game = Game.objects.get(pk=game)
space = game.space_set.get(location=space)
data = {
'name': space.name,
'location': space.location,
'defense_points': space.defense,
'attack_points': space.attack,
}
return JsonResponse(data)
Right now the JS that I'm using to test usage is the following:
<script>
$("#modalButton").click(function(){
var space = "{{ space }}"
console.log(space)
alert('Modal Button Clicked')
})
</script>
Summary
Essentially all I want to be able to do, which I can't figure out how to do, is pass the space variable to the JS code so that I can build the appropriate AJAX call within the last script code.
To touch on what Daniel wrote, what I was asking was simply how to pass Django template data to a JQuery script, which I would then use in an AJAX call. I figured it out, though, and will post my answer here instead of just deleting the question.
The modal pop-up anchor tag should look like this:
<small class="text-muted">Spaces Owned</small>
<div class="list-group list-group-flush">
{% for space in player.space_set.all %}
<a class="list-group-item" data-toggle="modal" data-target="#spaceModal" id="modalButton" data-location="{{ space.location }}">
{{ space.name }}
</a>
{% endfor %}
</div>
and the resulting JQuery code is as follows:
<script>
$("#modalButton").click(function(){
console.log($(this).data('location'))
alert('Modal Button Clicked')
})
</script>
From this I will be able to add an actual AJAX call to the script and pull the data as needed.
in this way you send the variables to the js to use them in the ajax
{% block scripts %}
<script>
var name = {{space.name}}
var location = {{space.location}}
</script>
<!-- JS Template -->
<script src="{% static 'folder/name.js' %}"></script>
{% endblock scripts %}
and your js
$.ajax({
url: url,
method: "",
data: {
"name" : name,
"location":location
},
success: function (_response) {
},
)

Flask jinja2 update div content without refresh page

Need achieve some features like [http://webonise.co.uk/][1] when click on contact,resume,resources link will update (location URL&div content) but without refresh the page.
Flask view function
#app.route('/')
def index():
flash('Welcome')
return render_template('index.html')
Under index.html is extends base.html
{% block content %}
{{super()}}
<section class="content">
<i class="mdi-event"></i>Event
<i class="mdi-contact"></i>Contact
<div class="board">
{# dynamic template #}
{# without using {{% include 'event.html' %}} #}
</div>
</section>
{%- endblock %}
How can i dynamic rendar event.html / contact.html content when different link is click and rendar under {# dynamic template #} without refresh the page ?
<!--event.html-->
<ul class="list">
<li>
<h3>123</h3>
<p>abc</p>
</li>
</ul>
What I try
import jinja2 Environment but still no idea how to achieve this
env = Environment(autoescape=True,
loader=FileSystemLoader(os.path.join(os.path.dirname(__file__), 'templates')))
#app.route('/')
def index():
board = env.get_template('event.html')
flash('Welcome Home Tyler')
return render_template('index.html', board=board)
Is there really need ajax technique get/post method to achieve all this?
You can use Flask-Sijax which helps you add Sijax support to your Flask app. Sijax is a python/jquery library that makes AJAX easy to use on your web applications. Alternatively you could do this:
<script>
$(document).ready( function() {
$('#next').click(function() {
$.ajax("{{ url_for('yourroute') }}").done(function (reply) {
$('#container').html(reply);
});
});
});
</script>
<input type="button" id="next" value="Next" />
<div id="container"></div>

Categories

Resources