How to change CSS class in Python - flask website - python
What is the simplest way to change class name form .black to .white in the example below using python and flask framework? For example: after mouse click on div #area ?
CSS file:
#area {position:absolute;width:100px;height:100px;}
.black {background-color:#000;}
.white {background-color:#fff;}
HTML file:
<!doctype html>
<html>
<head>
<title>Title</title>
<link rel="stylesheet" href="{{ url_for('static',filename='style.css')}}">
</head>
<body>
<div id="area" class="black"></div>
</body>
</html>
This need JavaScript and it has nothing to do with Flask
Example using querySelector()
<div id="area" class="black" onclick="change();"></div>
<script>
area = document.querySelector('#area');
function change(){
area.classList.replace('black', 'white');
}
</script>
or using special variable this
<div id="area" class="black" onclick="change(this);"></div>
<script>
function change(item){
item.classList.replace('black', 'white');
}
</script>
Eventually you could use addEventListener instead of onclick
<div id="area" class="black"></div>
<script>
function change(){
this.classList.replace('black', 'white');
}
area = document.querySelector('#area');
area.addEventListener('click', change);
</script>
or shorter
<div id="area" class="black"></div>
<script>
area = document.querySelector('#area');
area.addEventListener('click', function(){
this.classList.replace('black', 'white');
});
</script>
or even little shorter
<div id="area" class="black"></div>
<script>
document.querySelector('#area').addEventListener('click', function(){
this.classList.replace('black', 'white');
});
</script>
Minimal working code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Title</title>
<style>
#area1 {width:100px;height:100px;}
#area2 {width:100px;height:100px;}
#area3 {width:100px;height:100px;}
#area4 {width:100px;height:100px;}
.black {background-color:#000;}
.white {background-color:#fff;}
</style>
</head>
<body>
<div id="area1" class="black" onclick="change1();"></div>
<br>
<div id="area2" class="black" onclick="change2(this);"></div>
<br>
<div id="area3" class="black"></div>
<br>
<div id="area4" class="black"></div>
<script>
area1 = document.querySelector('#area1');
function change1(){
area1.classList.replace('black', 'white');
console.log('change1');
}
function change2(item){
item.classList.replace('black', 'white');
console.log('change2');
}
function change3(){
this.classList.replace('black', 'white');
console.log('change3');
}
area3 = document.querySelector('#area3');
area3.addEventListener('click', change3);
area4 = document.querySelector('#area4');
area4.addEventListener('click', function(){
this.classList.replace('black', 'white');
console.log('change4');
});
</script>
</body>
</html>
Using Python you would have to use <a></a> which would send information to server when you click it. And server would use Python to generate HTML with new class and send it back to browser. But it means to reload all page and it needs time.
Minimal working code:
I put black area in <a></a> which ?color=white and when server gets it then it sends back HTML with white area and with ?color=black, etc.
from flask import Flask, request, render_template_string
app = Flask(__name__)
#app.route('/')
def index():
color = request.args.get('color', 'black')
if color == 'black':
other = 'white'
else:
other = 'black'
return render_template_string('''
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Title</title>
<style>
#area {width:100px;height:100px;}
.black {background-color:#000;}
.white {background-color:#fff;}
</style>
</head>
<body>
<div id="area" class="{{ color }}"></div>
</body>
</html>''', color=color, other=other)
if __name__ == '__main__':
app.run()
It is not popular but you can load JavaScript module Brython to run some Python code in web browser. But you can uses only modules converted to JavaScript
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Title</title>
<style>
#area {width:100px;height:100px;}
.black {background-color:#000;}
.white {background-color:#fff;}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/brython/3.9.1/brython.min.js"></script>
</head>
<body onload="brython()">
<div id="area" class="black"></div>
<script type="text/python">
from browser import document
def change(ev):
if document['area'].attrs['class'] == 'black':
document['area'].attrs['class'] = 'white'
else:
document['area'].attrs['class'] = 'black'
document["area"].bind("click", change)
</script>
</body>
</html>
There is also transcrypt which can convert some Python code to JavaScript code and run in web browser.
Similar module RapydScript
Thanks, but it must be Python. I have found solution for printing a list, for example:
If I create a list called 'content'=['white','black'] the code below will print: white black and it works fine.
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="{{ url_for('static',filename='style.css')}}">
</head>
<body>
{% for x in content %}
{{x}}
{% endfor %}
</body>
</html>
So according to my question the code below should also work:
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="{{ url_for('static',filename='style.css')}}">
</head>
<body>
{% if x==1 %}
<div id="area" class="white"></div>
{% else %}
<div id="area" class="black"></div>
{% endif %}
</body>
</html>
But it doesn't, any ideas?
Related
Why is my image not showing up when using html and flask?
I have the image in the static folder but the image is not displaying however the css part is working fine. How do I make it so that my image is displayed. I have tried using normal html and inserted the url_for function from flask but it doesn't want to appear. body {color:#3366CC;} <!DOCTYPE html> <html lang = "en"> <head> <meta charset = "utf-8"> <meta http-equiv = "X-UA-Compatible" content = "IE = edge"> <meta name = "viewport" content = "width = device - width, initial-scale = 1.0"> <link rel = "stylesheet" href = "{{url_for('static', filename='Styles/index.css')}}"> <title>{% block title %}{% endblock %}</title> </head> <body> <header> <div class="logo"> <image scr="{{url_for('static', filename='Images/logo.png')}}", alt="lol"> </div> </header> {% block content %} {% endblock %} </body> </html>
You use scr attribute instead src (so it's just a wrong typing).
Version issue with embedding bokeh on heroku app
I am having a problem embedding Bokeh on Heroku. It works fine on my local machine, but something is wrong, when I try on heroku. Below is the html file. My guess is the data is not embedding correctly. For instance __ndarray__ has some weird characters instead of the data. I had been struggling to find a solution. Can someone provide help? <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Time-series plot</title> <link rel="stylesheet" href="http://cdn.bokeh.org/bokeh/release/bokeh-0.12.3.min.css" type="text/css" /> <script type="text/javascript" src="http://cdn.bokeh.org/bokeh/release/bokeh-0.12.3.min.js"></script> <script type="text/javascript"> (function() { var fn = function() { Bokeh.safely(function() { var docs_json = {"25435e2e-0cb3-47b8-8bf1-32c906b6f420":{"roots":{"references":[{"attributes":{"callback":null},"id":"10baebf3-faeb-46d1-859d-3263c6cd9354","type":"DataRange1d"},{"attributes":{"line_alpha":{"value":0.1},"line_color":{"value":"#1f77b4"},"x":{"field":"x"},"y":{"field":"y"}},"id":"2be1d120-5724-460f-b0f0-7231d7e46726","type":"Line"},{"attributes":{"base":60,"mantissas":[1,2,5,10,15,20,30],"max_interval":1800000.0,"min_interval":1000.0,"num_minor_ticks":0},"id":"062863cd-1ed4-4b1a-af68-b016860bd87a","type":"AdaptiveTicker"},{"attributes":{"bottom_units":"screen","fill_alpha":{"value":0.5},"fill_color":{"value":"lightgrey"},"left_units":"screen","level":"overlay","line_alpha":{"value":1.0},"line_color":{"value":"black"},"line_dash":[4,4],"line_width":{"value":2},"plot":null,"render_mode":"css","right_units":"screen","top_units":"screen"},"id":"616ed4ac-d4c5-4010-beff-1589b8b73f52","type":"BoxAnnotation"},{"attributes":{"max_interval":500.0,"num_minor_ticks":0},"id":"9517227c-f613-42bc-a35e-ae3c9543f317","type":"AdaptiveTicker"},{"attributes":{"items":[{"id":"2fd93036-1ef3-4d56-bad7-88fdf9352c21","type":"LegendItem"}],"location":"top_left","plot":{"id":"8fa14872-25cd-4dec-82ab-b1dd9b8a852f","subtype":"Figure","type":"Plot"}},"id":"13ee15d7-a5bd-40c8-b896-6d8955b883ee","type":"Legend"},{"attributes":{},"id":"751d139b-ceca-4eec-acbd-41e25b434a73","type":"DatetimeTickFormatter"},{"attributes":{},"id":"34d4f26b-a640-4129-88fd-578633815bbd","type":"YearsTicker"},{"attributes":{"below":[{"id":"f8b00322-303d-4c46-a577-b48573240aa7","type":"DatetimeAxis"}],"left":[{"id":"77143d5d-525f-4d25-acea-5c424eded496","type":"LinearAxis"}],"plot_height":500,"plot_width":800,"renderers":[{"id":"f8b00322-303d-4c46-a577-b48573240aa7","type":"DatetimeAxis"},{"id":"aa08aef8-adbe-4ac9-bb30-3276e6833765","type":"Grid"},{"id":"77143d5d-525f-4d25-acea-5c424eded496","type":"LinearAxis"},{"id":"bff245c2-03a5-411c-a938-515909623506","type":"Grid"},{"id":"616ed4ac-d4c5-4010-beff-1589b8b73f52","type":"BoxAnnotation"},{"id":"4311d6d9-1db1-4a28-b427-4f0d3da33a8d","type":"BoxAnnotation"},{"id":"13ee15d7-a5bd-40c8-b896-6d8955b883ee","type":"Legend"},{"id":"baee81d6-e664-46ba-b9d3-2e030d7fd672","type":"GlyphRenderer"}],"title":{"id":"ed0051be-e237-4b47-8663-afb3b1f1ce7c","type":"Title"},"tool_events":{"id":"93f77166-b47d-4147-8f40-60587534bb6e","type":"ToolEvents"},"toolbar":{"id":"9af07266-a889-4c6c-8e88-7a1f31d740f0","type":"Toolbar"},"x_range":{"id":"10baebf3-faeb-46d1-859d-3263c6cd9354","type":"DataRange1d"},"y_range":{"id":"4ffcdd86-22b4-4b7a-be07-ac70c84c27db","type":"DataRange1d"}},"id":"8fa14872-25cd-4dec-82ab-b1dd9b8a852f","subtype":"Figure","type":"Plot"},{"attributes":{"band_fill_alpha":{"value":0.1},"band_fill_color":{"value":"olive"},"dimension":1,"grid_line_alpha":{"value":0},"plot":{"id":"8fa14872-25cd-4dec-82ab-b1dd9b8a852f","subtype":"Figure","type":"Plot"},"ticker":{"id":"06fb8ff2-d611-405b-be38-e171cbf46d8c","type":"BasicTicker"}},"id":"bff245c2-03a5-411c-a938-515909623506","type":"Grid"},{"attributes":{"months":[0,2,4,6,8,10]},"id":"5fc979d4-46a9-469c-af56-527c9d4cb163","type":"MonthsTicker"},{"attributes":{"num_minor_ticks":5},"id":"f897d924-3e38-464c-a5af-8eb5d3b68094","type":"DatetimeTicker"},{"attributes":{"data_source":{"id":"6d6fc44a-63fb-4b3d-95b8-3d219a92f1ca","type":"ColumnDataSource"},"glyph":{"id":"dfd7789a-7064-469a-aed1-0f49e3bb6fb7","type":"Line"},"hover_glyph":null,"nonselection_glyph":{"id":"2be1d120-5724-460f-b0f0-7231d7e46726","type":"Line"},"selection_glyph":null},"id":"baee81d6-e664-46ba-b9d3-2e030d7fd672","type":"GlyphRenderer"},{"attributes":{},"id":"06fb8ff2-d611-405b-be38-e171cbf46d8c","type":"BasicTicker"},{"attributes":{"days":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]},"id":"413be9a6-f974-4bb0-a547-fd109820f4ac","type":"DaysTicker"},{"attributes":{"active_drag":"auto","active_scroll":"auto","active_tap":"auto","tools":[{"id":"ad71abf4-7812-47df-974c-bdf963267996","type":"PanTool"},{"id":"4651a289-09bc-4249-ab43-dcf8d0073edf","type":"WheelZoomTool"},{"id":"a630d9b3-35fa-4631-8971-6ffe63f5f285","type":"BoxZoomTool"},{"id":"2d21e9c6-d52c-4788-a4c1-96bb295c2421","type":"ResetTool"},{"id":"94e83390-ed62-4543-81c3-177bb7404bd0","type":"SaveTool"},{"id":"7d10de35-f889-4af5-a737-7b7e18177842","type":"BoxSelectTool"}]},"id":"9af07266-a889-4c6c-8e88-7a1f31d740f0","type":"Toolbar"},{"attributes":{"callback":null},"id":"4ffcdd86-22b4-4b7a-be07-ac70c84c27db","type":"DataRange1d"},{"attributes":{"days":[1,8,15,22]},"id":"f1182eaa-c07f-4f7a-b6e2-e2e003b26503","type":"DaysTicker"},{"attributes":{"plot":null,"text":"Data for GOOG from Quandle WIKI set"},"id":"ed0051be-e237-4b47-8663-afb3b1f1ce7c","type":"Title"},{"attributes":{"base":24,"mantissas":[1,2,4,6,8,12],"max_interval":43200000.0,"min_interval":3600000.0,"num_minor_ticks":0},"id":"2cee3978-4144-4aee-9971-b93db0a60f31","type":"AdaptiveTicker"},{"attributes":{"plot":{"id":"8fa14872-25cd-4dec-82ab-b1dd9b8a852f","subtype":"Figure","type":"Plot"}},"id":"94e83390-ed62-4543-81c3-177bb7404bd0","type":"SaveTool"},{"attributes":{"plot":{"id":"8fa14872-25cd-4dec-82ab-b1dd9b8a852f","subtype":"Figure","type":"Plot"}},"id":"2d21e9c6-d52c-4788-a4c1-96bb295c2421","type":"ResetTool"},{"attributes":{"callback":null,"column_names":["x","y"],"data":{"x":{"__ndarray__":"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","dtype":"float64","shape":[711]},"y":{"__ndarray__":"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","dtype":"float64","shape":[711]}}},"id":"6d6fc44a-63fb-4b3d-95b8-3d219a92f1ca","type":"ColumnDataSource"},{"attributes":{},"id":"93f77166-b47d-4147-8f40-60587534bb6e","type":"ToolEvents"},{"attributes":{"line_color":{"value":"blue"},"x":{"field":"x"},"y":{"field":"y"}},"id":"dfd7789a-7064-469a-aed1-0f49e3bb6fb7","type":"Line"},{"attributes":{"grid_line_alpha":{"value":0},"plot":{"id":"8fa14872-25cd-4dec-82ab-b1dd9b8a852f","subtype":"Figure","type":"Plot"},"ticker":{"id":"f897d924-3e38-464c-a5af-8eb5d3b68094","type":"DatetimeTicker"}},"id":"aa08aef8-adbe-4ac9-bb30-3276e6833765","type":"Grid"},{"attributes":{"label":{"value":"Adj. Close"},"renderers":[{"id":"baee81d6-e664-46ba-b9d3-2e030d7fd672","type":"GlyphRenderer"}]},"id":"2fd93036-1ef3-4d56-bad7-88fdf9352c21","type":"LegendItem"},{"attributes":{"plot":{"id":"8fa14872-25cd-4dec-82ab-b1dd9b8a852f","subtype":"Figure","type":"Plot"}},"id":"ad71abf4-7812-47df-974c-bdf963267996","type":"PanTool"},{"attributes":{},"id":"48053516-3d87-4026-986f-48129fc60e01","type":"BasicTickFormatter"},{"attributes":{"months":[0,6]},"id":"36d97b27-7fc5-4095-a5b7-6ec9003c8381","type":"MonthsTicker"},{"attributes":{"axis_label":"Date","formatter":{"id":"751d139b-ceca-4eec-acbd-41e25b434a73","type":"DatetimeTickFormatter"},"plot":{"id":"8fa14872-25cd-4dec-82ab-b1dd9b8a852f","subtype":"Figure","type":"Plot"},"ticker":{"id":"f897d924-3e38-464c-a5af-8eb5d3b68094","type":"DatetimeTicker"}},"id":"f8b00322-303d-4c46-a577-b48573240aa7","type":"DatetimeAxis"},{"attributes":{"days":[1,15]},"id":"5c4984ed-252e-4eae-a6a2-1cf39a55814a","type":"DaysTicker"},{"attributes":{"months":[0,1,2,3,4,5,6,7,8,9,10,11]},"id":"4d867e4d-d57d-47b0-a9ed-037e2feeb430","type":"MonthsTicker"},{"attributes":{"bottom_units":"screen","fill_alpha":{"value":0.5},"fill_color":{"value":"lightgrey"},"left_units":"screen","level":"overlay","line_alpha":{"value":1.0},"line_color":{"value":"black"},"line_dash":[4,4],"line_width":{"value":2},"plot":null,"render_mode":"css","right_units":"screen","top_units":"screen"},"id":"4311d6d9-1db1-4a28-b427-4f0d3da33a8d","type":"BoxAnnotation"},{"attributes":{"callback":null,"overlay":{"id":"4311d6d9-1db1-4a28-b427-4f0d3da33a8d","type":"BoxAnnotation"},"plot":{"id":"8fa14872-25cd-4dec-82ab-b1dd9b8a852f","subtype":"Figure","type":"Plot"},"renderers":[{"id":"baee81d6-e664-46ba-b9d3-2e030d7fd672","type":"GlyphRenderer"}]},"id":"7d10de35-f889-4af5-a737-7b7e18177842","type":"BoxSelectTool"},{"attributes":{"days":[1,4,7,10,13,16,19,22,25,28]},"id":"18e0bad7-fd4d-483a-a66d-8326fd4cb8d4","type":"DaysTicker"},{"attributes":{"axis_label":"Price","formatter":{"id":"48053516-3d87-4026-986f-48129fc60e01","type":"BasicTickFormatter"},"plot":{"id":"8fa14872-25cd-4dec-82ab-b1dd9b8a852f","subtype":"Figure","type":"Plot"},"ticker":{"id":"06fb8ff2-d611-405b-be38-e171cbf46d8c","type":"BasicTicker"}},"id":"77143d5d-525f-4d25-acea-5c424eded496","type":"LinearAxis"},{"attributes":{"months":[0,4,8]},"id":"541618b2-937c-4225-a9e3-c94d0e9cac89","type":"MonthsTicker"},{"attributes":{"plot":{"id":"8fa14872-25cd-4dec-82ab-b1dd9b8a852f","subtype":"Figure","type":"Plot"}},"id":"4651a289-09bc-4249-ab43-dcf8d0073edf","type":"WheelZoomTool"},{"attributes":{"overlay":{"id":"616ed4ac-d4c5-4010-beff-1589b8b73f52","type":"BoxAnnotation"},"plot":{"id":"8fa14872-25cd-4dec-82ab-b1dd9b8a852f","subtype":"Figure","type":"Plot"}},"id":"a630d9b3-35fa-4631-8971-6ffe63f5f285","type":"BoxZoomTool"}],"root_ids":["8fa14872-25cd-4dec-82ab-b1dd9b8a852f"]},"title":"Bokeh Application","version":"0.12.4"}}; var render_items = [{"docid":"25435e2e-0cb3-47b8-8bf1-32c906b6f420","elementid":"f91b2880-937e-436d-88b0-04c339475f6f","modelid":"8fa14872-25cd-4dec-82ab-b1dd9b8a852f"}]; Bokeh.embed.embed_items(docs_json, render_items); }); }; if (document.readyState != "loading") fn(); else document.addEventListener("DOMContentLoaded", fn); })(); </script> </head> <body> <div class=page> <h1> Generated plot for GOOG </h1> <h4> Back</h4> <div class="bk-root"> <div class="bk-plotdiv" id="f91b2880-937e-436d-88b0-04c339475f6f"></div> </div> </div> </body> </html>
Problem to be the versioning of bokeh. In the html file had 0.12.3, but my requirements.txt had bokeh>=0.12.3, and because of which heroku was using 0.12.4. Changing the requirements.txt file to bokeh==0.12.3 fixed the problem.
Python Flask + AngularJS + DevExtreme
First, I am fairly new to javascript but I know my way around python. I am trying to learn javascript and I may be out of my league with trying this, but that is how you learn right. Secondly, Flask and AngularJS play well together with a little help. Special thanks goes to shea256 (https://github.com/shea256/angular-flask) Now, I am able to get the 'test application' up and running fairly easily. However, I want to add DevExtreme to this stack and I am having some issues. Here is what I have: index.html <!doctype html> <html lang="en" ng-app="AngularFlask"> <head> <meta charset="utf-8"> <title>AngularFlask</title> <link rel="stylesheet" href="/static/css/bootstrap.css"> <link rel="stylesheet" href="/static/css/main.css"> <link rel="stylesheet" type="text/css" href="http://cdn3.devexpress.com/jslib/16.1.5/css/dx.common.css" /> <link rel="stylesheet" type="text/css" href="http://cdn3.devexpress.com/jslib/16.1.5/css/dx.light.css" /> <!--<script src="/static/lib/jquery/jquery.min.js"></script>--> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script> <!--2.7.0--> <!--<script src="/static/lib/angular/angular.js"></script> <script src="/static/lib/angular/angular-resource.js"></script>--> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular-resource.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular-route.min.js"></script> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular-sanitize.min.js"></script> <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/globalize/0.1.1/globalize.min.js"></script> <!--<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.min.js"></script> --> <script type="text/javascript" src="http://cdn3.devexpress.com/jslib/16.1.5/js/dx.web.js"></script> <script src="/static/js/app.js"></script> <script src="/static/js/controllers.js"></script> <script src="/static/js/services.js"></script> <script src="/static/lib/bootstrap/bootstrap.min.js"></script> </head> <body> <div id="header" class="header navbar navbar-static-top"> <div class="navbar-inner"> <div class="container"> <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> </button> <a class="brand" href="/">AngularFlask</a> <div class="nav-collapse collapse"> <ul class="nav pull-right"> <li class=""> Home </li> </ul> </div> </div> </div> </div> <div class="container page"> <div id="content" class="container main" ng-view> </div> <hr> <footer id="footer" class="footer"> <div class="footer-left"> About | Home </div> <div class="footer-right"> <span>© 2013 AngularFlask</span> </div> </footer> </div> </body> </html> controllers.js function IndexController($scope) { } function AboutController($scope) { } function PostListController($scope, Post) { var postsQuery = Post.get({}, function(posts) { $scope.posts = posts.objects; }); } function PostDetailController($scope, $routeParams, Post) { var postQuery = Post.get({ postId: $routeParams.postId }, function(post) { $scope.post = post; }); } app.js 'use strict'; angular.module('AngularFlask', ['angularFlaskServices', 'dx']) .config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) { $routeProvider .when('/', { templateUrl: 'static/partials/landing.html', controller: IndexController }) .when('/about', { templateUrl: 'static/partials/about.html', controller: AboutController }) .when('/post', { templateUrl: 'static/partials/post-list.html', controller: PostListController }) .when('/post/:postId', { templateUrl: '/static/partials/post-detail.html', controller: PostDetailController }) /* Create a "/blog" route that takes the user to the same place as "/post" */ .when('/blog', { templateUrl: 'static/partials/post-list.html', controller: PostListController }) .otherwise({ redirectTo: '/' }) ; $locationProvider.html5Mode(true); }]) ; With this, when I navigate to localhost:5000, this error is reported https://docs.angularjs.org/error/$injector/modulerr?p0=AngularFlask&p1=%5B$injector:unpr%5D%20http:%2F%2Ferrors.angularjs.org%2F1.5.7%2F$injector%2Funpr%3Fp0%3D%2524routeProvider%0AO%2F%3C#https:%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.5.7%2Fangular.min.js:6:412%0Adb%2Fn.$injector%3C#https:%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.5.7%2Fangular.min.js:43:84%0Ad#https:%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.5.7%2Fangular.min.js:40:344%0Ae#https:%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.5.7%2Fangular.min.js:41:78%0Ah%2F%3C.invoke#https:%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.5.7%2Fangular.min.js:41:163%0Ad#https:%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.5.7%2Fangular.min.js:39:313%0Ag%2F%3C#https:%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.5.7%2Fangular.min.js:39:445%0Ar#https:%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.5.7%2Fangular.min.js:7:353%0Ag#https:%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.5.7%2Fangular.min.js:39:222%0Adb#https:%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.5.7%2Fangular.min.js:43:246%0ABc%2Fc#https:%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.5.7%2Fangular.min.js:20:359%0ABc#https:%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.5.7%2Fangular.min.js:21:163%0Age#https:%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.5.7%2Fangular.min.js:19:484%0A#https:%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.5.7%2Fangular.min.js:315:135%0An.Callbacks%2Fi#https:%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fjquery%2F1.12.4%2Fjquery.min.js:2:27444%0An.Callbacks%2Fj.fireWith#https:%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fjquery%2F1.12.4%2Fjquery.min.js:2:28213%0A.ready#https:%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fjquery%2F1.12.4%2Fjquery.min.js:2:30004%0AK#https:%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fjquery%2F1.12.4%2Fjquery.min.js:2:30366%0AO%2F%3C()%20angular.min.js:6g%2F%3C()%20angular.min.js:40r()%20angular.min.js:7g()%20angular.min.js:39db()%20angular.min.js:43Bc%2Fc()%20angular.min.js:20Bc()%20angular.min.js:21ge()%20angular.min.js:19%3Canonymous%3E%20angular.min.js:315n.Callbacks%2Fi()%20jquery.min.js:2n.Callbacks%2Fj.fireWith()%20jquery.min.js:2.ready()%20jquery.min.js:2K()%20jquery.min.js:21%20angular.min.js:6:412 It may be worth mentioning that if I use AngularJS 1.0.7 (included with Angular-Flask) the issue is cleared up until I add my html dev tag <div dx-button="{ text: 'Generate random value' }"></div> then these are the errors: Error: e.$$postDigest is not a function Error: t.$root is undefined Error: a.$watch is not a function Error: c.$watch is not a function Error: a.$watch is not a function Error: t.dxTemplateModel is undefined So this tells me that DevExpress is missing some functions in AngularJS 1.0.7; However, when using AngularJS 1.2.X Angular-Flask breaks. Is there anyway to get these two to play well together?
DevExtreme supports AngularJS 1.2 - 1.4. Your try to use too old version of AngularJS. Scripts in this repo were updated 3 years ago. But you can easily use another angularjs version. Your flask layout can look like below: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{{ title }} - My Flask Application</title> <link rel="stylesheet" type="text/css" href="/static/content/site.css" /> <link rel="stylesheet" type="text/css" href="http://cdn3.devexpress.com/jslib/16.1.5/css/dx.common.css" /> <link rel="stylesheet" type="text/css" href="http://cdn3.devexpress.com/jslib/16.1.5/css/dx.light.css" /> </head> <body class="dx-theme-generic-typography" ng-app="myApp"> <div ng-controller="defaultCtrl"> <div dx-button="buttonOptions"></div> </div> <script src="https://code.jquery.com/jquery-2.1.3.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.16/angular.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.16/angular-sanitize.js"></script> <script src="http://cdn3.devexpress.com/jslib/16.1.5/js/dx.all.js"></script> <script src="/static/scripts/application.js"></script> </body> </html> And the /static/scripts/application.js file: var myApp = angular.module("myApp", ["dx"]); myApp.controller("defaultCtrl", function($scope) { $scope.buttonOptions = { text: "My button", onClick: function(){ alert("Hi!"); } }; });
This XML file does not appear to have any style information associated with it. The document tree is shown below.2
When using the following code in django template: <!DOCTYPE html> <html lang="en"> <head> <link href="http://52.11.183.14/static/wiki/bootstrap/css/wiki-bootstrap.css" type="text/css" rel="stylesheet"/> <link href="http://52.11.183.14/static/wiki/bootstrap/css/simple-sidebar.css" type="text/css" rel="stylesheet"/> <title> Profile - Technology βιβλιοθήκη </title> </head> <body> <div class="container"> {% for p in profiles %} {{p}} {% endfor %} </div> </body> </html> I receive the following error: This XML file does not appear to have any style information associated with it. The document tree is shown below. Why? And what can I do to fix it? Solved: by change HttpResponse on render_to_response my_context={'profiles': profiles} c = RequestContext(request,{'profiles': profiles}) return render_to_response('wiki/profile.html', my_context, context_instance=RequestContext(request)) #return HttpResponse(t.render(c), content_type="application/xhtml+xml")
You must replace your content html tag with this. <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html dir="rtl" xmlns="http://www.w3.org/1999/xhtml">
Markdown with Syntax highlighting in Flask
I am trying to implement the same stack overflow text-area with syntax highlighting in Python and have come this far but i am not able to get it working. app.py from flask import Flask, render_template, request import preview app = Flask(__name__) #app.route('/',methods=['GET','POST']) def index(): if request.method == 'POST': markdown_content = request.args.get['wdd-input'] post_preview = preview.markdown(markdown_content['data']) return render_template('test.html', result=post_preview) if request.method == 'GET': return render_template('demo.html') if __name__ == '__main__': app.run() preview is something which does syntax highlighting and its based upon Pygments. test.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>PageDown Demo Page</title> <link rel="stylesheet" type="text/css" href="/static/css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" href="/static/css/highlighting.css"> <link rel="stylesheet" type="text/css" href="/static/css/demo.css" /> <script type="text/javascript" src="/static/js/jquery-1.9.1.min.js"></script> <script type="text/javascript" src="/static/js/bootstrap.min.js"></script> <script type="text/javascript" src="/static/js/hycus-textarea.js"></script> <script type="text/javascript" src="/static/js/Markdown.Editor.js"></script> <script type="text/javascript"> (function (m) { m(document).ready(function () { m('textarea.wmd-input').TextAreaResizer(); }); })(jQuery); </script> </head> <body> <div class="container"> <div id="pagedwon"> <div id="tabnav"> <ul class="nav nav-tabs" id="markdown_tab" style="padding: 0 10px; margin-bottom: 10px;"> <li class="active">Edit</li> <li>Preview</li> </ul> </div> <div class="tab-content"> <div class="tab-pane active" id="edit"> <div class="wmd-panel"> <div id="wmd-button-bar"></div> <textarea class="wmd-input" id="wmd-input" rows="10" name="text-input"> This is the *pagedown* editor. ------------------------------ **Note**: Just plain **Markdown**, except that the input is sanitized: **HTML** is not allowed. </textarea> </div> <script type="text/javascript"> (function () { var pagedown_editor = new Markdown.Editor(); pagedown_editor.run(); })(); </script> <script type="text/javascript"> (function (m) { m("#markdown_tab a").click(function () { if (m(this).html() == "Preview"){ var markdown_content = m("#wmd-input").val(); if (!markdown_content) { m("div#markdownpreview").html("Empty Markdown Content."); } else { content_to_preview = { "data": markdown_content } m.post("/", content_to_preview) .success( function(preview_content){ if (preview_content == 'None'){ m("div#markdownpreview").html("No content received."); } else { m("div#markdownpreview").html(preview_content); } }) .error( function () { m("div#markdownpreview").html("Sorry, error occurred. Please retry."); }); } } }); })(jQuery); </script> </div> <div class="tab-pane markdown-body" id="markdownpreview"> Loding preview content ... </div> </div> </div> </div> </body> </html> This is log from the console: 127.0.0.1 - - [26/Jun/2014 20:25:01] "POST / HTTP/1.1" 500 - How to get it working, please help. I am new to Flask.
First, request.args is for query string parameters, but you are sending over data via POST. You should be using request.form instead. Second, MultiDict.get is a function, and does not support the __getitem__ protocol (which is the cause of your 500 error). Third, as #Doobeh points out in the comments, you are sending the data over under the key data, but you are trying to access it via the key "wdd-input" - this will result in a BadRequest error. Finally, the value extracted from request.form will be a string (which does not support strings as __getitem__ values) - and you don't need it anyway, as you already have the entire string. A re-worked version of your POST portion: if request.method == 'POST': markdown_content = request.form.get('data', 'No content yet ...') post_preview = preview.markdown(markdown_content) return render_template('test.html', result=post_preview)