How to utilize Bootstrap Ti Ta Toggle Checkbox with Flask - python

Python/Flask/Bootstrap noob here. I'm trying to build a web-app to control a speaker selector. I'm using bootstrap and Ti-Ta Toggles to beautify the app a bit, but basically it consists of 4-5 checkbox/toggles. Here's what my HTML looks like right now:
<form name="input" action="/" method="post">
<div class="row">
<div class="col-md-6">
<table class="table">
<tbody>
<tr>
<td>Living Room</td>
<td>
<div class="checkbox checkbox-slider-lg checkbox-slider--a checkbox-slider-info">
<label>
<input name="spkrs-00" type="checkbox" onclick="this.form.submit()" checked><span></span>
</label>
</div>
</td>
</tr>
<tr>
<td>Kitchen</td>
<td>
<div class="checkbox checkbox-slider-lg checkbox-slider--a checkbox-slider-info">
<label>
<input name="spkrs-01" type="checkbox" onclick="this.form.submit()"><span></span>
</label>
</div>
</td>
</tr>
<tr>
<td>Dining Room</td>
<td>
<div class="checkbox checkbox-slider-lg checkbox-slider--a checkbox-slider-info">
<label>
<input name="spkrs-02" type="checkbox" onclick="this.form.submit()"><span></span>
</label>
</div>
</td>
</tr>
<tr>
<td>Unconnected</td>
<td>
<div class="checkbox checkbox-slider-lg checkbox-slider--a checkbox-slider-info">
<label>
<input name="spkrs-03" type="checkbox" onclick="this.form.submit()" disabled><span></span>
</label>
</div>
</td>
</tr>
<tr>
<td>Protection</td>
<td>
<div class="checkbox checkbox-slider-lg checkbox-slider--a checkbox-slider-warning">
<label>
<input name="protection" type="checkbox" onclick="this.form.submit()"><span></span>
</label>
</div>
</td>
</tr>
</tbody>
</table>
</div>
So, what I'm trying to figure out is how to handle the POST data from the checkbox inputs in my Python/Flask app. I was trying to do a simple test which looks like the following:
from flask import Flask, request, render_template
import time
app = Flask(__name__)
#app.route('/', methods=['POST','GET'])
def change():
if request.method == 'POST':
spkr_00_state = request.args['spkrs-00']
spkr_01_state = request.args['spkrs-01']
spkr_02_state = request.args['spkrs-02']
protection_state = request.args['protection']
speaker_states = [spkrs_00_state, spkrs_01_state, spkrs_02_state, protection_state]
return render_template('index.html', speaker_states=speakers_states)
else:
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=80)
However, I get Bad Request messages, etc. So, I'm a bit lost on how this should work. Should I create separate forms for each toggle? Should I put "try" if statements around the request.args?

OK, just in case someone else stumbles upon this post later and is curious, I was able to figure out what my issues were. Mainly, my issue was that by default checkboxes will only POST when checked. Therefore if you do not have a particular box checked (in this case it was the toggle switches I was using in bootstrap Ti-Ta Toggles) then there will be no POST information when checked.
In Flask/Python, when you try to request the post data for a particular checkbox/toggle, and it doesn't exist, then you will get a bad request error. For example, the following will likely generate an error if the checkbox spkrs_02 after POST.
spkr_state[1] = request.form['spkrs_02']
The way to get around this is to use a hidden input tag after the input tag for the checkbox. This will return a value in post, even if the input tag isn't checked/toggled.
For example it would look like something like this (in your HTML file) if you were setting up a checkbox(toggle) using :
<input name="spkrs_02" type="checkbox" onclick="this.form.submit()"><span>Kitchen</span>
<input name="spkrs_02" type="hidden" value="off">
That last line will, as mentioned above, provide some feedback in post, when the "box" is not checked.
Also a side note that I used onclick="this.form.submit()" which was helpful in tacking action on a toggle/checkbox immediately when it is clicked. I'll be honest that I'm not sure if that is the proper way to handle this, but it worked well for me.
Anyway, good luck!

Related

Getting multiple html fields with same name using getlist with flask in python

I have a form with dynamically added rows that have the same name. I try to use getlist but I only get the first value.
Here is my HTML form code:
<html>
<div>
<form method=POST>
</div>
<table id="linkTable">
<tbody><tr class="tr_clone" id="addrow">
<td>First: </td>
<td><input class="from-field" id="from" type="text" name="first"></td>
<td>Last: </td>
<td><input class="to-field" id="to" type="text" name="last"></td>
<td>Email: </td>
<td><input class="port-field" id="ports" type="text" name="email"></td>
</tr>
</tbody></table>
<script>
$("#addbtn").click(function(){
$("#addrow").clone().find("input:text").val("").end().prependTo("#linkTable");
})
</script>
</form>
</html>
Here is my python code:
from flask import Flask, request, render_template
for arg in request.form:
print arg, request.form.getlist(arg)
Can anyone explain that even if I use getlist, I only get the first value?
Thanks in advance
It's convenient to use zip() every time you want to parse same name attribute in html. Have a look at this:
#app.route('/creation', methods=['GET', 'POST'])
def create():
try:
if request.method == 'POST':
for first, last, email in zip(request.form.getlist('first'),
request.form.getlist('last'),
request.form.getlist('email')):
print(first, last, email)
else:
return render_template('create.html')
except Exception as e:
print(str(e))
After looking for a long time, was able to answer my own question by looking on the web.
I had the following:
<html>
<!-- note how the form has been moved out of the div so that the navigator does not close the div -->
<form method=POST>
<table id="linkTable">
<tbody><tr class="tr_clone" id="addrow">
<td>First: </td>
<td><input class="from-field" id="from" type="text" name="first"></td>
<td>Last: </td>
<td><input class="to-field" id="to" type="text" name="last"></td>
<td>Email: </td>
<td><input class="port-field" id="ports" type="text" name="email"></td>
</tr>
</tbody></table>
<script>
$("#addbtn").click(function(){
$("#addrow").clone().find("input:text").val("").end().prependTo("#linkTable");
})
</script>
</form>
</html>
It turns out that closing a div will close a form tag so rows were being dynamically added outside the form. By moving the form directive outside of the div, I started getting multiple values when the form was submitted
I also eventually found a more detailed answer at Form Issue (closing itself early in table)

I am using Selenuim on python. I need to update value for two Webelement but am able to only update for one

Here is the page source code snippet.
<tr>
<th>Model Name<span class="c-c60000 txtNormal">*</span></th>
<td><table cellpadding="0" cellspacing="0" border="0"><tr><td><input tabindex="-1" readonly="readonly" value="" disabled="disabled" type="text" class="inputText" name="modelName" id="modelName" style="width:150px;" style = "ime-mode:disabled"/> </td><td><table class="btnTypeA"><tr><td>
Search
</td></tr></table></td></tr></table></td>
<th>Customer Code<span class="c-c60000 txtNormal">*</span></th>
<td><input readonly="readonly" disabled="disabled" type="text" value="" class="inputText" name="cc" id="cc" style="width:150px;" style = "ime-mode:disabled"/></td>
</tr>
<tr>
<th>Model Alias</th>
<td><input readonly="readonly" disabled="disabled" type="text" value="" class="inputText" name="modelAlias" id="modelAlias" style="width:150px;" style = "ime-mode:disabled"/></td>
<th>Scenario Type</th>
<td>
<select style="width:155px;" name="testOrUse" id="testOrUse" onchange="javascript:loadSubField('');">
<!-- Admin, Lead Model Developer -->
<option value="T">Testing Scenario</option>
</select>
</td>
</tr>
My code is
element4 = browser.find_element_by_id("modelAlias")
browser.execute_script("arguments[0].value = 'GT-I9192';", element4)
element2 = browser.find_element_by_id("modelName")
browser.execute_script("arguments[0].value = 'GT-I9192';", element2)
First 2 lines seem to work and value gets updated for "modelAlias"
but last two lines are not working correctly.
Also my code is not throwing any error which is making things difficult.
I think span here is the reason of different behavior.
Try this I dont know python too much but you to remove the attribute as it is disabled and then try to pass values, this is javacode. Try to convert it into Python
JavascriptExecutor jse =(JavascriptExecutor)driver;
jse.executeScript("arguments[0].removeAttribute('disabled','disabled')", element4);
jse.executeScript("arguments[0].value = 'GT-I9192';", element4);
jse.executeScript("arguments[0].removeAttribute('disabled','disabled')", element5);
jse.executeScript("arguments[0].value = 'GT-I9192';", element5);

sqlalchemy.exc.DataError while executing the update query in Postgresql

I am trying to write a simple flask application where I am using a Postgresql as database. I am trying to update the table row on button click but it is giving me following error
DataError: (psycopg2.DataError) invalid input syntax for integer: "125/" LINE 1: ...ATE tasks SET taskname='IamUpdated' WHERE tasks.uid = '125/' ^ [SQL: 'UPDATE tasks SET taskname=%(taskname)s WHERE tasks.uid = %(uid_1)s'] [parameters: {'taskname': 'IamUpdated', 'uid_1': u'125/'}]
I am not sure if it is adding "/" at the end as a glitch or it is supposed to be like that? or That is what causing an error.
Please Help.
Following is my Flask Python code
edituser = request.form.getlist('editId')
if edituser:
for e in edituser:
User.query.filter_by(uid=e).update(dict(taskname="IamUpdated"))
db.session.commit()
return render_template("index.html",User=User.query.all())
Following is my HTML code
<form action="" method="POST">
<div ng-controller="myctrl" >
<table>
<caption> Todo List</caption>
<thead>
<tr>
<td>
<input type="text" name="text">
<input type="submit" value="Add Task" >
</td><td>
Search :<input type="text">
</td>
</tr>
<tr>
<th>Task Id</th>
<th>Task</th>
</tr>
</thead>
<tbody>
{% for user in User %}
<tr>
<td> {{ user.uid }} </td>
<td >{{ user.taskname }}
<input type="image" class="deleteImg" src="static/img/trash_can.png" height="15px" width="18px" name="removeId" value={{user.uid}} />
<input type="image" src="static/img/editbtn.svg" height="15px" width="18px" name="editId" value={{user.uid}}/>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<script>
var app = angular.module("app", ['xeditable']);
app.controller('myctrl', function($scope) {
$scope.myname="Howdy";
});
app.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('//').endSymbol('//');
});
app.run(function(editableOptions) {
editableOptions.theme = 'bs3'; // bootstrap3 theme. Can be also 'bs2', 'default'
});
</script>
</form>
</body>
Your problem seems to be this tag here:
<input type="image" src="static/img/editbtn.svg" height="15px" width="18px" name="editId" value={{user.uid}}/>
All values in html are strings. Therefore they must all be quoted.
value="{{user.uid}}"
Once you've done this, HTML will know exactly what you meant to include in the value, rather than guessing.
The reason this hasn't affected other fields is because this is the only time you didn't put a space between the value and the number.
The error was because I have "/>" at the end of the input tag. it was unnecessary. I have removed it and now it is working fine.

How can I log into a simple web access login using Python?

I'm trying to create a little Python script that'll log into a web access authentication page for me automatically for the purposes of convenience (the login appears each time the computer is disconnected from the network).
My attempt so far has been to use the module mechanize, but running this doesn't result in the login vanishing from my standard browser:
import mechanize
browser = mechanize.Browser()
browser.addheaders = [("User-agent","Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.10 (maverick) Firefox/3.6.13")]
browser.open("https://controller.mobile.lan/101/portal/")
browser.select_form(name="logonForm")
browser["login"] = "myUsername"
browser["password"] = "myPasscode"
browser.submit()
print browser.title()
How can I get this login to work in Python?
Here's what I think is the relevant section of the HTML of the login page:
<form name="logonForm" style="display:none">
<!-- Logon Form -->
<div id="logonForm_subscriptionChoice_top_title_block" class="subtitle">
<span id="logonForm_subscriptionChoice_top_title_text">YOU ALREADY HAVE YOUR LOGIN</span>
</div>
<div id="logonForm_auth_modes_block" style="display:none">
<table class="hoverLink"><tr>
<td>
<div id="logonForm_shibboleth_authentication_button">
<img src="./resources/_images/shibboleth.png" height="30px"><br><span id="logonForm_shibboleth_text">Utilisez vos identifiants institutionnels</span>
</div>
</td>
<td>
<div id="logonForm_standard_authentication_button">
<img src="./resources/_images/ticket.png" height="30px"><br><span id="logonForm_ticket_text">Utilisez un ticket de connexion</span>
</div>
</td>
</tr></table>
</div>
<div id="logonForm_logon_block">
<table>
<tr id="logonForm_logon_block_credentials">
<td class="label">
<span id="logonForm_login_text">LOGIN</span><br><input type="text" name="login" autocomplete="on">
</td>
<td class="label">
<span id="logonForm_password_text">PASSWORD</span><br><input type="password" name="password" autocomplete="on">
</td>
<td>
<button type="submit" id="logonForm_connect_button"><span><img src="./resources/_images/auth_button.png" height="35px"></span></button>
</td>
</tr>
<tr id="logonForm_policy_block">
<!-- Check Box Confirm (Visible status depends on configuration option) --><td colspan="3">
<br><input type="checkbox" name="policy_accept">
<span id="logonForm_policy_text"></span>
</td>
</tr>
</table>
</div>
<br><button type="button" id="logonForm_authentication_form_back_button" style="display:none">Retour</button>
<div id="logonForm_subscriptionChoice_block">
<br><div class="subtitle">
<span id="logonForm_subcribe_bottom_title_text">NOT A LOGIN YET ?</span>
</div>
<br><div id="logonForm_subscriptionChoice_first_double_insert_block">
<table class="hoverLink"><tr>
<td></td>
<td></td>
</tr></table>
</div>
<div id="logonForm_subscriptionChoice_second_double_insert_block">
<table class="hoverLink"><tr>
<td></td>
<td></td>
</tr></table>
</div>
<div id="logonForm_subscriptionChoice_single_insert_block">
<table class="hoverLink"><tr><td></td></tr></table>
</div>
</div>
</form>
That form submits data somewhere. You need to find out where and what method it uses. After you find out, you can use the requests library to do a one-liner, like:
response = requests.post("https://controller.mobile.lan/101/portal/", data={'login': "username", 'password': "password")
print response.read() # Dumps the whole webpage after.
Note that if that form uses javascript for submission, mechanize won't do it and you'll have to get something that actually makes javascript tick. Mechanize's FAQ (here) specifies that it doesn't do javascript and you have to emulate it in your own code.
Edit: If you have PyQt4 lying around, or can install it, you can use a 'headless' browser, like this:
import sys
from PyQt4.QtGui import QApplication
from PyQt4.QtCore import QUrl
from PyQt4.QtWebKit import QWebPage
# Set vars here for convenience
username = "myUsername"
password = "myPassword"
class HeadlessBrowser(QWebPage):
def __init__(self, url):
self.app = QApplication(sys.argv)
super(HeadlessBrowser, self).__init__()
self.loadFinished.connect(self.login)
self.mainFrame().load(QUrl(url))
self.app.exec_();
def login(self):
doc = self.mainFrame().documentElement()
user = doc.findFirst("input[name=login]")
pwd = doc.findFirst("input[name=password]")
button = doc.findFirst("button[id=logonForm_connect_button]")
user.setAttribute("value", username)
pwd.setAttribute("value", password)
button.evaluateJavaScript("this.click()")
# Uncomment if the button click above is not enough
#form = doc.findFirst("form[name=logonForm]")
#form.evaluateJavaScript("this.submit()")
self.app.quit()
page = HeadlessBrowser("http://localhost/~iskren/headlesstest.html")
html = page.mainFrame().toHtml()
And the contents of http://localhost/~iskren/headlesstest.html that I used for testing:
<html>
<body>
<form name="logonForm">
<input type="text" name="login"/>
<input type="password" name="password"/>
<button type="submit" id="logonForm_connect_button">Click me!</button>
</form>
</body>
</html>

Log onto a Website and select options using Python

I am trying to log onto a website using Python. I have written the code to connect to the target but I need to login and select a button on the website and wait for a response. I have looked at the HTTP Protocol in Python and was thinking of using 'HTTPConnection.putrequest'. I am not sure how to do this, I have the code I have so far below:
def testHTTPS(self):
c = httplib.HTTPSConnection(ip)
c.request("GET", "/")
response = c.getresponse()
self.assertEqual(response.status, 200) # '200' is success code
conn.close()
And the code for the logon function on the website is:
<td align="right" id="lgn_userName"></td>
<td><input type="text" class="button" name="username" id="username" size="24" maxlength="16" accesskey="u" tabindex="1" value=""/></td>
</tr>
<tr>
<td align="right" id="lgn_userPwd"></td>
<td><input type="password" class="button" name="password" id="password" size="24" maxlength="20" accesskey="p" tabindex="2" value=""/></td>
</tr>
<tr>
<td align="right"> </td>
<td>
<input type="submit" id="lgn_button" class="button" tabindex="3" accesskey="s" />
</td>
Does anyone know how to go about this?
Thanks
Yes, you use mechanize, which a sort of a "webbrowser" for Python. With it you can easily open web pages, find forms, fill in form values and submit the forms from Python. I use it (via Zopes testbrowser module) for testing web applications.
Use urllib2 and create a POST request.
For more information, read:
urllib2: submitting a form and then redirecting
How to make python urllib2 follow redirect and keep post method
How do I send a HTTP POST value to a (PHP) page using Python?.

Categories