Get value from textbox input without ng-repeat - python

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.

Related

Python - How can I pass variable in Flask when clicked on a button

I am working on a Flask project that has two pages (firstpage, secondpage). The first page has two buttons. When a user clicks on one of them, it should send a variable (variable name is value) with text to the second page. The second page should display message depending on what button the user clicked in the first page. But my program is always printing the second value even when the first button is clicked. If I declared the variable global, can I use it in the secondpage?
My html code looks kind of like this:
<form action="/firstpage" method="post">
<div><h2 class="header">Click one button</h2></div>
<div class="pickitem">
<button class="btn one" name="btn-one" type="submit">ONE</button><br>
<button class="btn two" name="btn-two" type="submit">TWO</button></div>
</form>
and my Python code looks like this:
var value=""
#app.route("/firstpage", methods=["GET", "POST"])
def mymethod():
value = ""
if request.method == "POST":
if request.form.get("btn-one"):
value = "uno"
else:
request.form.get("btn-two"):
value = "dos"
print (value)
return render_template("secondpage.html")
else:
return render_template("firstpage.html")
You can use an hidden input field for this.
HTML:
<form action="/firstpage" method="post">
<div><h2 class="header">Click one button</h2></div>
<input type="hidden" name="btn-pressed" class="hidden-field">
<div class="pickitem">
<button class="btn one" name="btn-one" type="submit">ONE</button><br>
<button class="btn two" name="btn-two" type="submit">TWO</button></div>
</form>
Change its value depending upon the button clicked.
JavaScript:
document.addEventListener('click', (e) => {
// do not process if the clicked element is not a form button
if ( ! e.target.matches('form .btn') ) return;
// prevent form submission
e.preventDefault();
// change hidden field value
let field = document.querySelector('.hidden-field');
field.value = e.target.getAttribute('name');
// submit the form
e.target.closest('form').submit();
});
Then in Python, you can get the value through the name btn-pressed
Python:
request.form.get("btn-pressed") # to get the hidden field value
A few syntax errors you might need to fix.
It seems like you are mixing up different programming languages. In the first line, you entered var value="". Try to remove the var.
Make sure your indentation is correct! Indent the block from def mymethod(): to the bottom.
Remove the colon from the line request.form.get("btn-two"):. Did you mean if request.form.get("btn-two"): instead?
Apart from that, the reason value ends up not being either "uno" or "dos" is because of the if-statements in the code. To fix the issue, change them to:
if list(request.form)[0] == 'btn-one':
Why does this work? The request.form looks like this:
ImmutableMultiDict(['btn-one', ''])
Transforming this into a list (i.e., getting its keys, which is either btn-one or btn-two) and taking the first item will tell us the button pressed.
Hope this helps :)

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

Input text field value behavior after Get request

I have this form
<form class="form-inline" type="get" action=".">
<input id="excel_input" class="form-control" type="text" name="excel_input" value="0">
<input class="btn" type="submit" name="excelbutton" value="excelbuttonclicked"
onclick='document.getElementById("excel_input").value = "1";'><i class="ion ion-search"></i></input>
</form>
I want to get the value "1" when the excelbutton clicked in the Get request in order to export an excel file. I want to use the Get request because in this point I have a ready query set , the query set user sees on the screen.
I use the commands
request.GET.get('excel_input', None)
if excel_string not in ['0', None]:
testxlsxwriter(d_list)
to get the value of the input field and export the excel file. The problem is that I get the value "1" from the input field on button click , but then I always get the value "1" on get requests( refresh , next page etc.
I see the value "0" on screen on refresh but I get the value "1" on my view
I also tried javascript with no luck
window.onload = function(){
document.getElementById("excel_input").value = "0";
}
Can someone help me please to understand how get request works with this input element?
Thanks a lot
Kostas

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.

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

Categories

Resources