Refresh html DIv in Django - javascript

i am trying to refresh an {%extends%} page since my base.html is getting message information from whatever is happening in the python backend, it only shows the message after i refresh my page and i want to refresh it every x seconds so the alerts will show without needing to refresh my entire page.
<div id="Mydiv">
{% extends 'crodlUSDT/base.html'%}
</div>
<script>
$(document).ready(function()
{
function refresh()
{
var div = $('#Mydiv'),
divHtml = div.html();
div.html(divHtml);
}
setInterval(function()
{
refresh()
}, 3000); //300000 is 5minutes in ms
})
</script>
this is what i've found online but tested a lot of different things but none are working, is this possible ?
thanks
ive also tried doing this inside of my html file
<div id="messages" class="messages">
{% if messages %}
{% for message in messages %}
<div class = "alert alert-{{message.tags}}">{{message}}</div>
{% endfor %}
{% endif %}
</div>
<script>
$(document).ready(function()
{
function refresh()
{
var div = $('#messages'),
divHtml = div.html();
div.html(divHtml);
}
setInterval(function()
{
refresh()
}, 3000); //300000 is 5minutes in ms
})
</script>
but also only shows the message after page refresh

Related

Passing context variable from template to JavaScript file

This thread here discussed using variables in inline JavaScript in templates. If I have separate .js files containing scripts, sitting in static folder, such as following:
utils.js
const createButton = (buttonCount) => {
containerId = "myContainerId"
container = document.getElementById(containerId)
for (var i = 0; i < buttonCount; i++) {}
newButton = document.createElement("button")
newButton.value = "Test"
newButton.id = "testButton" + i
container.appendChild(newButton)
}
}
createButton(buttonCount)
mytemplate.html
{% extends "base.html" %}
{% load static %}
{% block title %}Testpage{% endblock %}
{% block content-main %}
<link href="{% static "css/mycss.css" %}" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.4.0/css/bulma.css" />
<div id="myContainerId"></div>
<script src="{% static 'js/utils.js' %}"> </script>
{% endblock %}
If I have a variable buttonCount passed into this template via a view function's context, how do I pass it to the utils.js file to be called by function createButton()?
views.py
def button_view(request):
...
buttonCount = 5
return render(request, 'mytemplate.html', {'buttonCount': buttonCount})
There can be a few ways:
Using Input Field
<input id="buttonCount" value = "{{buttonCount}}" style="display:none;">
Then read value of element with id= buttonCount in utils.js.
Inline Script **Not Suggested,Use Document.onload instead.
<script>
set_button_count({{buttonCount}});
</script>
But this will create a problem when your utils.js is not loaded yet.
document.onload
Place the script source in <head></head>
<script src="{% static 'js/utils.js' %}" defer> </script>
<script>
document.addEventListener('onload',function(
{set_button_count({{buttonCount}});
})
</script>
set_button_count() is to be placed in utils.js
Defer will ask browser to only fire document load when utils.js
is complete and it will be fetched and loaded after the document is
loaded.
Warning: Inline scripts are to be used with strict CSP (Content Security Policy).Any inline script can be given a src as nonce.
CSP can be done on Server Side on apache or Nginx which are very common web server/reverse proxy or you can also mention the same in HTML if you don't have control on that.
<meta http-equiv="Content-Security-Policy"
content="default-src 'self';
script-src 'self' 'nonce-{{nonce}}';">
and this nonce can be generated something like this:
import random,base64
def usersession_processor(request):
user = request.user
unbaked_nonce = '%32x' % random.getrandbits(16*8)
unbaked_nonce = unbaked_nonce.encode('utf-8')
baked_nonce = base64.b64encode(unbaked_nonce)
baked_nonce = baked_nonce.decode('utf-8')
Then <script src="{{nonce}}"></script> can be used for safe inlines.
I don't think this is recommended but you could do something like this if you're using the django template context. Put the script at the bottom of the page and include the buttoncount as a Django Templating Language variable. I don't think it's recommended to mix Django template variables with javascript though.
You can put a new block in your 'base.html' file, at the bottom inside the body tag like this:
{% block inline_javascript %}
{% enblock inline_javascript %}
Then inside the page you want the function to run on you put the script inside the same tags at the bottom of that page outside the 'block content' like:
{% block inline_javascript %}
<script>
const createButton = ({{ buttonCount }}) => {
containerId = "myContainerId"
container = document.getElementById(containerId)
for (var i = 0; i < {{ buttonCount }}; i++) {}
newButton = document.createElement("button")
newButton.value = "Test"
newButton.id = "testButton" + i
container.appendChild(newButton)
}
}
</script>
{% enblock inline_javascript %}

show random php page in iframe using javascript

I would like to load .php in iframe. I have (more than) 10 php files in a folder with index.html,which has the iframe. In this i frame I would like load the .php files randomly (withou repeat-If all 10 files shown then show the messgae "No More") when user click Next... How do I write this javascript.
My index.html looks like this . This file and all the .php files placed in the same folder.
<!DOCTYPE HTML>
<html>
<head>
<title>Test</title>
<link rel="stylesheet" type="text/css" href="main.cs" />
</head>
<body class="is-demo">
<header id="demo-header">
<div class="details">
<div class="inner">
<h1>one.php title</h1>
</div>
</div>
<ul class="actions">
<li><a href="index.php" ><span>Home Page</span></a></li>
<li><span>Previous</span></li>
<li><span>Next</span></li>
</ul>
</header>
<script>
var iframe = document.getElementById("demo-iframe");
var pages = ["one.htm", "two.htm", "three.htm",
"four.htm", "five.htm", "six.htm",
"seven.htm", "eight.htm","nine.htm",
"ten.htm"];
function choose_random_page() {
if(pages.length>0) {
var r = Math.floor(Math.random(pages.length));
var ranom_page = pages.slice(r,1);
iframe.src = random_page;
} else {
alert("No more pages to load");
}
}
</script>
<div id="demo-main">
<iframe id="demo-iframe" src="" data-responsive="1">-</iframe>
</div>
</body>
</html>
Put all your pages to array, mix it, change the iframe src with javascript, exclude page from array after that.
var locations = ['a.php', 'b.php', 'c.php'];
for(var i = 0; i < locations.length; i++){
// I put code for changing locations inside setTimeout, but you can change it with your logic.
setTimeout(function(){
document.getElementById('demo-iframe').src = locations[i];
}, i * 1000)
}
One way to acheive that is to have all possible pages in an array, in any order.
Then once the function triggered to choose the random page, it should do the following:
a- check if pages array still has pages to choose from
b- select a random index between 0 and the number of elements in the array
c- slice the element from that array out and load iframe source with the value
var iframe = document.getElementById("demo-iframe");
var pages = ["one.php", "two.php", "three.php",
"four.php", "five.php", "six.php",
"seven.php", "eight.php","nine.php",
"ten.php"];
function choose_random_page() {
if(pages.length>0) {
var r = Math.floor(Math.random(pages.length));
var ranom_page = pages.slice(r,1);
iframe.src = random_page;
} else {
alert("No more pages to load");
}
}
<iframe id="demo-iframe">

Javascript of selected php file won't load when using JQuery's load(file.php) method

I have a master container php file with a div container. Initially, the div container doesn't have any content or html children by default when page is loaded. I use JQuery to load php files to this div container when the user clicks a navigation item in the navbar.
landingpage.php
<?php
require_once 'navbar.php';
?>
<!DOCTYPE html>
<html>
<head>
<title>Admin | Dashboard</title>
<link rel="stylesheet" href="css/dashboard_admin.css">
</head>
<body>
<div class="wrapper">
<!-- CONTENT CONTAINER's content depends on what was clicked on navbar -->
<div class="container" id="content_container">
<div class="div_dashboardLabel" id="dashboard_Label">
<h2 id="label_Dashboard">Admin Dashboard</h2>
</div>
</div>
<!-- END OF CONTENT CONTAINER-->
</div>
<!-- end of wrapper-->
<script src="js/jquery-3.3.1.js"></script>
<script type="text/javascript">
var user = '<?php echo json_encode($user);?>';
var role = '<?php echo json_encode($role); ?>';
</script>
<script src="js/landingpage.js"></script>
</body>
</html>
landingpage.js
/* GLOBAL VARIABLES WITHIN THIS DOCUMENT*/
var div_content_container = $("#content_container");
var navitem_dashboard = $("#admin_dashboard");
var navitem_admin_account_management = $("#admin_accountmanagement");
var userObj = JSON.parse(user);
var roleObj = JSON.parse(role);
var logout = $('#logout');
/* END */
$(document).ready(function(){
loadDashboard(); // dashboard is loaded as default view.
navitem_admin_account_management.on("click",loadAccountManagement);
});
function loadDashboard() {
var url_admin_dashboard = 'view/admin_dashboard.php';
var url_teacher_dashboard = 'view/teacher_dashboard.php';
var url_student_dashboard = 'view/student_dashboard.php';
div_content_container.html('');
if (roleObj.rolename === 'Administrator') {
div_content_container.load(url_admin_dashboard);
} else if (roleObj.rolename === 'Teacher') {
div_content_container.load(url_teacher_dashboard);
} else if (roleObj.rolename === 'Student') {
div_content_container.load(url_student_dashboard);
}
}
function loadAccountManagement(){
var url = 'view/admin_accountmanagement.php';
div_content_container.html('');
div_content_container.load(url);
}
Everything works as expected for landingpage.php which uses landingpage.js for the front end. No problem.
The problem is when admin_accountmanagement.php file is loaded in div_content_container. The JS of admin_account_management.php doesn't seem to bind to elements:
function loadAccountManagement(){
var url = 'view/admin_accountmanagement.php'; // has its JS file
div_content_container.html('');
div_content_container.load(url);
}
For example, let's take url which is 'view/admin_accountmanagement.php' This page gets loaded within div_content_container when user clicks a navbar item Account Management
as in
<div class="wrapper">
<!-- CONTENT CONTAINER's content depends on what was clicked on navbar -->
<div class="container" id="content_container">
<!-- view/admin_accountmanagement.php loaded here -->
</div>
<!-- END OF CONTENT CONTAINER-->
</div>
There are no problems displaying the page or replacing the current element contained in the div_content_container. The problem is, the JS file attached to view/admin_accountmanagement.php doesn't seem to apply when view/admin_accountmanagement.php page is loaded in div_content_container
The view/admin_accountmanagement.php is loaded but the click events binded to the elements of view/admin_accountmanagement.php doesn't work. I know this because I tried to display an alert() message on $(document).ready()
admin_accountmanagement.php
<body>
<div>
<button class="button" id="btn_AddUser">
Add New User
</button>
</div>
<script src="js/admin_accountmanagement.js"></script> <!-- this JS doesn't seem to get binded when this page is loaded in the div_content_container -->
</body>
admin_accountmanagement.js
var btn_add_user = $('#btn_AddUser');
$(document).ready(function(){
alert("TEST"); //doesn't work no alert message.
btn_add_user.on("click",test); //doesn't work no alert message
});
function test(){
alert("testing"); //doesn't work. no alert message
}
I'm only able to display the page but when I click on the <button id="btn_AddUser"> nothing happens.
How can I solve this given the how I structured the loading of pages to div_content_container?
Thanks in advance.
Change your admin_accountmanagement.js to
var btn_add_user = $('#btn_AddUser');
alert('Account management js loaded'); // this should show alert
$(document).on("click",btn_add_user,test);
function test(){
alert("testing"); //doesn't work. no alert message
}
This method works because the binding is not dependent on "document ready" as document ready has already been fired when you loaded the parent page for the first time
#jordan i agree with #Magnus Eriksson as it is better to bind it on('event','selector','function') but make use of .off() before your .on() as you are playing with dynamic content which may cause multiple binding of the function. And if you are still not able to get the binding event to work you can try injecting the .js file in your page's head section after the load of your content like: $('head').append('<script src="admin_accountmanagement.js"></script>'). With your load() function in your js to bind the click event.
Or, your use the below code snippet:
function LoadContent()
{
var url = 'view/admin_accountmanagement.php';
var jssrc = 'js/admin_accountmanagement.js';
div_content_container.html('');
div_content_container.load(url);
if($('head').find('*[src="'+jssrc+'"]').length==0)
{
//the below approach have some consequences related to it as you will not be able to see the injected js in your developers tool's Sources(in chrome).
$('head').append('<script src="'+jssrc+'"></script>');
}
}
and then on your .js will look like this:
var btn_add_user = null;
$(window).load(function(){
alert("TEST");
btn_add_user = $('#btn_AddUser');
btn_add_user.off('click').on("click",test); //use .off('event') if load() is being called multiple times.
});
function test(){
alert("testing");
}

Javascript enabling buttons works in JSFiddle but not in browser - Flask

I am using Python/Flask to develop a web app.
In a page I want to have some buttons disabled initially, and then enabled if a function is called.
In JSFiddle for example something like this works:
JSFiddle
However, if in my index.html file I have something like this:
{%- extends "base.html" %}
{% import "bootstrap/utils.html" as utils %}
{% block content %}
<h1>Three buttons!</h1>
<div id="audio">
<p>
<button id=startRecord onclick="startRecording()">Start</button>
<button id=stopRecord onclick="stopRecording()">Stop</button>
<button id=submitRecord onclick="submit()">Submit</button>
</p>
<p>
<audio id=recordedAudio></audio>
</p>
<p>
<a id=audioDownload></a>
</p>
</div>
{% endblock %}
{% block scripts %}
<script src="{{url_for('static', filename='js/recordtest.js')}}"></script>
{% endblock %}
Where recordtest.js is:
startRecord.disabled = false;
stopRecord.disabled = true;
submitRecord.disabled = true;
function startRecording() {
stopRecord.disabled = false;
}
All buttons start as enabled and are not changed with the function.
I am using Chrome.
Put following lines in your js files in a self executing javascript closure, something like written below.
$(function(){
startRecord.disabled = false;
stopRecord.disabled = true;
submitRecord.disabled = true;
function startRecording() {
stopRecord.disabled = false;
}
})();
Also, put type="text/javascript" in script tag for neatness.
Firstly put an alert in startRecording function to confirm that it is actually getting called, try the code like this
document.getElementById("startRecord").disabled = false;
document.getElementById("stopRecord").disabled = true;
document.getElementById("stopRecord").style.backgroundColor = '#aaa'; // or any color you need to make it look like its hidden
document.getElementById("submitRecord").disabled = true;
document.getElementById("submitRecord").style.backgroundColor = '#aaa'; // or any color you need to make it look like its hidden
function startRecording() {
alert();
document.getElementById("stopRecord").disabled = false;
document.getElementById("stopRecord").style.backgroundColor = '#FFF'; // or any color you need to make it look like its not hidden
}
Also Verify that your java-script files are properly linked, that's probably the cause

Filter Flask Rendered HTML Table Using jQuery

I am trying to render a jinja2 template that displays an html table and then dynamically filters the table but I cannot get it to work correctly. The table renders as expected but the search box used to dynamically filter the table isn't working. For reference, the script in layout.html works in a non-flask app.
Here is my flask app (message_log.py):
import pandas as pd
from flask import Flask, render_template
pd.set_option('display.max_colwidth', -1)
app = Flask(__name__)
message_log = pd.read_csv('data.csv')
table = message_log.to_html().replace('<tbody', '<tbody id="fbody"')
#app.route("/")
def show_table():
return render_template('index.html', table=table)
if __name__ == "__main__":
app.run(debug=True)
index.html:
{% extends "layout.html" %}
{% block body %}
Search (Case Sensitive): <input type="text" id="search" placeholder="type to search"/>
{{ table|safe }}
{% endblock %}
layout.html:
<!doctype html>
<html>
<head>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
// Search functionality
$("#search").keyup(function () {
//split the current value of searchInput
var data = this.value.split(" ");
//create a jquery object of the rows
var jo = $("#fbody").find("tr");
if (this.value == "") {
jo.show();
return;
}
//hide all the rows
jo.hide();
//Recusively filter the jquery object to get results.
jo.filter(function (i, v) {
var $t = $(this);
for (var d = 0; d < data.length; ++d) {
if ($t.is(":contains('" + data[d] + "')")) {
return true;
}
}
return false;
})
//show the rows that match.
.show();
}).focus(function () {
this.value = "";
$(this).css({
"color": "black"
});
$(this).unbind('focus');
}).css({
"color": "#C0C0C0"
});
</script>
<title>jQuery Example</title>
</head>
<body>
{% block body %}{% endblock %}
</body>
</html>
Move the second element to the bottom of index.html file just before the html tag closes. The jquery in your script was searching for an element that wasn't injected into your dom at the time that it was loaded.

Categories