How to easily create a single-page Web Application? - python

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..

Related

How to render a CheckboxGroup (or any other element) in a custom way?

Bokeh renders the checkboxes like this
<div class="bk-bs-checkbox">
<label>
<input type="checkbox" value="0">
Label text
</label>
</div>
But I would like to select the label depending on the input state :focus, :disabled, :checked, ...
Since there is no CSS parent selector, what I could do to render the checkbox in a custom way? I would like to avoid JavaScript. If the checkbox is rendered as the following code it would be easier to customize:
<div class="bk-bs-checkbox">
<input type="checkbox" value="0">
<label>
Label text
</label>
</div>
And I could this CSS code to select the label depending the checkbox state:
.bk-bs-checkbox input[type="checkbox"]:disabled + label::after {
background-color: red,
}
This is just an example to show one case of use.
Is there an easy way to achieve this? Actually I am looking for some mechanism in bokeh to inherit the template that renders that object in order to change it with my custom template.
Well, finally I have found a workaround that is not very clean, but it works. Basically I have hidden the original element and I have created my own customised control. I have used JavaScript as #Gerard suggested.
First I need to wait until Bokeh Server is loaded. All the elements must be already rendered. So I have applied some workaround from this answer
Then I have hidden the original element generated by bokeh using the python attribute css_classes and the CSS tyle display: none;
I have created the element by JavaScript (actually I have enabled jQuery). This can be done with bokeh templates as well. In my case I found it more convenient like this. Then I have added the element before the original one.
var new_cb = $('<div>', {
class: 'abc-checkbox abc-checkbox-primary',
});
new_cb.append(
$('<input>', {
id: 'id_new_cb',
type: 'checkbox'
})
);
new_cb.append(
$('<label>', {
for: 'id_new_cb',
text: 'Custom element'
})
);
$('.original_cb').before(new_cb);
Finally I have added an event to trigger the event on the original hidden element:
$('#id_new_cb').change(function() {
if(this.checked) {
$('.original_cb input').click();
} else {
$('.original_cb input').click();
}
});
Something similar can be done with the rest of the elements. This is useful if you just want to change a couple of elements. If not this will become kind of cumbersome.

Accessing Calculated Value in Text Area Spotfire

I am trying to access a calculated value sitting in a text area with the API. My python skills are not that good, but I believe I am pretty close, and that this will probably be an easy question for someone more experienced. I have looked around a good bit and haven't found a solution.
So far this is what I have:
from Spotfire.Dxp.Application.Visuals import Miniatures
val1 = Miniatures.CalculatedValueMiniatureVisualizationDetails.Value
print val1
This gives me the following: 
property# Value on CalculatedValueMiniatureVisualizationDetails>.
The real question is how do I extract the value from this property?
Thanks,
Jamey
I ended up ditching this way and solved this problem by using jQuery:
I ended up figuring this one out. Here is the html:
<body >
<div id = wrapper>
<div id = thisyear><SpotfireControl id="d644de4c97c440fbb78c561f190e5a47" /> </div>
<div id = lastyear ><SpotfireControl id="f98415c74eb34cedbab057f763788bc6" /></div>
</div>
</body>
And the jQuery that gets this done:
setInterval(function() {
var thisyearval = parseInt($("#thisyear").text(),10)
var lastyearval = parseInt($("#lastyear").text(),10)
if (thisyearval > lastyearval){
$("#wrapper").css("background-color", "#009900")
} else{$("#wrapper").css("background-color", "#FF0000")}
}, 500);
It turns out that spotfire doesnt support the change function in jQuery, so I used setInterval() to essentially call the function over and over.
Hopefully this will help someone else out too.

Get value from textbox input without ng-repeat

I'm new in AngularJS.
I want to get value from input text without ng-repeat where the value is from Python.
Value from Python:
{{user.id}}
My text input:
<form ng-submit="SendHttpPostData()">
<p><input type="text" ng-model="user" value="{{user.id}}"></p>
<input type="submit" value="Submit" />
</form>
My problem is:
The value of user.id doesn't display in input text.
I get undefined result when click Submit button.
Angular, by default, will not read the value attribute of an input when initializing data bindings. However, you can write a directive which will do this for you:
app.directive('value', function () {
return {
restrict: 'A',
require: '?ngModel',
link: function postLink(scope, element, attrs, ngModel) {
if (!ngModel)
return;
var val = attrs.value || element.val() || element.text();
ngModel.$setViewValue(val);
ngModel.$render();
}
};
});
This will ensure that whenever the value attribute appears together with ng-model, it will be used to initialize the bindings. See this Plunker for a demo.
However, please note that this is not the recommended way of passing data to Angular from the backend. Generally, it is best to write a JSON API endpoint and load the data into the client-side using $http or $resource.

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).

HTML drop-down box with Google App Engine

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.

Categories

Resources