HTML drop-down box with Google App Engine - python

I am creating a Google App Engine web application written in Python, and I would like to create a drop down box that displays different values corresponding to pages of a book that a user could choose from. I would like the action of the drop down box to be to direct the user to the page that corresponds to this link:
<a href='/viewpage/{{bookpage.key}}'>{{ bookpage.page }} </a>
The "bookpage" entity is passed to the html
Thank you!
David

Use a Jump Menu. Here is a pretty straight forward implementation.
Basically you'll just add a bit of JavaScript, and instead of writing an a tag, you'll write an option:
<option value='/viewpage/{{bookpage.key}}'>{{ bookpage.page }} </option>

What about <option value='/viewpage/{{bookpage.key.id}}'>{{bookpage.page}}</option>?
I hope it's not a dumb answer.

I'm not familiar with the google-app-engine but, the following javascript seems to do what you want. The python could generate the array variables on the server side, and then everything else would work properly.
I included the hardcoded arrays so you can see what is going on, but you can replace the arrays with the python code(assuming bookpage is some kind of dictionary):
i = 0
for bp in bookpage.keys():
print("mysites["+str(i)+"] = "+ bookpage[bp])+";"
print("sitenames["+str(i)+"] = "+sitenames[bp])+";"
i+=1
<html>
<body>
<script type="text/javascript">
var mysites= new Array();
mysites[0] = "http://www.google.com"; //Generate this line with python
mysites[1] = "http://www.bing.com"; //Generate this line with python
mysites[2] = "http://www.yahoo.com"; //Generate this line with python
var sitenames = new Array();
sitenames[0] = "Google"; //Generate this line with python
sitenames[1] = "Bing"; //Generate this line with python
sitenames[2] = "Yahoo"; //Generate this line with python
function changeLink(){
var index = document.getElementById("theselect").selectedIndex
document.getElementById("thelink").innerHTML=index;
var newlink = mysites[index];
var newstring = sitenames[index];
document.getElementById("thelink").href=newlink;
document.getElementById("thelink").innerHTML=sitenames[index];
}
</script>
<select id="theselect" onclick="changeLink()">
<option>Google</option>
<option>Bing</option>
<option>Yahoo</option>
</select>
<br />
<a id="thelink" href="http://www.google.com" > Google </a>
</body>
</html>
Clicking on the option box calls the changeLink() function, which then changes the link and the inner html of the tag.

Related

How to easily create a single-page Web Application?

What is the easiest way to make a one-page web application, where there will be two input text, in which the variables a, b are entered and one button for accessing the python script to display the image at the received URL
def get_pic(a,b):
*magic*
return *pic url*
I've tried Django, but since I'm a beginner, I didn't understand how to assign a python function call to a button. Maybe there are ways as simple as possible and without unnecessary troubles, I need an elementary interface as in the attached picture
P.S. Before that, I was engaged in creating desktop applications in PyQt and it was much easier there, you just drag-n-drop the necessary buttons, text blocks in the editor and then bind functions to them in Python, but with web applications, as I understand it, it will not work
If you need simple example how to just pickup values from 2 inputs, and send them down the wire here you go..
var btn = document.querySelector('button') ;
var in1 = document.querySelector('#nr1') ;
var in2 = document.querySelector('#nr2') ;
var img = document.querySelector('img') ;
// event on button click
btn.addEventListener( 'click', function() {
// bails. ..todo, security ?..?
if( !parseInt(in1.value) || !parseInt(in2.value) ) return;
// take values from input1 and input2 and replace attribute, browser will do ajax for you and render it
img.setAttribute( 'src', "https://placehold.it/" + in1.value + "x" + in2.value )
});
.img, .frm{
float: left;
width: 49%;
padding-left: 1%
}
<div class="img">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==" />
</div>
<div class="frm">
<input id="nr1"> <p> </p>
<input id="nr2"> <p> </p>
<button>Render</button>
</div>
This example will pick integers in two fields and send them to free backend service that will return image.
Your have to replace https://placehold.it/ with your backend service url, and send args like url parameters as I did for example. Your service needs to return url of the image or mine type image/png etc.., it's scripts responsibility to handle security, edge cases, fallback image, etc..

How to execute only onclick python function for each link in html?

I want to execute onclick event "saveChoice" when an image is clicked on a html page. There are two images, left and right, with the same onclick event only they have one other parameter, the left one passes "Left" and the right one passes "Right".
Now when I click on one of them, both get executed. I want to execute only the one which is clicked on.
I looked for a lot of solutions, html related, flask related and python related. I didn't find the solution. I tried to make a script in the html file but then i have the same problem. I tried to place the script on other places but it didn't solve the problem.
in the html file
<body>
<a href="{{ url_for('question') if text < 3 else url_for('endsurvey')}}", onclick= "{{ saveChoice("Left", num1, num2, text) }}">
<img src="{{url_for('static', filename='kaart{}.png'.format(num1))}}", border="0"> <!-- het moet in de map static staan! -->
</a>
<a href="{{ url_for('question') if text < 3 else url_for('endsurvey')}}", onclick= "{{ saveChoice("Right", num1, num2, text) }}">
<img src="{{url_for('static', filename='kaart{}.png'.format(num2))}}", border="0">
</a>
...
</body>
the python function in app.py
#app.context_processor
def utility_processor():
def saveChoice(side, num1, num2, tekst):
mycol.insert_one({"date": datetime.datetime.now(), "user": "2",
"photoleft": num1, "photoright": num2, "choice": side,
"question": tekst})
return dict(saveChoice=saveChoice)
The function should save one click, the info on the right or left image. The info is saved correctly but for left and right on one click.
The answer is probadly that it is not possible. You cannot use python functions directly in html therefore you need to use javascript for example.
I solved this with a copy of function question and endsurvey. I made one for the left side and for the right side and with url_for I go to that function. In these function you can use the saveChoice function the right way.
Instead of writing an onclick within the tag with a python function maybe it is better to attach an eventand use some javascript. Assign a class to each img tag, ie: class="leftSide" and class="rightSide". And add the num1, num2 and num3 as data-xxx tags to the wrappping div (you can put everything in the img tag but i think it's cleaner with a wrapper).
Something like this:
<body>
<div data-num1="{{num1}}" data-num2="{{num2}}" data-num3="{{num3}}">
<img class="leftSide" src=" {{url_for('static', filename='kaart{}.png'.format(num1))}}", border="0"> <!-- het moet in de map static staan! -->
</div>
<div data-num1="{{num1}}" data-num2="{{num2}}" data-num3="{{num3}}">
<img class="rightSide" src=" {{url_for('static', filename='kaart{}.png'.format(num1))}}", border="0"> <!-- het moet in de map static staan! -->
</div>
...
</body>
Then write some lines of javascript code like the following:
$(document).on("click", ".leftSide", function (e) {
let side = $(this).closest("div"); // Finds wrapping div
const num1 = side.attr("data-num1");
const num2 = side.attr("data-num2");
const num3 = side.attr("data-num3");
//Now you have your side and your variables. You can do as you like. Maybe call same AJAX on a modal with the insert and a message with ok or ko.
const url = /route/to/funct/side/num1/num2/num3
$('.modal-content').load(url, function () {
$('#myModal').modal({
show: true,
closable: false,
transition: 'fade up',
});
});
//where url is the route to your insert function
});
FInally you would have to write an event for the right side but you can recycle the insert fuction.
Hope this helps

Django and AngularJS: how to display Angular $http errors that come from Django debug error messages

I have a Django view that is called from Angular with a $http.post
//LOADFILE ===================
this.loadfile = function (clickedItem) {
$http.post('/display/' , { "filename": clickedItem.fileName} )
.success(function(data) {
$scope.fileView.text = data;
$scope.fileView.title = clickedItem.title
}).error(function(data) {$scope.displayError=data});
};
If Django throws an error, data will be a full Django error page (full html page).
How do I display that error page (a complete html page) under Angular? (Some discussion of modals here : AngularJS, show popups - The most elegant way?, but nothing about a complete html page...)
I thought I could do this with a frame element and dom:
$window.frames['myErrorFrame'].document.innerHTML = $scope.displayError;
But that doesn't look very Angularish... And this almost does it, but I still have the problem of writing directly to the dom since the src is a string: insert an iframe into page dynamically in AngularJS
Is there a better way to display a full html page string in Angular?
Here is a possible solution. It works, but there are degrees of working, and this is a bit hacky -- the degree zero of working.
The error function (from Write elements into a child iframe using Javascript or jQuery):
update_error = function (message) {
var ifrm = document.getElementById('errorIFrame');
ifrm = (ifrm.contentWindow) ? ifrm.contentWindow : (ifrm.contentDocument.document) ? ifrm.contentDocument.document : ifrm.contentDocument;
ifrm.document.open();
ifrm.document.write(message);
ifrm.document.close();
};
And the html:
<div ng-show="errorMessage != ''">
<button class="btn btn-info btn-xs" ng-click="errorMessage=''">Close</button><br />
<iframe width="100%" id="errorIFrame"> </iframe>
</div>
The error callback:
.error(function(data) {
update_error(data);
$scope.errorMessage="error"}
Note the switching of the errorMessage flag, which I seem to have to do because update_error is outside the controller (there must be a simple fix for that, but I have other fish to fry). This works, but I imagine it isn't orthodox. There is probably a better way with $sce (will fry that one later).

Python script for SVG to PNG conversion with Extjs

I'm trying to save a chart by converting SVG to PNG with a Python script.
So I start storing the svg data in a variable with :
var svgdata = Ext.draw.engine.SvgExporter.generate(chart.surface);
When I do alert(svgdata), I can see that this output is correct.
But when I send it to the server like this :
Ext.draw.engine.ImageExporter.defaultUrl = "data/svg_to_png.py?svgdata="+svgdata;
The svgdata that has been sent looks like this :
<?xml version=
I'm new to extjs, please help me on this one. What is the right way to send svg data to my python script and render a png image ?
This is my python script :
import cairo
import cgi
import rsvg
print "Content-type: image/png\n\n"
arguments = cgi.FieldStorage()
img = cairo.ImageSurface(cairo.FORMAT_ARGB32, 640,480)
ctx = cairo.Context(img)
handler= rsvg.Handle(None, str(arguments["svgdata"]))
handler.render_cairo(ctx)
img.write_to_png("svg.png")
HELP ME PLEASE!
<div style="display:none;">
<iframe id="file_download_iframe" src="blank.html"></iframe>
</div>
You will need a blank html page on your server for this to work properly in all browsers. Basically the blank.html page is an empty page to satisfy that the ifram always has a page in it.
Then you need a basic form hidden somewhere too:
<div style="display:none;">
<form
id = "file_download_iframe_form"
name = "file_download_iframe_form"
target = "file_download_iframe"
method = "post"
action = "data/svg_to_png.py"
>
<input type="hidden" id="svgdata" name="svgdata"/>
</form>
</div>
Then have a javascript function like this:
function getImage(svgdata){
var form = document.getElementById("file_download_iframe_form");
document.getElementById("svgdata").value = svgdata;
form.submit();
};

SL4A _R6 / Python4android_R4 webViewShow NullPointerException on simple example code

I'm trying to get a HTML Gui on my simple SL4A Python app. the only thing I need to perform is ask the user for 1 input string at the start of my app.
For debugging purposes I started of simple. Unfortunately even this won't function.
Any idea's what's wrong here? (I've tried several pieces of code like this and all have the same issue)
Python code:
import android
loop = True
droid = android.Android()
droid.webViewShow('/sdcard/sl4a/scripts/screen.html')
while loop:
res = droid.waitForEvent('data')
if res:
print str(res)
HTML code
<html>
<head>
<script>
var droid = new Android();
var fiets = function() {
droid.postEvent("data", document.getElementById("gsm").value);
}
</script>
</head>
<body onload:"fiets()">
<form onsubmit="fiets(); return false;">
<label for="say">What would you like to say?</label>
<input type="text" id="gsm" value="99999999" />
<input type="submit" value="Store" />
</form>
</body>
</html>
the error message is repeatedly (the number 3114 is incremental):
java.lang.NullPointerException
Result(id=3114, result=None, error=u'java.lang.NullPointerException')
update:
http://www.mithril.com.au/android/doc/EventFacade.html
As we go I read waitForEvent is deprecated in r4. I should use eventWaitFor instead.
This takes the error away but doesn't make the example function. Python script prints nothing.
update2:
droid.postEvent should become droid.eventPost
droid.waitForEvent('data') should become droid.waitForEvent('data')
In javascript and python.
Problem Solved

Categories

Resources