Flask - boolean form - forms

i'm running locally a python file. when i access 127.0.01:5000/string i get to a specific html page. Up to now, using javascript, i managed to put some checkbox (boolean form) on that page, but how can i assign the value of each one of them (True or False) to a variable in the python file?
i'm being unable to use the user's response in anyway.
i'm using flask-ext-wtforms, render_template, etc.
this is what i have on the html file so far.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
var creature=0
var artifact=0
function suggest(){
if ($('#Creature').is(':checked')){creature=1;}
if ($('#Artifact').is(':checked')){artifact=1;}
}
</script>
<input type="checkbox" id = "Creature">Creature<br>
<input type="checkbox" id = "Artifact">Artifact<br>
<input type="checkbox" id = "Enchantment"> Enchantment<br>
<input type="checkbox" id = "Sorcery"> Sorcery<br>
<button type="button" onclick = "suggest(); alert('creature ' + creature + ' artifact ' + artifact)">Submit</button>
It tells me whether or not the user has clicked one of the first two boxes, but that's it. i don't know how to make the python file access such information.

It'd be useful to see what you have in the actual Python file, but I'll give it a go. Also I'll state right off the bat that for these sorts of questions the documentation should be your best friend and first go-to, but here's a start.
From the html you've posted it doesn't look like you're actually using a Flask-WTF Form instance. You would want to first create a Form with BooleanFields like so:
from flask.ext.wtf import Form
from wtforms import BooleanField
class MyForm(Form):
creature = BooleanField()
# etc
submit = SubmitField()
then in your template render the form & the fields like so:
<form method="POST" action="/string">
{{ form.creature.label }}
{{ form.creature() }}
{# ... etc ... #}
{{ form.submit() }}
</form>
Then finally in your view, you have to (A) specify that the view accepts POST requests, (B) create the form, and (C) make sure you pass the form to the template for rendering. If you do all these things, then when you, or someone else, or a robot or whatever click submit, then the browser will POST the data from the form to the flask view, and you will be able to access it in the view as, say, form.creature.data. Example:
#route('/string', methods=['GET', 'POST']) # part A
def get_critters():
form = MyForm() # part B
if form.validate_on_submit():
# do something with form.creature, or form.whatever
return render_template("string.html", form=form) # part C
All of this is very ably covered in multiple parts of each project's documentation. See:
https://flask-wtf.readthedocs.org/en/latest/quickstart.html
https://wtforms.readthedocs.org/en/latest/fields.html#wtforms.fields.BooleanField
and virtually everything at http://flask.pocoo.org/docs/0.10/ but especially http://flask.pocoo.org/docs/0.10/patterns/wtforms/ and http://flask.pocoo.org/docs/0.10/tutorial/.

Related

Getting user entries from a Form based on Genshi Template

I'm trying to write a Plugin for Trac.
I've succeeded to export variables contents from my request (process_request)
to my template ...but I still having problems doing it in the other way : how to catch the information taped by the user ?
<form name="input" action="" method="POST">
Configuration : <input type="text" name="configuration" value ="$my_var" /> <br /><br />
<label for="file">URL:</label>
<input type="text" name="file" id="WillPosted" value="This text will be changed by the user"/>
<input type="submit" name="SubmiT" value="Browse" /><br /><br />
So how can I catch the content of the input form with the id="WillPosted" ?
Notice : actual problem is in IRequestHandler methods from Trac !
Any Idea ?
Thanks
You're asking about the common web-UI interaction
my_var --> template with input field 'file' and default value 'This will ..'
user input to field
submission by POST request
How to get (changed) new value of input, right? If so, you explained it rather complicated.
And I'm wondering, if you don't know about trac-hacks.org, probably the most authoritative source of Trac plugin code on the planet - much more working examples to look at than needed here.
Anyway, the key is reading the return value(s) from reg.args dict like so:
from pkg_resources import resource_filename
from trac.web.chrome import ITemplateProvider, add_stylesheet
implements(IRequestHandler, ITemplateProvider)
# IRequestHandler methods
def match_request(self, req):
# Any condition evaluating to True will fire the second method.
return req.path_info == '/<your_path>'
def process_request(self, req):
"Demo how to interact with your template."
# Check, if you'r really processing the right request by target matching,
# and only act on input of authorized users - as an added suggestion/option.
if req.path_info.startswith('/<your_path>') and req.authname != 'anonymous':
# Check for request type.
if req.method == 'POST':
# Ok, go pock for the new value now.
value = req.args.get('file', 'default_value')))
# Now go, process it, store it, even redirect away, if you're done.
# Fallback for Trac 0.11 compatibility included.
referer = req.args.get('referer') or req.get_header('Referer')
# Steer clear of requests going nowhere or loop to self
if referer is None or \
referer.startswith(str(req.abs_href()) + '/<your_path>'):
referer = req.abs_href()
req.redirect(referer)
# Still there, so that's the initial call or anonymous user, hey?
# So let's prepare information for displaying the template ...
data = dict(my_var='any_string_or_number')
# Take the env obj from self, if needed.
env = self.env
mod = MyOwnSecondaryModule(env)
if mod.can_do_something:
data['my_var'] = mod.do('better')
# Why not apply an own style?
add_stylesheet(req, 'your_plugin/most_famous_style.css')
return 'your_template.html', data
# ITemplateProvider methods
def get_htdocs_dirs(self):
"""Return the absolute path of a directory containing additional
static resources (such as images, style sheets, etc).
"""
return [('your_plugin', resource_filename('your_plugin_pkg_base_dir', 'htdocs'))]
def get_templates_dirs(self):
"""Return the absolute path of the directory containing the provided
Genshi templates.
"""
return [resource_filename('your_plugin_pkg_base_dir', 'templates')]
Questions on using various Trac extension point interfaces? See the authoritative wiki documentation on the subject as well!

web2py form creation

I'm trying to create a form in web2py.
I'm not sure on the correct syntax and don't understand from the examples in the site how this is done. Could someone give a better explanation?
How is a simple form like this created?
<form>
<select>
<option>Paint</option>
<option>Brushes</option>
<option>Erasers</option>
</select>
Quantity: <input type="text" />
<input type="submit" />
</form>
How can I validate more complex forms?
items = ['Paint','Brushes','Erasers']
form = FORM(
SELECT(*items),
INPUT('Quantity', _type='text'),
)
return dict(form=form)
(in view):
{{ extend 'layout.html' }}
{{ =form}}
To validate this form, or a "more complex" form:
(in controller)
form = FORM(...) # This is the same form def as above, must be before form.process()
if form.process().accepted:
# Valid!
else:
# invalid.
If you have a more specific question, I'll attempt to answer it, but I highly recommend you check out the book and try to create and validate your own simple forms. You can use the welcome app as a place to start. Or you could google around for web2py apps and download and play with them.
Read these two chapters in their entirety and I'll help you with anything web2py in the future (there will be a quiz!):
Database Abstraction layer (important for unlocking the full power of web2py's DB-driven forms):
http://web2py.com/books/default/chapter/29/6
Forms and Validators (everything you ever needed to know about creating forms and linking it to data:
http://web2py.com/books/default/chapter/29/7

How to change a form's action in Lift

I am building a Lift application, where one of the pages is based on the "File Upload" example from the Lift demo at: http://demo.liftweb.net/file_upload.
If you look at the source code for that page... you see that there is a Lift "snippet" tag, surrounding two "choose" tags:
<lift:snippet type="misc:upload" form="post" multipart="true">
<choose:post>
<p>
File name: <ul:file_name></ul:file_name><br >
MIME Type: <ul:mime_type></ul:mime_type><br >
File length: <ul:length></ul:length><br >
MD5 Hash: <ul:md5></ul:md5><br >
</p>
</choose:post>
<choose:get>
Select a file to upload: <ul:file_upload></ul:file_upload><br >
<input type="submit" value="Upload File">
</choose:get>
</lift:snippet>
The idea is that when a user hits the page for the first time (i.e. a GET request), then Lift will show the form for uploading a file. When the user submits the form (i.e. a POST request to the same page), then Lift instead displays the outcome of the file being processed.
With my application, the new wrinkle is that my "results" POST view needs to also contain a form. I want to provide a text input for the user to enter an email address, and a submit button that when pressed will email information about the processed file:
...
<choose:post>
<p>
File name: <ul:file_name></ul:file_name><br >
MIME Type: <ul:mime_type></ul:mime_type><br >
File length: <ul:length></ul:length><br >
MD5 Hash: <ul:md5></ul:md5><br >
</p>
<!-- BEGIN NEW STUFF -->
Output: <br/>
<textarea rows="30" cols="100"><ul:output></ul:output></textarea>
<br/><br/>
Email the above output to this email address:<br/>
<ul:email/><br/>
<input type="submit" value="Email"/>
<!-- END NEW STUFF -->
</choose:post>
...
However, both the GET and POST versions of this page are wrapped by the same Lift-generated form, which has its "action" set to the same snippet in both cases. How can I change this such that in the POST version, the form's action changes to a different snippet?
In a typical web framework, I would approach something like this with an "onclick" event and two basic lines of JavaScript. However, I haven't even begun to wrap my mind around Lift's... err, interesting notions about writing JavaScript in Scala. Maybe I need to go down that route, or maybe there's a better approach altogether.
First, I will suggest you use Lift's new designer friendly CSS binding instead of the custom XHTML tag.
And one thing you should remember when you're using Lift's snippet, is that it is recursive, you could put an lift snippet inside another snippet's HTML block.
For example, if you wish there is another form after POST, then just put it into the block.
<choose:post>
<p>
File name: <ul:file_name></ul:file_name><br >
MIME Type: <ul:mime_type></ul:mime_type><br >
File length: <ul:length></ul:length><br >
MD5 Hash: <ul:md5></ul:md5><br >
</p>
<!--
The following is same as <lift:snippet type="EMailForm" form="post" multipart="true">
-->
<form action="" method="post" data-lift="EMailForm">
<input type="text" name="email"/>
<input type="submit" />
</form>
</choose:post>
Then deal with the email form action at snippet class EMailForm.
Finally, you may pass the filename / minetype and other information by using hidden form element or SessionVar.
I agree with Brian, use Lift's new designer friendly CSS binding.
Use two separate forms, one for the file upload and one for the submitting the email. Use S.seeOther to redirect the user to the second form when the first has finished processing.
I also prefer the new 'data-lift' HTML attribute.
File upload HTML:
<div data-lift="uploadSnippet?form=post">
<input type="file" id="filename" />
<input type="submit" id="submit" />
</div
File upload snippet:
class uploadSnippet {
def processUpload = {
// do your processing
....
if (success)
S.seeOther("/getemail")
// if processing fails, just allow this method to exit to re-render your
// file upload form
}
def render = {
"#filename" #> SHtml.fileUpload(...) &
"#submit" #> SHtml.submit("Upload", processUpload _ )
}
}
GetEmail HTML:
<div data-lift="getEmailSnippet?form=post">
<input type="text" id="email" />
<input type="submit" id="submit" />
</div
Get Email Snippet:
class getEmailSnippet {
def processSubmit = {
....
}
def render = {
"#email" #> SHtml.text(...) &
"#submit" #> SHtml.submit("Upload", processSubmit _ )
}
There's a bit more on form processing in my blog post on using RequestVar's here:
http://tech.damianhelme.com/understanding-lifts-requestvars
Let me know if you want more detail.
Hope that's useful
Cheers
Damian
If somebody comes up with a more elegant (or "Lift-y") approach within the next few days, then I'll accept their answer. However, I came up with a workaround approach on my own.
I kept the current layout, where the view has a GET block and a POST block both submitting to the same snippet function. The snippet function still has an if-else block, handling each request differently depending on whether it's a GET or POST.
However, now I also have a secondary if-else block inside of the POST's block. This inner if-else looks at the name of the submit button that was clicked. If the submit button was the one for uploading a file, then the snippet handles the uploading and processing of the file. Otherwise, if it was the send email submit button shown after the first POST, then the snippet processes the sending of the email.
Not particularly glamorous, but it works just fine.

how to pass html form data to variable (nodejs / javascript)

so i'm using nodejs and nodejsdb-mysql. i want to make form for adding and searching posts.
I make html page with form, transform it to node using jsdom but how do i set up variables?
for example my html form is like:
name = text input
surname = text input
submit
and how do i pass inserted name/surname to var??
You will need to turn your submit into a button with an event such as onclick - this might be what you are looking for:
<input type="button" value="Submit" id="submit" name="submit" onclick="submit()">
<script type="text/javascript">
function submit(){
var name = document.getElementById('**name**').value;
var surname = document.getElementById('**surname**').value;
alert("Thanks for submitting, " +name);
}
</script>
With nodejsdb-mysql sooner or later you will face real problems like date localization problems and so on, use https://github.com/felixge/node-mysql instead

get checkbox group values

This has driven me really bananas. It's so simple and easy and yet I can't figure out what's wrong with it.
I want to get my checkbox value populated in my controller (for testing purposes).
Here is my form.
<a href='#' name='submitForm'>submit the form</a>
//I have jquery attached to this tag and will submit the form when user clicks it
echo form_open('test/show');
echo form_checkbox('checkbox[]','value1');
echo form_checkbox('checkbox[]','value2');
echo form_checkbox('checkbox[]','value3');
echo form_checkbox('checkbox[]','value4');
echo "<input type='text' name='text1' value='ddd'>";
echo form_close();
//My controller test
public function show(){
$data1=$this->input->post('text1');
//I can get text1 value from input box
$data2=$this->input->post('checkbox');
//it keeps giving me undefined index 'checkbox'
$data3=$_POST['checkbox'];
//same error message
//WTH is going on here!!!!!
}
Please help. This thing drives me nuts! Thanks.
UPDATE:
Thanks for the help. To be more precisely, my submit button is a <a> tag and outside of form tag. It appear that I have to include <a> tag inside my form tag to make them works. Is that true?
A checkbox will not submit any data if it is unchecked as they're not considered successful (as per the w3c specification here)
If you actually tick the box and submit, it'll work - in fact it does, I've just tested it.
You need to wrap calls to $_POST in the isset() function.
if( isset( $_POST['checkbox'] ) ) {}
Calling $this->input->post('checkbox') shouldn't give you an undefined index error as the method deals with this eventuality. the Input::post() method returns false or the value of the checkbox.
Edit --
In response to your amendment to your question, you must use an element of type input with the type attribute set to submit in order to submit your form data without the use of Javascript etc. This button must be INSIDE the <form></form> which you are intending to submit.
<input type="submit" value="Submit">
The type="submit" causes the browser to send the data as submit event occurs. If you wish to use another element insider or outside of the form to do this you need to use Javascript. This however can be disabled on a per browser/user basis and isn't reliable as a result.
// Standard Javascript
<form name="myform"...
<a onclick="javascript:document.myform.submit();" href="javascript:void(0)">Submit</a>
// jQuery
$('#my-a-tag-submit-button').live( 'click', function() {
$('#my-form').submit();
}